Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IceAABB.cpp
Go to the documentation of this file.
1 
8 
11 
17 
20 // Precompiled Header
21 #include "Stdafx.h"
22 
23 
24 using namespace Opcode;
25 
26 
28 
33 AABB& AABB::Add(const AABB& aabb)
35 {
36  // Compute new min & max values
37  Point Min; GetMin(Min);
38  Point Tmp; aabb.GetMin(Tmp);
39  Min.Min(Tmp);
40 
41  Point Max; GetMax(Max);
42  aabb.GetMax(Tmp);
43  Max.Max(Tmp);
44 
45  // Update this
46  SetMinMax(Min, Max);
47  return *this;
48 }
49 
51 
56 float AABB::MakeCube(AABB& cube) const
58 {
59  Point Ext; GetExtents(Ext);
60  float Max = Ext.Max();
61 
62  Point Cnt; GetCenter(Cnt);
63  cube.SetCenterExtents(Cnt, Point(Max, Max, Max));
64  return Max;
65 }
66 
68 
72 void AABB::MakeSphere(Sphere& sphere) const
74 {
75  GetExtents(sphere.mCenter);
76  sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds
77  GetCenter(sphere.mCenter);
78 }
79 
81 
86 bool AABB::IsInside(const AABB& box) const
88 {
89  if(box.GetMin(0)>GetMin(0)) return false;
90  if(box.GetMin(1)>GetMin(1)) return false;
91  if(box.GetMin(2)>GetMin(2)) return false;
92  if(box.GetMax(0)<GetMax(0)) return false;
93  if(box.GetMax(1)<GetMax(1)) return false;
94  if(box.GetMax(2)<GetMax(2)) return false;
95  return true;
96 }
97 
99 
104 bool AABB::ComputePlanes(Plane* planes) const
106 {
107  // Checkings
108  if(!planes) return false;
109 
110  Point Center, Extents;
111  GetCenter(Center);
112  GetExtents(Extents);
113 
114  // Writes normals
115  planes[0].n = Point(1.0f, 0.0f, 0.0f);
116  planes[1].n = Point(-1.0f, 0.0f, 0.0f);
117  planes[2].n = Point(0.0f, 1.0f, 0.0f);
118  planes[3].n = Point(0.0f, -1.0f, 0.0f);
119  planes[4].n = Point(0.0f, 0.0f, 1.0f);
120  planes[5].n = Point(0.0f, 0.0f, -1.0f);
121 
122  // Compute a point on each plane
123  Point p0 = Point(Center.x+Extents.x, Center.y, Center.z);
124  Point p1 = Point(Center.x-Extents.x, Center.y, Center.z);
125  Point p2 = Point(Center.x, Center.y+Extents.y, Center.z);
126  Point p3 = Point(Center.x, Center.y-Extents.y, Center.z);
127  Point p4 = Point(Center.x, Center.y, Center.z+Extents.z);
128  Point p5 = Point(Center.x, Center.y, Center.z-Extents.z);
129 
130  // Compute d
131  planes[0].d = -(planes[0].n|p0);
132  planes[1].d = -(planes[1].n|p1);
133  planes[2].d = -(planes[2].n|p2);
134  planes[3].d = -(planes[3].n|p3);
135  planes[4].d = -(planes[4].n|p4);
136  planes[5].d = -(planes[5].n|p5);
137 
138  return true;
139 }
140 
142 
147 bool AABB::ComputePoints(Point* pts) const
149 {
150  // Checkings
151  if(!pts) return false;
152 
153  // Get box corners
154  Point min; GetMin(min);
155  Point max; GetMax(max);
156 
157  // 7+------+6 0 = ---
158  // /| /| 1 = +--
159  // / | / | 2 = ++-
160  // / 4+---/--+5 3 = -+-
161  // 3+------+2 / y z 4 = --+
162  // | / | / | / 5 = +-+
163  // |/ |/ |/ 6 = +++
164  // 0+------+1 *---x 7 = -++
165 
166  // Generate 8 corners of the bbox
167  pts[0] = Point(min.x, min.y, min.z);
168  pts[1] = Point(max.x, min.y, min.z);
169  pts[2] = Point(max.x, max.y, min.z);
170  pts[3] = Point(min.x, max.y, min.z);
171  pts[4] = Point(min.x, min.y, max.z);
172  pts[5] = Point(max.x, min.y, max.z);
173  pts[6] = Point(max.x, max.y, max.z);
174  pts[7] = Point(min.x, max.y, max.z);
175 
176  return true;
177 }
178 
180 
185 const Point* AABB::GetVertexNormals() const
187 {
188  static float VertexNormals[] =
189  {
197  -INVSQRT3, INVSQRT3, INVSQRT3
198  };
199  return (const Point*)VertexNormals;
200 }
201 
203 
207 const udword* AABB::GetEdges() const
209 {
210  static udword Indices[] = {
211  0, 1, 1, 2, 2, 3, 3, 0,
212  7, 6, 6, 5, 5, 4, 4, 7,
213  1, 5, 6, 2,
214  3, 7, 4, 0
215  };
216  return Indices;
217 }
218 
220 
224 const Point* AABB::GetEdgeNormals() const
226 {
227  static float EdgeNormals[] =
228  {
229  0, -INVSQRT2, -INVSQRT2, // 0-1
230  INVSQRT2, 0, -INVSQRT2, // 1-2
231  0, INVSQRT2, -INVSQRT2, // 2-3
232  -INVSQRT2, 0, -INVSQRT2, // 3-0
233 
234  0, INVSQRT2, INVSQRT2, // 7-6
235  INVSQRT2, 0, INVSQRT2, // 6-5
236  0, -INVSQRT2, INVSQRT2, // 5-4
237  -INVSQRT2, 0, INVSQRT2, // 4-7
238 
239  INVSQRT2, -INVSQRT2, 0, // 1-5
240  INVSQRT2, INVSQRT2, 0, // 6-2
241  -INVSQRT2, INVSQRT2, 0, // 3-7
242  -INVSQRT2, -INVSQRT2, 0 // 4-0
243  };
244  return (const Point*)EdgeNormals;
245 }
246 
247 // ===========================================================================
248 // (C) 1996-98 Vienna University of Technology
249 // ===========================================================================
250 // NAME: bboxarea
251 // TYPE: c++ code
252 // PROJECT: Bounding Box Area
253 // CONTENT: Computes area of 2D projection of 3D oriented bounding box
254 // VERSION: 1.0
255 // ===========================================================================
256 // AUTHORS: ds Dieter Schmalstieg
257 // ep Erik Pojar
258 // ===========================================================================
259 // HISTORY:
260 //
261 // 19-sep-99 15:23:03 ds last modification
262 // 01-dec-98 15:23:03 ep created
263 // ===========================================================================
264 
265 //----------------------------------------------------------------------------
266 // SAMPLE CODE STARTS HERE
267 //----------------------------------------------------------------------------
268 
269 // NOTE: This sample program requires OPEN INVENTOR!
270 
271 //indexlist: this table stores the 64 possible cases of classification of
272 //the eyepoint with respect to the 6 defining planes of the bbox (2^6=64)
273 //only 26 (3^3-1, where 1 is "inside" cube) of these cases are valid.
274 //the first 6 numbers in each row are the indices of the bbox vertices that
275 //form the outline of which we want to compute the area (counterclockwise
276 //ordering), the 7th entry means the number of vertices in the outline.
277 //there are 6 cases with a single face and and a 4-vertex outline, and
278 //20 cases with 2 or 3 faces and a 6-vertex outline. a value of 0 indicates
279 //an invalid case.
280 
281 
282 // Original list was made of 7 items, I added an 8th element:
283 // - to padd on a cache line
284 // - to repeat the first entry to avoid modulos
285 //
286 // I also replaced original ints with sbytes.
287 
288 static const sbyte gIndexList[64][8] =
289 {
290  {-1,-1,-1,-1,-1,-1,-1, 0}, // 0 inside
291  { 0, 4, 7, 3, 0,-1,-1, 4}, // 1 left
292  { 1, 2, 6, 5, 1,-1,-1, 4}, // 2 right
293  {-1,-1,-1,-1,-1,-1,-1, 0}, // 3 -
294  { 0, 1, 5, 4, 0,-1,-1, 4}, // 4 bottom
295  { 0, 1, 5, 4, 7, 3, 0, 6}, // 5 bottom, left
296  { 0, 1, 2, 6, 5, 4, 0, 6}, // 6 bottom, right
297  {-1,-1,-1,-1,-1,-1,-1, 0}, // 7 -
298  { 2, 3, 7, 6, 2,-1,-1, 4}, // 8 top
299  { 0, 4, 7, 6, 2, 3, 0, 6}, // 9 top, left
300  { 1, 2, 3, 7, 6, 5, 1, 6}, //10 top, right
301  {-1,-1,-1,-1,-1,-1,-1, 0}, //11 -
302  {-1,-1,-1,-1,-1,-1,-1, 0}, //12 -
303  {-1,-1,-1,-1,-1,-1,-1, 0}, //13 -
304  {-1,-1,-1,-1,-1,-1,-1, 0}, //14 -
305  {-1,-1,-1,-1,-1,-1,-1, 0}, //15 -
306  { 0, 3, 2, 1, 0,-1,-1, 4}, //16 front
307  { 0, 4, 7, 3, 2, 1, 0, 6}, //17 front, left
308  { 0, 3, 2, 6, 5, 1, 0, 6}, //18 front, right
309  {-1,-1,-1,-1,-1,-1,-1, 0}, //19 -
310  { 0, 3, 2, 1, 5, 4, 0, 6}, //20 front, bottom
311  { 1, 5, 4, 7, 3, 2, 1, 6}, //21 front, bottom, left
312  { 0, 3, 2, 6, 5, 4, 0, 6}, //22 front, bottom, right
313  {-1,-1,-1,-1,-1,-1,-1, 0}, //23 -
314  { 0, 3, 7, 6, 2, 1, 0, 6}, //24 front, top
315  { 0, 4, 7, 6, 2, 1, 0, 6}, //25 front, top, left
316  { 0, 3, 7, 6, 5, 1, 0, 6}, //26 front, top, right
317  {-1,-1,-1,-1,-1,-1,-1, 0}, //27 -
318  {-1,-1,-1,-1,-1,-1,-1, 0}, //28 -
319  {-1,-1,-1,-1,-1,-1,-1, 0}, //29 -
320  {-1,-1,-1,-1,-1,-1,-1, 0}, //30 -
321  {-1,-1,-1,-1,-1,-1,-1, 0}, //31 -
322  { 4, 5, 6, 7, 4,-1,-1, 4}, //32 back
323  { 0, 4, 5, 6, 7, 3, 0, 6}, //33 back, left
324  { 1, 2, 6, 7, 4, 5, 1, 6}, //34 back, right
325  {-1,-1,-1,-1,-1,-1,-1, 0}, //35 -
326  { 0, 1, 5, 6, 7, 4, 0, 6}, //36 back, bottom
327  { 0, 1, 5, 6, 7, 3, 0, 6}, //37 back, bottom, left
328  { 0, 1, 2, 6, 7, 4, 0, 6}, //38 back, bottom, right
329  {-1,-1,-1,-1,-1,-1,-1, 0}, //39 -
330  { 2, 3, 7, 4, 5, 6, 2, 6}, //40 back, top
331  { 0, 4, 5, 6, 2, 3, 0, 6}, //41 back, top, left
332  { 1, 2, 3, 7, 4, 5, 1, 6}, //42 back, top, right
333  {-1,-1,-1,-1,-1,-1,-1, 0}, //43 invalid
334  {-1,-1,-1,-1,-1,-1,-1, 0}, //44 invalid
335  {-1,-1,-1,-1,-1,-1,-1, 0}, //45 invalid
336  {-1,-1,-1,-1,-1,-1,-1, 0}, //46 invalid
337  {-1,-1,-1,-1,-1,-1,-1, 0}, //47 invalid
338  {-1,-1,-1,-1,-1,-1,-1, 0}, //48 invalid
339  {-1,-1,-1,-1,-1,-1,-1, 0}, //49 invalid
340  {-1,-1,-1,-1,-1,-1,-1, 0}, //50 invalid
341  {-1,-1,-1,-1,-1,-1,-1, 0}, //51 invalid
342  {-1,-1,-1,-1,-1,-1,-1, 0}, //52 invalid
343  {-1,-1,-1,-1,-1,-1,-1, 0}, //53 invalid
344  {-1,-1,-1,-1,-1,-1,-1, 0}, //54 invalid
345  {-1,-1,-1,-1,-1,-1,-1, 0}, //55 invalid
346  {-1,-1,-1,-1,-1,-1,-1, 0}, //56 invalid
347  {-1,-1,-1,-1,-1,-1,-1, 0}, //57 invalid
348  {-1,-1,-1,-1,-1,-1,-1, 0}, //58 invalid
349  {-1,-1,-1,-1,-1,-1,-1, 0}, //59 invalid
350  {-1,-1,-1,-1,-1,-1,-1, 0}, //60 invalid
351  {-1,-1,-1,-1,-1,-1,-1, 0}, //61 invalid
352  {-1,-1,-1,-1,-1,-1,-1, 0}, //62 invalid
353  {-1,-1,-1,-1,-1,-1,-1, 0} //63 invalid
354 };
355 
356 const sbyte* AABB::ComputeOutline(const Point& local_eye, sdword& num) const
357 {
358  // Get box corners
359  Point min; GetMin(min);
360  Point max; GetMax(max);
361 
362  // Compute 6-bit code to classify eye with respect to the 6 defining planes of the bbox
363  int pos = ((local_eye.x < min.x) ? 1 : 0) // 1 = left
364  + ((local_eye.x > max.x) ? 2 : 0) // 2 = right
365  + ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom
366  + ((local_eye.y > max.y) ? 8 : 0) // 8 = top
367  + ((local_eye.z < min.z) ? 16 : 0) // 16 = front
368  + ((local_eye.z > max.z) ? 32 : 0); // 32 = back
369 
370  // Look up number of vertices in outline
371  num = (sdword)gIndexList[pos][7];
372  // Zero indicates invalid case
373  if(!num) return null;
374 
375  return &gIndexList[pos][0];
376 }
377 
378 // calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box
379 
380 //const Point& eye, //eye point (in bbox object coordinates)
381 //const AABB& box, //3d bbox
382 //const Matrix4x4& mat, //free transformation for bbox
383 //float width, float height, int& num)
384 float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const
385 {
386  const sbyte* Outline = ComputeOutline(eye, num);
387  if(!Outline) return -1.0f;
388 
389  // Compute box vertices
390  Point vertexBox[8], dst[8];
391  ComputePoints(vertexBox);
392 
393  sdword i;
394  // Transform all outline corners into 2D screen space
395  for(i=0;i<num;i++)
396  {
397  HPoint Projected;
398  vertexBox[Outline[i]].ProjectToScreen(width, height, mat, Projected);
399  dst[i] = Projected;
400  }
401 
402  float Sum = (dst[num-1][0] - dst[0][0]) * (dst[num-1][1] + dst[0][1]);
403 
404  for(i=0; i<num-1; i++)
405  Sum += (dst[i][0] - dst[i+1][0]) * (dst[i][1] + dst[i+1][1]);
406 
407  return Sum * 0.5f; //return computed value corrected by 0.5
408 }
409