TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::Box Class Reference

An arbitrary (oriented) 3D box, useful as a bounding box. More...

#include <Box.h>

Public Member Functions

 Box ()
 
 Box (const Any &a)
 
 Box (const Vector3 &min, const Vector3 &max)
 
 Box (const Vector3 &osMin, const Vector3 &osMax, const CoordinateFrame &frame)
 
 Box (class BinaryInput &b)
 
 Box (const class AABox &b)
 
 Box (const Point3 &p)
 
Any toAny () const
 
void serialize (class BinaryOutput &b) const
 
void deserialize (class BinaryInput &b)
 
CoordinateFrame localFrame () const
 
void getLocalFrame (CoordinateFrame &frame) const
 
Box operator* (float f) const
 
Vector3 center () const
 
Vector3 corner (int i) const
 
Vector3 axis (int a) const
 
float extent (int a) const
 
Vector3 extent () const
 
void getFaceCorners (int f, Vector3 &v0, Vector3 &v1, Vector3 &v2, Vector3 &v3) const
 
bool culledBy (const Array< Plane > &plane, int32 &cullingPlaneIndex, const uint32 testMask, uint32 &childMask) const
 
bool culledBy (const Array< Plane > &plane, int32 &cullingPlaneIndex=dummy, const uint32 testMask=-1) const
 
bool contains (const Vector3 &point) const
 
float area () const
 
float volume () const
 
void getRandomSurfacePoint (Vector3 &P, Vector3 &N=Vector3::ignore()) const
 
Vector3 randomInteriorPoint () const
 
void getBounds (class AABox &) const
 
bool isFinite () const
 

Static Public Member Functions

static Box inf ()
 

Private Member Functions

void init (const Vector3 &min, const Vector3 &max)
 

Private Attributes

Vector3 _edgeVector [3]
 
Point3 _center
 
float _area
 
float _volume
 

Static Private Attributes

static int32 dummy = 0
 

Friends

class CoordinateFrame
 

Detailed Description

An arbitrary (oriented) 3D box, useful as a bounding box.

To construct a box from a coordinate frame, center and extent, use the idiom: Box box = cframe.toObjectSpace(Box(center - extent/2, center + extent/2));

Constructor & Destructor Documentation

G3D::Box::Box ( )
21  : _area(0), _volume(0) {
22 }
float _area
Definition: Box.h:49
float _volume
Definition: Box.h:51

+ Here is the caller graph for this function:

G3D::Box::Box ( const Any a)
explicit
57  {
58  if (a.name() == "Box::inf") {
59  *this = Box::inf();
60  } else {
61  a.verifyName("Box", "AABox", "Point3");
62 
63  if (a.name() == "Point3") {
64  *this = Box(Point3(a));
65  } else if (a.size() == 1) {
66  // Single point
67  *this = Box(Point3(a[0]));
68  } else if (a.size() == 2) {
69  *this = Box(Point3(a[0]), Point3(a[1]));
70  } else {
71  // Oriented box
72  a.verifySize(2);
73  a.verifyName("Box");
74  *this = Box(Point3(a[0]), Point3(a[1]), CFrame(a[2]));
75  }
76  }
77 }
static Box inf()
Definition: Box.cpp:458
Box()
Definition: Box.cpp:21
class CoordinateFrame CFrame
Definition: Box2D.h:22
Vector3 Point3
Definition: Vector3.h:820

+ Here is the call graph for this function:

G3D::Box::Box ( const Vector3 min,
const Vector3 max 
)

Constructs a box from two opposite corners.

27  {
28  init(min.min(max), min.max(max));
29 }
void init(const Vector3 &min, const Vector3 &max)
Definition: Box.cpp:149
T max(const T &x, const T &y)
Definition: g3dmath.h:320
T min(const T &x, const T &y)
Definition: g3dmath.h:305

+ Here is the call graph for this function:

G3D::Box::Box ( const Vector3 osMin,
const Vector3 osMax,
const CoordinateFrame frame 
)
G3D::Box::Box ( class BinaryInput b)
52  {
53  deserialize(b);
54 }
void deserialize(class BinaryInput &b)
Definition: Box.cpp:129

+ Here is the call graph for this function:

