2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
33 ===============================================================================
37 ===============================================================================
43 explicit idBox( const idVec3 ¢er, 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 );
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 );
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
62 void Clear( void ); // inside out box
63 void Zero( void ); // single point at origin
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
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
80 float PlaneDistance( const idPlane &plane ) const;
81 int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
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;
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 );
98 void ToPoints( idVec3 points[8] ) const;
99 idSphere ToSphere( void ) const;
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;
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;
115 extern idBox box_zero;
117 ID_INLINE idBox::idBox( void ) {
120 ID_INLINE idBox::idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ) {
121 this->center = center;
122 this->extents = extents;
126 ID_INLINE idBox::idBox( const idVec3 &point ) {
127 this->center = point;
128 this->extents.Zero();
129 this->axis.Identity();
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();
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;
145 ID_INLINE idBox idBox::operator+( const idVec3 &t ) const {
146 return idBox( center + t, extents, axis );
149 ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) {
154 ID_INLINE idBox idBox::operator*( const idMat3 &r ) const {
155 return idBox( center * r, extents, axis * r );
158 ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) {
164 ID_INLINE idBox idBox::operator+( const idBox &a ) const {
171 ID_INLINE idBox &idBox::operator+=( const idBox &a ) {
176 ID_INLINE idBox idBox::operator-( const idBox &a ) const {
177 return idBox( center, extents - a.extents, axis );
180 ID_INLINE idBox &idBox::operator-=( const idBox &a ) {
181 extents -= a.extents;
185 ID_INLINE bool idBox::Compare( const idBox &a ) const {
186 return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) );
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 ) );
193 ID_INLINE bool idBox::operator==( const idBox &a ) const {
197 ID_INLINE bool idBox::operator!=( const idBox &a ) const {
198 return !Compare( a );
201 ID_INLINE void idBox::Clear( void ) {
203 extents[0] = extents[1] = extents[2] = -idMath::INFINITY;
207 ID_INLINE void idBox::Zero( void ) {
213 ID_INLINE const idVec3 &idBox::GetCenter( void ) const {
217 ID_INLINE const idVec3 &idBox::GetExtents( void ) const {
221 ID_INLINE const idMat3 &idBox::GetAxis( void ) const {
225 ID_INLINE float idBox::GetVolume( void ) const {
226 return ( extents * 2.0f ).LengthSqr();
229 ID_INLINE bool idBox::IsCleared( void ) const {
230 return extents[0] < 0.0f;
233 ID_INLINE idBox idBox::Expand( const float d ) const {
234 return idBox( center, extents + idVec3( d, d, d ), axis );
237 ID_INLINE idBox &idBox::ExpandSelf( const float d ) {
244 ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const {
245 return idBox( center + translation, extents, axis );
248 ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) {
249 center += translation;
253 ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const {
254 return idBox( center * rotation, extents, axis * rotation );
257 ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) {
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] ) {
273 ID_INLINE idSphere idBox::ToSphere( void ) const {
274 return idSphere( center, extents.Length() );
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] ) );
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;
297 #endif /* !__BV_BOX_H__ */