VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/bbox.c@ 42499

Last change on this file since 42499 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <float.h>
8#include "cr_bbox.h"
9
10/**
11 * \mainpage Util
12 *
13 * \section UtilIntroduction Introduction
14 *
15 * Chromium consists of all the top-level files in the cr
16 * directory. The util module basically takes care of API dispatch,
17 * and OpenGL state management.
18 *
19 */
20static float _vmult(const float *m, float x, float y, float z)
21{
22 return m[0]*x + m[4]*y + m[8]*z + m[12];
23}
24
25void
26crTransformBBox( float xmin, float ymin, float zmin,
27 float xmax, float ymax, float zmax,
28 const CRmatrix *m,
29 float *out_xmin, float *out_ymin, float *out_zmin,
30 float *out_xmax, float *out_ymax, float *out_zmax )
31{
32 float x[8], y[8], z[8], w[8];
33 int i,j;
34
35 /* Here is the arrangement of the bounding box
36 *
37 * 0 --- 1
38 * |\ .\
39 * | 2 --- 3
40 * | | . |
41 * | | . |
42 * 4.|...5 |
43 * \| .|
44 * 6 --- 7
45 *
46 * c array contains the edge connectivity list
47 */
48
49 static const int c[8][3] = {
50 {1, 2, 4},
51 {0, 3, 5},
52 {0, 3, 6},
53 {1, 2, 7},
54 {0, 5, 6},
55 {1, 4, 7},
56 {2, 4, 7},
57 {3, 5, 6}
58 };
59
60 x[0] = _vmult(&(m->m00), xmin, ymin, zmin);
61 x[1] = _vmult(&(m->m00), xmax, ymin, zmin);
62 x[2] = _vmult(&(m->m00), xmin, ymax, zmin);
63 x[3] = _vmult(&(m->m00), xmax, ymax, zmin);
64 x[4] = _vmult(&(m->m00), xmin, ymin, zmax);
65 x[5] = _vmult(&(m->m00), xmax, ymin, zmax);
66 x[6] = _vmult(&(m->m00), xmin, ymax, zmax);
67 x[7] = _vmult(&(m->m00), xmax, ymax, zmax);
68
69 y[0] = _vmult(&(m->m01), xmin, ymin, zmin);
70 y[1] = _vmult(&(m->m01), xmax, ymin, zmin);
71 y[2] = _vmult(&(m->m01), xmin, ymax, zmin);
72 y[3] = _vmult(&(m->m01), xmax, ymax, zmin);
73 y[4] = _vmult(&(m->m01), xmin, ymin, zmax);
74 y[5] = _vmult(&(m->m01), xmax, ymin, zmax);
75 y[6] = _vmult(&(m->m01), xmin, ymax, zmax);
76 y[7] = _vmult(&(m->m01), xmax, ymax, zmax);
77
78 z[0] = _vmult(&(m->m02), xmin, ymin, zmin);
79 z[1] = _vmult(&(m->m02), xmax, ymin, zmin);
80 z[2] = _vmult(&(m->m02), xmin, ymax, zmin);
81 z[3] = _vmult(&(m->m02), xmax, ymax, zmin);
82 z[4] = _vmult(&(m->m02), xmin, ymin, zmax);
83 z[5] = _vmult(&(m->m02), xmax, ymin, zmax);
84 z[6] = _vmult(&(m->m02), xmin, ymax, zmax);
85 z[7] = _vmult(&(m->m02), xmax, ymax, zmax);
86
87 w[0] = _vmult(&(m->m03), xmin, ymin, zmin);
88 w[1] = _vmult(&(m->m03), xmax, ymin, zmin);
89 w[2] = _vmult(&(m->m03), xmin, ymax, zmin);
90 w[3] = _vmult(&(m->m03), xmax, ymax, zmin);
91 w[4] = _vmult(&(m->m03), xmin, ymin, zmax);
92 w[5] = _vmult(&(m->m03), xmax, ymin, zmax);
93 w[6] = _vmult(&(m->m03), xmin, ymax, zmax);
94 w[7] = _vmult(&(m->m03), xmax, ymax, zmax);
95
96 /* Now, the object-space bbox has been transformed into
97 * clip-space. */
98
99 /* Find the 2D bounding box of the 3D bounding box */
100 xmin = ymin = zmin = FLT_MAX;
101 xmax = ymax = zmax = -FLT_MAX;
102
103 for (i=0; i<8; i++)
104 {
105 float xp = x[i];
106 float yp = y[i];
107 float zp = z[i];
108 float wp = w[i];
109
110 /* If corner is to be clipped... */
111 if (zp < -wp)
112 {
113
114 /* Point has three edges */
115 for (j=0; j<3; j++)
116 {
117 /* Handle the clipping... */
118 int k = c[i][j];
119 float xk = x[k];
120 float yk = y[k];
121 float zk = z[k];
122 float wk = w[k];
123 float t;
124
125 if (zp+wp-zk-wk == 0.0)
126 continue; /* avoid divide by zero */
127 else
128 t = (wp + zp) / (zp+wp-zk-wk);
129
130 if (t < 0.0f || t > 1.0f)
131 {
132 continue;
133 }
134 wp = wp + (wk-wp) * t;
135 xp = xp + (xk-xp) * t;
136 yp = yp + (yk-yp) * t;
137 zp = -wp;
138
139 xp /= wp;
140 yp /= wp;
141 zp /= wp;
142
143 if (xp < xmin) xmin = xp;
144 if (xp > xmax) xmax = xp;
145 if (yp < ymin) ymin = yp;
146 if (yp > ymax) ymax = yp;
147 if (zp < zmin) zmin = zp;
148 if (zp > zmax) zmax = zp;
149 }
150 }
151 else
152 {
153 /* corner was not clipped.. */
154 xp /= wp;
155 yp /= wp;
156 zp /= wp;
157 if (xp < xmin) xmin = xp;
158 if (xp > xmax) xmax = xp;
159 if (yp < ymin) ymin = yp;
160 if (yp > ymax) ymax = yp;
161 if (zp < zmin) zmin = zp;
162 if (zp > zmax) zmax = zp;
163 }
164 }
165
166 /* Copy for export */
167 if (out_xmin) *out_xmin = xmin;
168 if (out_ymin) *out_ymin = ymin;
169 if (out_zmin) *out_zmin = zmin;
170 if (out_xmax) *out_xmax = xmax;
171 if (out_ymax) *out_ymax = ymax;
172 if (out_zmax) *out_zmax = zmax;
173}
174
175/**
176 * Given the coordinates of the two opposite corners of a bounding box
177 * in object space (x1,y1,z1) and (x2,y2,z2), use the given modelview
178 * and projection matrices to transform the coordinates to NDC space.
179 * Find the 3D bounding bounding box of those eight coordinates and
180 * return the min/max in (x1,y1,x1) and (x2,y2,z2).
181 */
182void
183crProjectBBox(const GLfloat modl[16], const GLfloat proj[16],
184 GLfloat *x1, GLfloat *y1, GLfloat *z1,
185 GLfloat *x2, GLfloat *y2, GLfloat *z2)
186{
187 CRmatrix m;
188
189 /* compute product of modl and proj matrices */
190 m.m00 = proj[0] * modl[0] + proj[4] * modl[1] + proj[8] * modl[2] + proj[12] * modl[3];
191 m.m01 = proj[1] * modl[0] + proj[5] * modl[1] + proj[9] * modl[2] + proj[13] * modl[3];
192 m.m02 = proj[2] * modl[0] + proj[6] * modl[1] + proj[10] * modl[2] + proj[14] * modl[3];
193 m.m03 = proj[3] * modl[0] + proj[7] * modl[1] + proj[11] * modl[2] + proj[15] * modl[3];
194 m.m10 = proj[0] * modl[4] + proj[4] * modl[5] + proj[8] * modl[6] + proj[12] * modl[7];
195 m.m11 = proj[1] * modl[4] + proj[5] * modl[5] + proj[9] * modl[6] + proj[13] * modl[7];
196 m.m12 = proj[2] * modl[4] + proj[6] * modl[5] + proj[10] * modl[6] + proj[14] * modl[7];
197 m.m13 = proj[3] * modl[4] + proj[7] * modl[5] + proj[11] * modl[6] + proj[15] * modl[7];
198 m.m20 = proj[0] * modl[8] + proj[4] * modl[9] + proj[8] * modl[10] + proj[12] * modl[11];
199 m.m21 = proj[1] * modl[8] + proj[5] * modl[9] + proj[9] * modl[10] + proj[13] * modl[11];
200 m.m22 = proj[2] * modl[8] + proj[6] * modl[9] + proj[10] * modl[10] + proj[14] * modl[11];
201 m.m23 = proj[3] * modl[8] + proj[7] * modl[9] + proj[11] * modl[10] + proj[15] * modl[11];
202 m.m30 = proj[0] * modl[12] + proj[4] * modl[13] + proj[8] * modl[14] + proj[12] * modl[15];
203 m.m31 = proj[1] * modl[12] + proj[5] * modl[13] + proj[9] * modl[14] + proj[13] * modl[15];
204 m.m32 = proj[2] * modl[12] + proj[6] * modl[13] + proj[10] * modl[14] + proj[14] * modl[15];
205 m.m33 = proj[3] * modl[12] + proj[7] * modl[13] + proj[11] * modl[14] + proj[15] * modl[15];
206
207 crTransformBBox( *x1, *y1, *z1,
208 *x2, *y2, *z2,
209 &m,
210 x1, y1, z1,
211 x2, y2, z2 );
212}
213
214
215#define MIN(a, b) ((a) < (b) ? (a) : (b))
216#define MAX(a, b) ((a) > (b) ? (a) : (b))
217
218
219/**
220 * Compute union of a and b and put in result.
221 */
222void
223crRectiUnion(CRrecti *result, const CRrecti *a, const CRrecti *b)
224{
225 result->x1 = MIN(a->x1, b->x1);
226 result->x2 = MAX(a->x2, b->x2);
227 result->y1 = MIN(a->y1, b->y1);
228 result->y2 = MAX(a->y2, b->y2);
229}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette