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
Opcode::OBB Class Reference

#include <Opcode.h>

Public Member Functions

inline_ OBB ()
 Constructor. More...
 
inline_ OBB (const Point &center, const Point &extents, const Matrix3x3 &rot)
 Constructor. More...
 
inline_ ~OBB ()
 Destructor. More...
 
void SetEmpty ()
 
bool ContainsPoint (const Point &p) const
 
void Create (const AABB &aabb, const Matrix4x4 &mat)
 
inline_ void Rotate (const Matrix4x4 &mtx, OBB &obb) const
 
inline_ BOOL IsValid () const
 
bool ComputePlanes (Plane *planes) const
 
bool ComputePoints (Point *pts) const
 
bool ComputeVertexNormals (Point *pts) const
 
const udwordGetEdges () const
 
const PointGetLocalEdgeNormals () const
 
void ComputeWorldEdgeNormal (udword edge_index, Point &world_normal) const
 
void ComputeLSS (LSS &lss) const
 
bool IsInside (const OBB &box) const
 
inline_ const PointGetCenter () const
 
inline_ const PointGetExtents () const
 
inline_ const Matrix3x3GetRot () const
 
inline_ void GetRotatedExtents (Matrix3x3 &extents) const
 

Public Attributes

Point mCenter
 B for Box. More...
 
Point mExtents
 B for Bounding. More...
 
Matrix3x3 mRot
 O for Oriented. More...
 

Detailed Description

Definition at line 19 of file Opcode.h.

Constructor & Destructor Documentation

inline_ Opcode::OBB::OBB ( )
inline

Constructor.

Definition at line 23 of file Opcode.h.

39 {
inline_ Opcode::OBB::OBB ( const Point center,
const Point extents,
const Matrix3x3 rot 
)
inline

Constructor.

Definition at line 25 of file Opcode.h.

39 {
inline_ Opcode::OBB::~OBB ( )
inline

Destructor.

Definition at line 27 of file Opcode.h.

39 {

Member Function Documentation

void OBB::ComputeLSS ( LSS lss) const

Computes an LSS surrounding the OBB.

Parameters
lss[out] the LSS

Definition at line 256 of file IceOBB.cpp.

257 {
258  Point Axis0 = mRot[0];
259  Point Axis1 = mRot[1];
260  Point Axis2 = mRot[2];
261 
262  switch(mExtents.LargestAxis())
263  {
264  case 0:
265  lss.mRadius = (mExtents.y + mExtents.z)*0.5f;
266  lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius);
267  lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius);
268  break;
269  case 1:
270  lss.mRadius = (mExtents.x + mExtents.z)*0.5f;
271  lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius);
272  lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius);
273  break;
274  case 2:
275  lss.mRadius = (mExtents.x + mExtents.y)*0.5f;
276  lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius);
277  lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius);
278  break;
279  default:
280  // Should not happen
281  break;
282  }
283 }
bool OBB::ComputePlanes ( Plane planes) const

Computes the obb planes.

Parameters
planes[out] 6 box planes
Returns
true if success

Definition at line 83 of file IceOBB.cpp.

84 {
85  // Checkings
86  if(!planes) return false;
87 
88  Point Axis0 = mRot[0];
89  Point Axis1 = mRot[1];
90  Point Axis2 = mRot[2];
91 
92  // Writes normals
93  planes[0].n = Axis0;
94  planes[1].n = -Axis0;
95  planes[2].n = Axis1;
96  planes[3].n = -Axis1;
97  planes[4].n = Axis2;
98  planes[5].n = -Axis2;
99 
100  // Compute a point on each plane
101  Point p0 = mCenter + Axis0 * mExtents.x;
102  Point p1 = mCenter - Axis0 * mExtents.x;
103  Point p2 = mCenter + Axis1 * mExtents.y;
104  Point p3 = mCenter - Axis1 * mExtents.y;
105  Point p4 = mCenter + Axis2 * mExtents.z;
106  Point p5 = mCenter - Axis2 * mExtents.z;
107 
108  // Compute d
109  planes[0].d = -(planes[0].n|p0);
110  planes[1].d = -(planes[1].n|p1);
111  planes[2].d = -(planes[2].n|p2);
112  planes[3].d = -(planes[3].n|p3);
113  planes[4].d = -(planes[4].n|p4);
114  planes[5].d = -(planes[5].n|p5);
115 
116  return true;
117 }
bool OBB::ComputePoints ( Point pts) const

Computes the obb points.

Parameters
pts[out] 8 box points
Returns
true if success

Definition at line 126 of file IceOBB.cpp.

127 {
128  // Checkings
129  if(!pts) return false;
130 
131  Point Axis0 = mRot[0];
132  Point Axis1 = mRot[1];
133  Point Axis2 = mRot[2];
134 
135  Axis0 *= mExtents.x;
136  Axis1 *= mExtents.y;
137  Axis2 *= mExtents.z;
138 
139  // 7+------+6 0 = ---
140  // /| /| 1 = +--
141  // / | / | 2 = ++-
142  // / 4+---/--+5 3 = -+-
143  // 3+------+2 / y z 4 = --+
144  // | / | / | / 5 = +-+
145  // |/ |/ |/ 6 = +++
146  // 0+------+1 *---x 7 = -++
147 
148  pts[0] = mCenter - Axis0 - Axis1 - Axis2;
149  pts[1] = mCenter + Axis0 - Axis1 - Axis2;
150  pts[2] = mCenter + Axis0 + Axis1 - Axis2;
151  pts[3] = mCenter - Axis0 + Axis1 - Axis2;
152  pts[4] = mCenter - Axis0 - Axis1 + Axis2;
153  pts[5] = mCenter + Axis0 - Axis1 + Axis2;
154  pts[6] = mCenter + Axis0 + Axis1 + Axis2;
155  pts[7] = mCenter - Axis0 + Axis1 + Axis2;
156 
157  return true;
158 }
bool OBB::ComputeVertexNormals ( Point pts) const

Computes vertex normals.

Parameters
pts[out] 8 box points
Returns
true if success

Definition at line 167 of file IceOBB.cpp.

168 {
169  static float VertexNormals[] =
170  {
178  -INVSQRT3, INVSQRT3, INVSQRT3
179  };
180 
181  if(!pts) return false;
182 
183  const Point* VN = (const Point*)VertexNormals;
184  for(udword i=0;i<8;i++)
185  {
186  pts[i] = VN[i] * mRot;
187  }
188 
189  return true;
190 }
void OBB::ComputeWorldEdgeNormal ( udword  edge_index,
Point world_normal 
) const

Returns world edge normal

Parameters
edge_index[in] 0 <= edge index < 12
world_normal[out] edge normal in world space

Definition at line 244 of file IceOBB.cpp.

245 {
246  OPASSERT(edge_index<12);
247  world_normal = GetLocalEdgeNormals()[edge_index] * mRot;
248 }
bool OBB::ContainsPoint ( const Point p) const

Tests if a point is contained within the OBB.

Parameters
p[in] the world point to test
Returns
true if inside the OBB

Definition at line 33 of file IceOBB.cpp.

34 {
35  // Point in OBB test using lazy evaluation and early exits
36 
37  // Translate to box space
38  Point RelPoint = p - mCenter;
39 
40  // Point * mRot maps from box space to world space
41  // mRot * Point maps from world space to box space (what we need here)
42 
43  float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z;
44  if(f >= mExtents.x || f <= -mExtents.x) return false;
45 
46  f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z;
47  if(f >= mExtents.y || f <= -mExtents.y) return false;
48 
49  f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z;
50  if(f >= mExtents.z || f <= -mExtents.z) return false;
51  return true;
52 }
void OBB::Create ( const AABB aabb,
const Matrix4x4 mat 
)

Builds an OBB from an AABB and a world transform.

Parameters
aabb[in] the aabb
mat[in] the world transform

Definition at line 61 of file IceOBB.cpp.

62 {
63  // Note: must be coherent with Rotate()
64 
65  aabb.GetCenter(mCenter);
66  aabb.GetExtents(mExtents);
67  // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity).
68 
69  // So following what's done in Rotate:
70  // - x-form the center
71  mCenter *= mat;
72  // - combine rotation with identity, i.e. just use given matrix
73  mRot = mat;
74 }
inline_ const Point& Opcode::OBB::GetCenter ( ) const
inline

Definition at line 160 of file Opcode.h.

const udword * OBB::GetEdges ( ) const

Returns edges.

Returns
24 indices (12 edges) indexing the list returned by ComputePoints()

Definition at line 198 of file IceOBB.cpp.

