1 //------------------------------------------------------------------------------
2 // File : SkyMinMaxBox.cpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 // The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its
8 // documentation for any purpose is hereby granted without fee, provided that
9 // the above copyright notice appear in all copies and that both that copyright
10 // notice and this permission notice appear in supporting documentation.
11 // Binaries may be compiled with this software without any royalties or
14 // The author(s) and The University of North Carolina at Chapel Hill make no
15 // representations about the suitability of this software for any purpose.
16 // It is provided "as is" without express or
19 * @file SkyMinMaxBox.cpp
21 * Implementation of a bounding box class. Modified from Wes Hunt's BoundingBox.
23 #include "SkyMinMaxBox.hpp"
24 #include "camutils.hpp"
29 //------------------------------------------------------------------------------
30 // Function : SkyMinMaxBox::SkyMinMaxBox
32 //------------------------------------------------------------------------------
34 * @fn SkyMinMaxBox::SkyMinMaxBox()
37 SkyMinMaxBox::SkyMinMaxBox()
43 //------------------------------------------------------------------------------
44 // Function : SkyMinMaxBox::Clear
46 //------------------------------------------------------------------------------
48 * @fn SkyMinMaxBox::Clear()
49 * @brief Reset the min and max to floating point extremes.
52 void SkyMinMaxBox::Clear()
63 //------------------------------------------------------------------------------
64 // Function : SkyMinMaxBox::PointInBBox
66 //------------------------------------------------------------------------------
68 * @fn SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
69 * @brief Queries pt to see if it is inside the SkyMinMaxBox.
72 bool SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
74 if( (pt.x >= _min.x) && ( pt.x <= _max.x ) )
76 if( (pt.y >= _min.y) && ( pt.y <= _max.y ) )
78 if( (pt.z >= _min.z) && ( pt.z <= _max.z ) )
87 //------------------------------------------------------------------------------
88 // Function : SkyMinMaxBox::AddPoint
90 //------------------------------------------------------------------------------
92 * @fn SkyMinMaxBox::AddPoint( float x , float y , float z )
93 * @brief Adds a point and adjusts bounds if necessary.
95 void SkyMinMaxBox::AddPoint( float x , float y , float z )
112 // update the center and radius
117 //------------------------------------------------------------------------------
118 // Function : SkyMinMaxBox::AddPoint
120 //------------------------------------------------------------------------------
122 * @fn SkyMinMaxBox::AddPoint( const Vec3f &pt )
123 * @brief Adds a point and adjusts bounds if necessary.
125 void SkyMinMaxBox::AddPoint( const Vec3f &pt )
142 // update the center and radius
147 //------------------------------------------------------------------------------
148 // Function : SkyMinMaxBox::ViewFrustumCull
150 //------------------------------------------------------------------------------
152 * @fn SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
153 * @brief Returns true if bounding volume culled against cam.
155 * This function must transform the object space min and max then adjust the new
156 * min and max box by expanding it. Each of the 8 points must be tested. This
157 * is faster then doing an xform of all the geometry points and finding a tight
158 * fitting min max box, however this will be enlarged.
160 bool SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
162 SkyMinMaxBox xBV; // Xformed Bounding Volume
163 Vec3f xMin = mat * _min; // Xformed _min
164 Vec3f xMax = mat * _max; // Xformed _max
165 Vec3f offset = _max - _min; // Offset for sides of MinMaxBox
168 xBV.Clear(); // Clear the values first
170 // First find the new minimum x,y,z
172 tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
178 tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
184 tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
189 // Second find the new maximum x,y,z
191 tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
197 tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
203 tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
208 // Use the camera utility function that already exists for minmax boxes
209 return VFC(&cam, xBV.GetMin(), xBV.GetMax());
213 //------------------------------------------------------------------------------
214 // Function : SkyMinMaxBox::Transform
216 //------------------------------------------------------------------------------
218 * @fn SkyMinMaxBox::Transform(const Mat44f& mat)
219 * @brief @todo <WRITE BRIEF SkyMinMaxBox::Transform DOCUMENTATION>
221 * @todo <WRITE EXTENDED SkyMinMaxBox::Transform FUNCTION DOCUMENTATION>
223 void SkyMinMaxBox::Transform(const Mat44f& mat)
228 for (int i = 0; i < 8; ++i)
230 AddPoint(mat * verts[i]);
234 //------------------------------------------------------------------------------
235 // Function : SkyMinMaxBox::_UpdateSphere
237 //------------------------------------------------------------------------------
239 * @fn SkyMinMaxBox::_UpdateSphere()
240 * @brief Updates the bounding sphere based on min and max.
242 void SkyMinMaxBox::_UpdateSphere()
250 _rRadius = rad.Length();
255 //------------------------------------------------------------------------------
256 // Function : SkyMinMaxBox::Display
258 //------------------------------------------------------------------------------
260 * @fn SkyMinMaxBox::Display() const
261 * @brief @todo <WRITE BRIEF SkyMinMaxBox::Display DOCUMENTATION>
263 * @todo <WRITE EXTENDED SkyMinMaxBox::Display FUNCTION DOCUMENTATION>
265 void SkyMinMaxBox::Display() const
270 glPushAttrib(GL_LINE_BIT);
273 glBegin(GL_LINE_LOOP); // TOP FACE
274 glVertex3fv(V[4]); glVertex3fv(V[5]); glVertex3fv(V[1]); glVertex3fv(V[0]);
276 glBegin(GL_LINE_LOOP); // BOTTOM FACE
277 glVertex3fv(V[3]); glVertex3fv(V[2]); glVertex3fv(V[6]); glVertex3fv(V[7]);
279 glBegin(GL_LINE_LOOP); // LEFT FACE
280 glVertex3fv(V[1]); glVertex3fv(V[5]); glVertex3fv(V[6]); glVertex3fv(V[2]);
282 glBegin(GL_LINE_LOOP); // RIGHT FACE
283 glVertex3fv(V[0]); glVertex3fv(V[3]); glVertex3fv(V[7]); glVertex3fv(V[4]);
285 glBegin(GL_LINE_LOOP); // NEAR FACE
286 glVertex3fv(V[1]); glVertex3fv(V[2]); glVertex3fv(V[3]); glVertex3fv(V[0]);
288 glBegin(GL_LINE_LOOP); // FAR FACE
289 glVertex3fv(V[4]); glVertex3fv(V[7]); glVertex3fv(V[6]); glVertex3fv(V[5]);
295 //-----------------------------------------------------------------------------
296 // Calculates the eight corner vertices of the MinMaxBox.
297 // V must be prealloced.
300 // 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
301 // | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
304 //-----------------------------------------------------------------------------
306 //------------------------------------------------------------------------------
307 // Function : SkyMinMaxBox::_CalcVerts
309 //------------------------------------------------------------------------------
311 * @fn SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
312 * @brief @todo <WRITE BRIEF SkyMinMaxBox::_CalcVerts DOCUMENTATION>
314 * @todo <WRITE EXTENDED SkyMinMaxBox::_CalcVerts FUNCTION DOCUMENTATION>
316 void SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
318 pVerts[0].Set(_max); pVerts[4].Set(_max.x, _max.y, _min.z);
319 pVerts[1].Set(_min.x, _max.y, _max.z); pVerts[5].Set(_min.x, _max.y, _min.z);
320 pVerts[2].Set(_min.x, _min.y, _max.z); pVerts[6].Set(_min);
321 pVerts[3].Set(_max.x, _min.y, _max.z); pVerts[7].Set(_max.x, _min.y, _min.z);