doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Box.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __BV_BOX_H__
30 #define __BV_BOX_H__
31 
32 /*
33 ===============================================================================
34 
35  Oriented Bounding Box
36 
37 ===============================================================================
38 */
39 
40 class idBox {
41 public:
42  idBox( void );
43  explicit idBox( const idVec3 &center, const idVec3 &extents, const idMat3 &axis );
44  explicit idBox( const idVec3 &point );
45  explicit idBox( const idBounds &bounds );
46  explicit idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis );
47 
48  idBox operator+( const idVec3 &t ) const; // returns translated box
49  idBox & operator+=( const idVec3 &t ); // translate the box
50  idBox operator*( const idMat3 &r ) const; // returns rotated box
51  idBox & operator*=( const idMat3 &r ); // rotate the box
52  idBox operator+( const idBox &a ) const;
53  idBox & operator+=( const idBox &a );
54  idBox operator-( const idBox &a ) const;
55  idBox & operator-=( const idBox &a );
56 
57  bool Compare( const idBox &a ) const; // exact compare, no epsilon
58  bool Compare( const idBox &a, const float epsilon ) const; // compare with epsilon
59  bool operator==( const idBox &a ) const; // exact compare, no epsilon
60  bool operator!=( const idBox &a ) const; // exact compare, no epsilon
61 
62  void Clear( void ); // inside out box
63  void Zero( void ); // single point at origin
64 
65  const idVec3 & GetCenter( void ) const; // returns center of the box
66  const idVec3 & GetExtents( void ) const; // returns extents of the box
67  const idMat3 & GetAxis( void ) const; // returns the axis of the box
68  float GetVolume( void ) const; // returns the volume of the box
69  bool IsCleared( void ) const; // returns true if box are inside out
70 
71  bool AddPoint( const idVec3 &v ); // add the point, returns true if the box expanded
72  bool AddBox( const idBox &a ); // add the box, returns true if the box expanded
73  idBox Expand( const float d ) const; // return box expanded in all directions with the given value
74  idBox & ExpandSelf( const float d ); // expand box in all directions with the given value
75  idBox Translate( const idVec3 &translation ) const; // return translated box
76  idBox & TranslateSelf( const idVec3 &translation ); // translate this box
77  idBox Rotate( const idMat3 &rotation ) const; // return rotated box
78  idBox & RotateSelf( const idMat3 &rotation ); // rotate this box
79 
80  float PlaneDistance( const idPlane &plane ) const;
81  int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
82 
83  bool ContainsPoint( const idVec3 &p ) const; // includes touching
84  bool IntersectsBox( const idBox &a ) const; // includes touching
85  bool LineIntersection( const idVec3 &start, const idVec3 &end ) const;
86  // intersection points are (start + dir * scale1) and (start + dir * scale2)
87  bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const;
88 
89  // tight box for a collection of points
90  void FromPoints( const idVec3 *points, const int numPoints );
91  // most tight box for a translation
92  void FromPointTranslation( const idVec3 &point, const idVec3 &translation );
93  void FromBoxTranslation( const idBox &box, const idVec3 &translation );
94  // most tight box for a rotation
95  void FromPointRotation( const idVec3 &point, const idRotation &rotation );
96  void FromBoxRotation( const idBox &box, const idRotation &rotation );
97 
98  void ToPoints( idVec3 points[8] ) const;
99  idSphere ToSphere( void ) const;
100 
101  // calculates the projection of this box onto the given axis
102  void AxisProjection( const idVec3 &dir, float &min, float &max ) const;
103  void AxisProjection( const idMat3 &ax, idBounds &bounds ) const;
104 
105  // calculates the silhouette of the box
106  int GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const;
107  int GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const;
108 
109 private:
113 };
114 
115 extern idBox box_zero;
116 
117 ID_INLINE idBox::idBox( void ) {
118 }
119 
120 ID_INLINE idBox::idBox( const idVec3 &center, const idVec3 &extents, const idMat3 &axis ) {
121  this->center = center;
122  this->extents = extents;
123  this->axis = axis;
124 }
125 
126 ID_INLINE idBox::idBox( const idVec3 &point ) {
127  this->center = point;
128  this->extents.Zero();
129  this->axis.Identity();
130 }
131 
132 ID_INLINE idBox::idBox( const idBounds &bounds ) {
133  this->center = ( bounds[0] + bounds[1] ) * 0.5f;
134  this->extents = bounds[1] - this->center;
135  this->axis.Identity();
136 }
137 
138 ID_INLINE idBox::idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) {
139  this->center = ( bounds[0] + bounds[1] ) * 0.5f;
140  this->extents = bounds[1] - this->center;
141  this->center = origin + this->center * axis;
142  this->axis = axis;
143 }
144 
145 ID_INLINE idBox idBox::operator+( const idVec3 &t ) const {
146  return idBox( center + t, extents, axis );
147 }
148 
149 ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) {
150  center += t;
151  return *this;
152 }
153 
154 ID_INLINE idBox idBox::operator*( const idMat3 &r ) const {
155  return idBox( center * r, extents, axis * r );
156 }
157 
158 ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) {
159  center *= r;
160  axis *= r;
161  return *this;
162 }
163 
164 ID_INLINE idBox idBox::operator+( const idBox &a ) const {
165  idBox newBox;
166  newBox = *this;
167  newBox.AddBox( a );
168  return newBox;
169 }
170 
171 ID_INLINE idBox &idBox::operator+=( const idBox &a ) {
172  idBox::AddBox( a );
173  return *this;
174 }
175 
176 ID_INLINE idBox idBox::operator-( const idBox &a ) const {
177  return idBox( center, extents - a.extents, axis );
178 }
179 
180 ID_INLINE idBox &idBox::operator-=( const idBox &a ) {
181  extents -= a.extents;
182  return *this;
183 }
184 
185 ID_INLINE bool idBox::Compare( const idBox &a ) const {
186  return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) );
187 }
188 
189 ID_INLINE bool idBox::Compare( const idBox &a, const float epsilon ) const {
190  return ( center.Compare( a.center, epsilon ) && extents.Compare( a.extents, epsilon ) && axis.Compare( a.axis, epsilon ) );
191 }
192 
193 ID_INLINE bool idBox::operator==( const idBox &a ) const {
194  return Compare( a );
195 }
196 
197 ID_INLINE bool idBox::operator!=( const idBox &a ) const {
198  return !Compare( a );
199 }
200 
201 ID_INLINE void idBox::Clear( void ) {
202  center.Zero();
203  extents[0] = extents[1] = extents[2] = -idMath::INFINITY;
204  axis.Identity();
205 }
206 
207 ID_INLINE void idBox::Zero( void ) {
208  center.Zero();
209  extents.Zero();
210  axis.Identity();
211 }
212 
213 ID_INLINE const idVec3 &idBox::GetCenter( void ) const {
214  return center;
215 }
216 
217 ID_INLINE const idVec3 &idBox::GetExtents( void ) const {
218  return extents;
219 }
220 
221 ID_INLINE const idMat3 &idBox::GetAxis( void ) const {
222  return axis;
223 }
224 
225 ID_INLINE float idBox::GetVolume( void ) const {
226  return ( extents * 2.0f ).LengthSqr();
227 }
228 
229 ID_INLINE bool idBox::IsCleared( void ) const {
230  return extents[0] < 0.0f;
231 }
232 
233 ID_INLINE idBox idBox::Expand( const float d ) const {
234  return idBox( center, extents + idVec3( d, d, d ), axis );
235 }
236 
237 ID_INLINE idBox &idBox::ExpandSelf( const float d ) {
238  extents[0] += d;
239  extents[1] += d;
240  extents[2] += d;
241  return *this;
242 }
243 
244 ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const {
245  return idBox( center + translation, extents, axis );
246 }
247 
248 ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) {
249  center += translation;
250  return *this;
251 }
252 
253 ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const {
254  return idBox( center * rotation, extents, axis * rotation );
255 }
256 
257 ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) {
258  center *= rotation;
259  axis *= rotation;
260  return *this;
261 }
262 
263 ID_INLINE bool idBox::ContainsPoint( const idVec3 &p ) const {
264  idVec3 lp = p - center;
265  if ( idMath::Fabs( lp * axis[0] ) > extents[0] ||
266  idMath::Fabs( lp * axis[1] ) > extents[1] ||
267  idMath::Fabs( lp * axis[2] ) > extents[2] ) {
268  return false;
269  }
270  return true;
271 }
272 
273 ID_INLINE idSphere idBox::ToSphere( void ) const {
274  return idSphere( center, extents.Length() );
275 }
276 
277 ID_INLINE void idBox::AxisProjection( const idVec3 &dir, float &min, float &max ) const {
278  float d1 = dir * center;
279  float d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) +
280  idMath::Fabs( extents[1] * ( dir * axis[1] ) ) +
281  idMath::Fabs( extents[2] * ( dir * axis[2] ) );
282  min = d1 - d2;
283  max = d1 + d2;
284 }
285 
286 ID_INLINE void idBox::AxisProjection( const idMat3 &ax, idBounds &bounds ) const {
287  for ( int i = 0; i < 3; i++ ) {
288  float d1 = ax[i] * center;
289  float d2 = idMath::Fabs( extents[0] * ( ax[i] * axis[0] ) ) +
290  idMath::Fabs( extents[1] * ( ax[i] * axis[1] ) ) +
291  idMath::Fabs( extents[2] * ( ax[i] * axis[2] ) );
292  bounds[0][i] = d1 - d2;
293  bounds[1][i] = d1 + d2;
294  }
295 }
296 
297 #endif /* !__BV_BOX_H__ */
bool AddPoint(const idVec3 &v)
Definition: Box.cpp:194
GLsizei const GLfloat * points
Definition: glext.h:3884
static const float INFINITY
Definition: Math.h:218
void FromPointRotation(const idVec3 &point, const idRotation &rotation)
Definition: Box.cpp:741
#define min(a, b)
idBox operator+(const idVec3 &t) const
Definition: Box.h:145
bool Compare(const idVec3 &a) const
Definition: Vector.h:496
bool Compare(const idMat3 &a) const
Definition: Matrix.h:561
const idVec3 & GetExtents(void) const
Definition: Box.h:217
const GLdouble * v
Definition: glext.h:2936
bool ContainsPoint(const idVec3 &p) const
Definition: Box.h:263
bool operator==(const idBox &a) const
Definition: Box.h:193
bool AddBox(const idBox &a)
Definition: Box.cpp:245
idBox operator*(const idMat3 &r) const
Definition: Box.h:154
idVec3 extents
Definition: Box.h:111
idBox & operator+=(const idVec3 &t)
Definition: Box.h:149
idBox & operator*=(const idMat3 &r)
Definition: Box.h:158
Definition: Vector.h:316
void Zero(void)
Definition: Box.h:207
void ToPoints(idVec3 points[8]) const
Definition: Box.cpp:761
void Identity(void)
Definition: Matrix.h:591
int i
Definition: process.py:33
void FromBoxTranslation(const idBox &box, const idVec3 &translation)
Definition: Box.cpp:730
idBox Expand(const float d) const
Definition: Box.h:233
idSphere ToSphere(void) const
Definition: Box.h:273
void FromPointTranslation(const idVec3 &point, const idVec3 &translation)
Definition: Box.cpp:719
float GetVolume(void) const
Definition: Box.h:225
idBox Rotate(const idMat3 &rotation) const
Definition: Box.h:253
float Length(void) const
Definition: Vector.h:631
int GetParallelProjectionSilhouetteVerts(const idVec3 &projectionDir, idVec3 silVerts[6]) const
Definition: Box.cpp:822
GLuint GLuint end
Definition: glext.h:2845
idBox Translate(const idVec3 &translation) const
Definition: Box.h:244
static float Fabs(float f)
Definition: Math.h:779
idBox box_zero
idBox & operator-=(const idBox &a)
Definition: Box.h:180
bool Compare(const idBox &a) const
Definition: Box.h:185
Definition: Plane.h:71
bool operator!=(const idBox &a) const
Definition: Box.h:197
idBox & TranslateSelf(const idVec3 &translation)
Definition: Box.h:248
bool IsCleared(void) const
Definition: Box.h:229
idBox & RotateSelf(const idMat3 &rotation)
Definition: Box.h:257
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
const idMat3 & GetAxis(void) const
Definition: Box.h:221
const idVec3 & GetCenter(void) const
Definition: Box.h:213
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
bool IntersectsBox(const idBox &a) const
Definition: Box.cpp:376
Definition: Matrix.h:333
void FromBoxRotation(const idBox &box, const idRotation &rotation)
Definition: Box.cpp:752
idBox & ExpandSelf(const float d)
Definition: Box.h:237
tuple f
Definition: idal.py:89
#define ON_EPSILON
Definition: Plane.h:44
idVec3 center
Definition: Box.h:110
void Clear(void)
Definition: Box.h:201
int GetProjectionSilhouetteVerts(const idVec3 &projectionOrigin, idVec3 silVerts[6]) const
Definition: Box.cpp:787
idMat3 axis
Definition: Box.h:112
float PlaneDistance(const idPlane &plane) const
Definition: Box.cpp:332
idBox(void)
Definition: Box.h:117
#define max(x, y)
Definition: os.h:70
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
Definition: Box.cpp:538
GLfloat GLfloat p
Definition: glext.h:4674
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2) const
Definition: Box.cpp:614
idBox operator-(const idBox &a) const
Definition: Box.h:176
void Zero(void)
Definition: Vector.h:415
Definition: Box.h:40
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
Definition: Box.cpp:354
GLuint start
Definition: glext.h:2845
void FromPoints(const idVec3 *points, const int numPoints)
Definition: Box.cpp:637
void AxisProjection(const idVec3 &dir, float &min, float &max) const
Definition: Box.h:277
GLdouble GLdouble t
Definition: glext.h:2943