G3D::Box::Box ( const class AABox b)
G3D::Box::Box ( const Point3 p)
explicit
32  {
33  init(min, min);
34 }
void init(const Vector3 &min, const Vector3 &max)
Definition: Box.cpp:149
T min(const T &x, const T &y)
Definition: g3dmath.h:305

+ Here is the call graph for this function:

Member Function Documentation

float G3D::Box::area ( ) const
222  {
223  return _area;
224 }
float _area
Definition: Box.h:49
Vector3 G3D::Box::axis ( int  a) const
inline

Unit length.

137  {
138  debugAssert(a < 3);
139  return _edgeVector[a].direction();
140  }
Vector3 direction() const
Definition: Vector3.h:756
#define debugAssert(exp)
Definition: debugAssert.h:160
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Vector3 G3D::Box::center ( ) const
inline

Returns the centroid of the box.

103  {
104  return _center;
105  }
Point3 _center
Definition: Box.h:47

+ Here is the caller graph for this function:

bool G3D::Box::contains ( const Vector3 point) const
386  {
387 
388  // Form axes from three edges, transform the point into that
389  // space, and perform 3 interval tests
390  // TODO: Write in a more intuitive way. I left it as it was before after figuring it out, but
391  // this should make no sense to someone who is just starting to read this code.
392  const Vector3& u = _edgeVector[2];
393  const Vector3& v = _edgeVector[1];
394  const Vector3& w = _edgeVector[0];
395 
396  Matrix3 M = Matrix3(u.x, v.x, w.x,
397  u.y, v.y, w.y,
398  u.z, v.z, w.z);
399 
400  // M^-1 * (point - _corner[0]) = point in unit cube's object space
401  // compute the inverse of M
402  Vector3 osPoint = M.inverse() * (point - corner(0));
403 
404  return
405  (osPoint.x >= 0) &&
406  (osPoint.y >= 0) &&
407  (osPoint.z >= 0) &&
408  (osPoint.x <= 1) &&
409  (osPoint.y <= 1) &&
410  (osPoint.z <= 1);
411 }
Vector3 corner(int i) const
Definition: Box.cpp:189
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Vector3 G3D::Box::corner ( int  i) const

    

    2--------3
   / :      /|
  /  :     / |
 6--------7  |
 |   :    |  |
 |   0....|..1
 | /      | /
 |/       |/
 4--------5

  y  
  ^ 
  |
  |-->x
z/


    

189  {
190  debugAssert(i < 8);
191  // The corner forms a bit mask (xyz), where a one indicates we should
192  // add half of the corresponding edge vector from center, and a zero indicates
193  // we should subtract it. Note:
194  // 1 = 001
195  // 2 = 010
196  // 4 = 100
197  //
198  // The following bit-hacky code shows this directly:
199  // return _center + ((_edgeVector[0] * ((i&1) - 0.5) +
200  // _edgeVector[1] * (((i>>1)&1) - 0.5) +
201  // _edgeVector[2] * (((i>>2)&1) - 0.5)));
202  // This method is implemented as a swtich statement due to being marginally faster than the bit-hack method
203  // Also, the _center + 0.5f * (...) is repeated every time for similarly speed-based reasons.
204  switch(i) {
205  case 0: return _center + (0.5f * (-_edgeVector[0] - _edgeVector[1] - _edgeVector[2]));
206  case 1: return _center + (0.5f * ( _edgeVector[0] - _edgeVector[1] - _edgeVector[2]));
207  case 2: return _center + (0.5f * (-_edgeVector[0] + _edgeVector[1] - _edgeVector[2]));
208  case 3: return _center + (0.5f * ( _edgeVector[0] + _edgeVector[1] - _edgeVector[2]));
209  case 4: return _center + (0.5f * (-_edgeVector[0] - _edgeVector[1] + _edgeVector[2]));
210  case 5: return _center + (0.5f * ( _edgeVector[0] - _edgeVector[1] + _edgeVector[2]));
211  case 6: return _center + (0.5f * (-_edgeVector[0] + _edgeVector[1] + _edgeVector[2]));
212  default: return _center + (0.5f * ( _edgeVector[0] + _edgeVector[1] + _edgeVector[2]));//case 7
213  }
214 
215 }
Point3 _center
Definition: Box.h:47
#define debugAssert(exp)
Definition: debugAssert.h:160
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the caller graph for this function:

bool G3D::Box::culledBy ( const Array< Plane > &  plane,
int32 cullingPlaneIndex,
const uint32  testMask,
uint32 childMask 
) const
bool G3D::Box::culledBy ( const Array< Plane > &  plane,
int32 cullingPlaneIndex = dummy,
const uint32  testMask = -1 
) const

Conservative culling test that does not produce a mask for children.

void G3D::Box::deserialize ( class BinaryInput b)
129  {
130  int i;
131  for (i = 0; i < 3; ++i) {
132  _edgeVector[i].deserialize(b);
133  }
134  _center.deserialize(b);
135 
136  float extent0 = extent(0);
137  float extent1 = extent(1);
138  float extent2 = extent(2);
139  _volume = extent0 * extent1 * extent2;
140 
141  _area = 2 *
142  (extent0 * extent1 +
143  extent1 * extent2 +
144  extent2 * extent0);
145 }
Vector3 extent() const
Definition: Box.h:151
float _area
Definition: Box.h:49
Point3 _center
Definition: Box.h:47
float _volume
Definition: Box.h:51
void deserialize(class BinaryInput &b)
Definition: Vector3.cpp:190
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float G3D::Box::extent ( int  a) const
inline

Distance from corner(0) to the next corner along the box's local axis a.

146  {
147  debugAssert(a < 3);
148  return _edgeVector[a].length();
149  }
float length() const
Definition: Vector3.h:751
#define debugAssert(exp)
Definition: debugAssert.h:160
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Vector3 G3D::Box::extent ( ) const
inline
151  {
152  return Vector3(_edgeVector[0].length(), _edgeVector[1].length(), _edgeVector[2].length());
153  }
float length(float v)
Definition: vectorMath.h:208
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Box::getBounds ( class AABox aabb) const
463  {
464  debugAssert(! _edgeVector[0].isNaN());
466  aabb = AABox::empty();
467  for (int i = 0; i < 8; ++i) {
468  aabb.merge(corner(i));
469  }
470 }
bool isNaN(double x)
Definition: g3dmath.cpp:56
Vector3 corner(int i) const
Definition: Box.cpp:189
Point3 _center
Definition: Box.h:47
static const AABox & empty()
Definition: AABox.cpp:61
#define debugAssert(exp)
Definition: debugAssert.h:160
Vector3 _edgeVector[3]
Definition: Box.h:45
bool isNaN() const
Definition: Vector3.cpp:83

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Box::getFaceCorners ( int  f,
Vector3 v0,
Vector3 v1,
Vector3 v2,
Vector3 v3 
) const

Returns the four corners of a face (0 <= f < 6). The corners are returned to form a clockwise quad facing outwards.

  +--------+
 / :      /|
/  :     / |

+-----—+ | | : | | | +....|..+ | / | / |/ |/ +-----—+

y ^ | |–>x z/ Faces are in the following order: 0: -Z 1: X 2: Z 3: Y 4: -X 5: -Y

248  {
249  switch (f) {
250  case 0:
251  v0 = corner(0); v1 = corner(2); v2 = corner(3); v3 = corner(1);
252  break;
253 
254  case 1:
255  v0 = corner(1); v1 = corner(3); v2 = corner(7); v3 = corner(5);
256  break;
257 
258  case 2:
259  v0 = corner(6); v1 = corner(4); v2 = corner(5); v3 = corner(7);
260  break;
261 
262  case 3:
263  v0 = corner(3); v1 = corner(2); v2 = corner(6); v3 = corner(7);
264  break;
265 
266  case 4:
267  v0 = corner(2); v1 = corner(0); v2 = corner(4); v3 = corner(6);
268  break;
269 
270  case 5:
271  v0 = corner(1); v1 = corner(5); v2 = corner(4); v3 = corner(0);
272  break;
273 
274  default:
275  debugAssert((f >= 0) && (f < 6));
276  }
277 }
Vector3 corner(int i) const
Definition: Box.cpp:189
#define debugAssert(exp)
Definition: debugAssert.h:160

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Box::getLocalFrame ( CoordinateFrame frame) const
See also
localFrame
227  {
228  const Vector3& axis0 = axis(0);
229  const Vector3& axis1 = axis(1);
230  const Vector3& axis2 = axis(2);
231 
232  frame.rotation = Matrix3(
233  axis0[0], axis1[0], axis2[0],
234  axis0[1], axis1[1], axis2[1],
235  axis0[2], axis1[2], axis2[2]);
236 
237  frame.translation = _center;
238 }
Vector3 axis(int a) const
Definition: Box.h:137
Point3 _center
Definition: Box.h:47

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Box::getRandomSurfacePoint ( Vector3 P,
Vector3 N = Vector3::ignore() 
) const
416  {
417  float aXY = extent(0) * extent(1);
418  float aYZ = extent(1) * extent(2);
419  float aZX = extent(2) * extent(0);
420 
421  float r = (float)uniformRandom(0, aXY + aYZ + aZX);
422 
423  // Choose evenly between positive and negative face planes
424  float d = (uniformRandom(0, 1) < 0.5f) ? -1.0f : 1.0f;
425 
426  // The probability of choosing a given face is proportional to
427  // its area.
428  if (r < aXY) {
429  P = _edgeVector[0] * (float)uniformRandom(-0.5, 0.5) +
430  _edgeVector[1] * (float)uniformRandom(-0.5, 0.5) +
431  _center + _edgeVector[2] * d * 0.5f;
432  N = axis(2) * d;
433  } else if (r < aYZ) {
434  P = _edgeVector[1] * (float)uniformRandom(-0.5, 0.5) +
435  _edgeVector[2] * (float)uniformRandom(-0.5, 0.5) +
436  _center + _edgeVector[0] * d * 0.5f;
437  N = axis(0) * d;
438  } else {
439  P = _edgeVector[2] * (float)uniformRandom(-0.5, 0.5) +
440  _edgeVector[0] *(float) uniformRandom(-0.5, 0.5) +
441  _center + _edgeVector[1] * d * 0.5f;
442  N = axis(1) * d;
443  }
444 }
Vector3 axis(int a) const
Definition: Box.h:137
Vector3 extent() const
Definition: Box.h:151
float uniformRandom(float low=0.0f, float hi=1.0f)
Definition: g3dmath.h:694
Point3 _center
Definition: Box.h:47
Vector3 _edgeVector[3]
Definition: Box.h:45
uint8 const P[]
Definition: AuthenticationPackets.cpp:225

+ Here is the call graph for this function:

Box G3D::Box::inf ( )
static
458  {
459  return Box(-Vector3::inf(), Vector3::inf());
460 }
Box()
Definition: Box.cpp:21
static const Vector3 & inf()
Definition: Vector3.cpp:124

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::Box::init ( const Vector3 min,
const Vector3 max 
)
private
150  {
151 
152  debugAssert(
153  (min.x <= max.x) &&
154  (min.y <= max.y) &&
155  (min.z <= max.z));
156 
157  _center = (max + min) * 0.5f;
158 
159  Vector3 bounds = Vector3(max.x - min.x, max.y - min.y, max.z - min.z);
160  _edgeVector[0] = Vector3(bounds.x, 0, 0);
161  _edgeVector[1] = Vector3(0, bounds.y, 0);
162  _edgeVector[2] = Vector3(0, 0, bounds.z);
163  bool finiteExtent = true;
164 
165  for (int i = 0; i < 3; ++i) {
166  if (! G3D::isFinite(extent(i))) {
167  finiteExtent = false;
168  // If the extent is infinite along an axis, make the center zero to avoid NaNs
169  _center[i] = 0.0f;
170  }
171  }
172 
173 
174  if (finiteExtent) {
175  _volume = bounds.x * bounds.y * bounds.z;
176  } else {
177  _volume = G3D::finf();
178  }
179 
180  debugAssert(! _edgeVector[0].isNaN());
181 
182  _area = 2 *
183  (bounds.x * bounds.y +
184  bounds.y * bounds.z +
185  bounds.z * bounds.x);
186 }
float finf()
Definition: g3dmath.cpp:71
Vector3 extent() const
Definition: Box.h:151
bool isNaN(double x)
Definition: g3dmath.cpp:56
float _area
Definition: Box.h:49
T max(const T &x, const T &y)
Definition: g3dmath.h:320
Point3 _center
Definition: Box.h:47
float _volume
Definition: Box.h:51
T min(const T &x, const T &y)
Definition: g3dmath.h:305
#define debugAssert(exp)
Definition: debugAssert.h:160
Vector3 _edgeVector[3]
Definition: Box.h:45
bool isFinite(double x)
Definition: g3dmath.h:525

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool G3D::Box::isFinite ( ) const
inline
228  {
229  return G3D::isFinite(_volume);
230  }
float _volume
Definition: Box.h:51
bool isFinite(double x)
Definition: g3dmath.h:525

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

CoordinateFrame G3D::Box::localFrame ( ) const

Returns the object to world transformation for this box, where the origin is the center of the box. localFrame().worldToObject(...) takes objects into the space where the box axes are (1,0,0), (0,1,0), (0,0,1). Note that there is no scaling in this transformation.

241  {
242  CoordinateFrame out;
243  getLocalFrame(out);
244  return out;
245 }
friend class CoordinateFrame
Definition: Box.h:40
void getLocalFrame(CoordinateFrame &frame) const
Definition: Box.cpp:227

+ Here is the call graph for this function:

Box G3D::Box::operator* ( float  f) const
104  {
105  Box b;
106 
107  for (int i = 0; i < 3; ++i) {
108  b._edgeVector[i] = _edgeVector[i] * f;
109  b._center = _center * f;
110  b._area = _area * square(f * f);
111  b._volume = _area * (f * f * f);
112  }
113 
114  return b;
115 }
Box()
Definition: Box.cpp:21
float _area
Definition: Box.h:49
Point3 _center
Definition: Box.h:47
double square(double fValue)
Definition: g3dmath.h:698
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

Vector3 G3D::Box::randomInteriorPoint ( ) const

Uniformly distributed on the interior (includes surface)

447  {
448  Vector3 sum = _center;
449 
450  for (int a = 0; a < 3; ++a) {
451  sum += _edgeVector[a] * (float)uniformRandom(-0.5, 0.5);
452  }
453 
454  return sum;
455 }
float uniformRandom(float low=0.0f, float hi=1.0f)
Definition: g3dmath.h:694
Point3 _center
Definition: Box.h:47
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

void G3D::Box::serialize ( class BinaryOutput b) const
118  {
119  int i;
120  for (i = 0; i < 3; ++i) {
121  _edgeVector[i].serialize(b);
122  }
123  _center.serialize(b);
124 
125  // Other state can be reconstructed
126 }
Point3 _center
Definition: Box.h:47
void serialize(class BinaryOutput &b) const
Definition: Vector3.cpp:219
Vector3 _edgeVector[3]
Definition: Box.h:45

+ Here is the call graph for this function:

Any G3D::Box::toAny ( ) const
80  {
81  if (! isFinite()) {
82  return Any(Any::ARRAY, "Box::inf");
83  } else {
84  CFrame c;
85  getLocalFrame(c);
86  if (c.rotation == Matrix3::identity()) {
87  // Aligned box
88  AABox b;
89  getBounds(b);
90  return b.toAny();
91  } else {
92  // Oriented box
93  Any a(Any::ARRAY, "Box");
94 
95  AABox b;
96  c.toObjectSpace(*this).getBounds(b);
97  a.append(b.low(), b.high(), c);
98  return a;
99  }
100  }
101 }
void getBounds(class AABox &) const
Definition: Box.cpp:463
class CoordinateFrame CFrame
Definition: Box2D.h:22
Definition: Any.h:187
void getLocalFrame(CoordinateFrame &frame) const
Definition: Box.cpp:227
bool isFinite() const
Definition: Box.h:228
static const Matrix3 & identity()
Definition: Matrix3.cpp:70

+ Here is the call graph for this function:

float G3D::Box::volume ( ) const
217  {
218  return _volume;
219 }
float _volume
Definition: Box.h:51

Friends And Related Function Documentation

friend class CoordinateFrame
friend

Member Data Documentation

float G3D::Box::_area
private
Point3 G3D::Box::_center
private
Vector3 G3D::Box::_edgeVector[3]
private

Axes with length equal to the 4 edges that run along each of them

float G3D::Box::_volume
private
int G3D::Box::dummy = 0
staticprivate

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