199 {
200  static udword Indices[] = {
201  0, 1, 1, 2, 2, 3, 3, 0,
202  7, 6, 6, 5, 5, 4, 4, 7,
203  1, 5, 6, 2,
204  3, 7, 4, 0
205  };
206  return Indices;
207 }
inline_ const Point& Opcode::OBB::GetExtents ( ) const
inline

Definition at line 161 of file Opcode.h.

const Point * OBB::GetLocalEdgeNormals ( ) const

Returns local edge normals.

Returns
edge normals in local space

Definition at line 215 of file IceOBB.cpp.

216 {
217  static float EdgeNormals[] =
218  {
219  0, -INVSQRT2, -INVSQRT2, // 0-1
220  INVSQRT2, 0, -INVSQRT2, // 1-2
221  0, INVSQRT2, -INVSQRT2, // 2-3
222  -INVSQRT2, 0, -INVSQRT2, // 3-0
223 
224  0, INVSQRT2, INVSQRT2, // 7-6
225  INVSQRT2, 0, INVSQRT2, // 6-5
226  0, -INVSQRT2, INVSQRT2, // 5-4
227  -INVSQRT2, 0, INVSQRT2, // 4-7
228 
229  INVSQRT2, -INVSQRT2, 0, // 1-5
230  INVSQRT2, INVSQRT2, 0, // 6-2
231  -INVSQRT2, INVSQRT2, 0, // 3-7
232  -INVSQRT2, -INVSQRT2, 0 // 4-0
233  };
234  return (const Point*)EdgeNormals;
235 }
inline_ const Matrix3x3& Opcode::OBB::GetRot ( ) const
inline

Definition at line 162 of file Opcode.h.

inline_ void Opcode::OBB::GetRotatedExtents ( Matrix3x3 extents) const
inline

Definition at line 164 of file Opcode.h.

bool OBB::IsInside ( const OBB box) const

Checks the OBB is inside another OBB.

Parameters
box[in] the other OBB
Returns
TRUE if we're inside the other box

Definition at line 292 of file IceOBB.cpp.

293 {
294  // Make a 4x4 from the box & inverse it
295  Matrix4x4 M0Inv;
296  {
297  Matrix4x4 M0 = box.mRot;
298  M0.SetTrans(box.mCenter);
299  InvertPRMatrix(M0Inv, M0);
300  }
301 
302  // With our inversed 4x4, create box1 in space of box0
303  OBB _1in0;
304  Rotate(M0Inv, _1in0);
305 
306  // This should cancel out box0's rotation, i.e. it's now an AABB.
307  // => Center(0,0,0), Rot(identity)
308 
309  // The two boxes are in the same space so now we can compare them.
310 
311  // Create the AABB of (box1 in space of box0)
312  const Matrix3x3& mtx = _1in0.mRot;
313 
314  float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x;
315  if(f > _1in0.mCenter.x) return FALSE;
316  if(-f < _1in0.mCenter.x) return FALSE;
317 
318  f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y;
319  if(f > _1in0.mCenter.y) return FALSE;
320  if(-f < _1in0.mCenter.y) return FALSE;
321 
322  f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z;
323  if(f > _1in0.mCenter.z) return FALSE;
324  if(-f < _1in0.mCenter.z) return FALSE;
325 
326  return TRUE;
327 }
inline_ BOOL Opcode::OBB::IsValid ( ) const
inline

Checks the OBB is valid.

Returns
true if the box is valid

Definition at line 82 of file Opcode.h.

inline_ void Opcode::OBB::Rotate ( const Matrix4x4 mtx,
OBB obb 
) const
inline

Recomputes the OBB after an arbitrary transform by a 4x4 matrix.

Parameters
mtx[in] the transform matrix
obb[out] the transformed OBB

Definition at line 66 of file Opcode.h.

void Opcode::OBB::SetEmpty ( )
inline

Setups an empty OBB.

Definition at line 34 of file Opcode.h.

39  {

Member Data Documentation

Point Opcode::OBB::mCenter

B for Box.

Definition at line 170 of file Opcode.h.

Point Opcode::OBB::mExtents

B for Bounding.

Definition at line 171 of file Opcode.h.

Matrix3x3 Opcode::OBB::mRot

O for Oriented.

Definition at line 172 of file Opcode.h.


The documentation for this class was generated from the following files: