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.
25 # include <simgear_config.h>
34 #include "SkyMinMaxBox.hpp"
35 #include "camutils.hpp"
39 //------------------------------------------------------------------------------
40 // Function : SkyMinMaxBox::SkyMinMaxBox
42 //------------------------------------------------------------------------------
44 * @fn SkyMinMaxBox::SkyMinMaxBox()
47 SkyMinMaxBox::SkyMinMaxBox()
53 //------------------------------------------------------------------------------
54 // Function : SkyMinMaxBox::Clear
56 //------------------------------------------------------------------------------
58 * @fn SkyMinMaxBox::Clear()
59 * @brief Reset the min and max to floating point extremes.
62 void SkyMinMaxBox::Clear()
73 //------------------------------------------------------------------------------
74 // Function : SkyMinMaxBox::PointInBBox
76 //------------------------------------------------------------------------------
78 * @fn SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
79 * @brief Queries pt to see if it is inside the SkyMinMaxBox.
82 bool SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
84 if( (pt.x >= _min.x) && ( pt.x <= _max.x ) )
86 if( (pt.y >= _min.y) && ( pt.y <= _max.y ) )
88 if( (pt.z >= _min.z) && ( pt.z <= _max.z ) )
97 //------------------------------------------------------------------------------
98 // Function : SkyMinMaxBox::AddPoint
100 //------------------------------------------------------------------------------
102 * @fn SkyMinMaxBox::AddPoint( float x , float y , float z )
103 * @brief Adds a point and adjusts bounds if necessary.
105 void SkyMinMaxBox::AddPoint( float x , float y , float z )
122 // update the center and radius
127 //------------------------------------------------------------------------------
128 // Function : SkyMinMaxBox::AddPoint
130 //------------------------------------------------------------------------------
132 * @fn SkyMinMaxBox::AddPoint( const Vec3f &pt )
133 * @brief Adds a point and adjusts bounds if necessary.
135 void SkyMinMaxBox::AddPoint( const Vec3f &pt )
152 // update the center and radius
157 //------------------------------------------------------------------------------
158 // Function : SkyMinMaxBox::ViewFrustumCull
160 //------------------------------------------------------------------------------
162 * @fn SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
163 * @brief Returns true if bounding volume culled against cam.
165 * This function must transform the object space min and max then adjust the new
166 * min and max box by expanding it. Each of the 8 points must be tested. This
167 * is faster then doing an xform of all the geometry points and finding a tight
168 * fitting min max box, however this will be enlarged.
170 bool SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
172 SkyMinMaxBox xBV; // Xformed Bounding Volume
173 Vec3f xMin = mat * _min; // Xformed _min
174 Vec3f xMax = mat * _max; // Xformed _max
175 Vec3f offset = _max - _min; // Offset for sides of MinMaxBox
178 xBV.Clear(); // Clear the values first
180 // First find the new minimum x,y,z
182 tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
188 tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
194 tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
199 // Second find the new maximum x,y,z
201 tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
207 tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
213 tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
218 // Use the camera utility function that already exists for minmax boxes
219 return VFC(&cam, xBV.GetMin(), xBV.GetMax());
223 //------------------------------------------------------------------------------
224 // Function : SkyMinMaxBox::Transform
226 //------------------------------------------------------------------------------
228 * @fn SkyMinMaxBox::Transform(const Mat44f& mat)
229 * @brief @todo <WRITE BRIEF SkyMinMaxBox::Transform DOCUMENTATION>
231 * @todo <WRITE EXTENDED SkyMinMaxBox::Transform FUNCTION DOCUMENTATION>
233 void SkyMinMaxBox::Transform(const Mat44f& mat)
238 for (int i = 0; i < 8; ++i)
240 AddPoint(mat * verts[i]);
244 //------------------------------------------------------------------------------
245 // Function : SkyMinMaxBox::_UpdateSphere
247 //------------------------------------------------------------------------------
249 * @fn SkyMinMaxBox::_UpdateSphere()
250 * @brief Updates the bounding sphere based on min and max.
252 void SkyMinMaxBox::_UpdateSphere()
260 _rRadius = rad.Length();
265 //------------------------------------------------------------------------------
266 // Function : SkyMinMaxBox::Display
268 //------------------------------------------------------------------------------
270 * @fn SkyMinMaxBox::Display() const
271 * @brief @todo <WRITE BRIEF SkyMinMaxBox::Display DOCUMENTATION>
273 * @todo <WRITE EXTENDED SkyMinMaxBox::Display FUNCTION DOCUMENTATION>
275 void SkyMinMaxBox::Display() const
280 glPushAttrib(GL_LINE_BIT);
283 glBegin(GL_LINE_LOOP); // TOP FACE
284 glVertex3fv(V[4]); glVertex3fv(V[5]); glVertex3fv(V[1]); glVertex3fv(V[0]);
286 glBegin(GL_LINE_LOOP); // BOTTOM FACE
287 glVertex3fv(V[3]); glVertex3fv(V[2]); glVertex3fv(V[6]); glVertex3fv(V[7]);
289 glBegin(GL_LINE_LOOP); // LEFT FACE
290 glVertex3fv(V[1]); glVertex3fv(V[5]); glVertex3fv(V[6]); glVertex3fv(V[2]);
292 glBegin(GL_LINE_LOOP); // RIGHT FACE
293 glVertex3fv(V[0]); glVertex3fv(V[3]); glVertex3fv(V[7]); glVertex3fv(V[4]);
295 glBegin(GL_LINE_LOOP); // NEAR FACE
296 glVertex3fv(V[1]); glVertex3fv(V[2]); glVertex3fv(V[3]); glVertex3fv(V[0]);
298 glBegin(GL_LINE_LOOP); // FAR FACE
299 glVertex3fv(V[4]); glVertex3fv(V[7]); glVertex3fv(V[6]); glVertex3fv(V[5]);
305 //-----------------------------------------------------------------------------
306 // Calculates the eight corner vertices of the MinMaxBox.
307 // V must be prealloced.
310 // 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
311 // | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
314 //-----------------------------------------------------------------------------
316 //------------------------------------------------------------------------------
317 // Function : SkyMinMaxBox::_CalcVerts
319 //------------------------------------------------------------------------------
321 * @fn SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
322 * @brief @todo <WRITE BRIEF SkyMinMaxBox::_CalcVerts DOCUMENTATION>
324 * @todo <WRITE EXTENDED SkyMinMaxBox::_CalcVerts FUNCTION DOCUMENTATION>
326 void SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
328 pVerts[0].Set(_max); pVerts[4].Set(_max.x, _max.y, _min.z);
329 pVerts[1].Set(_min.x, _max.y, _max.z); pVerts[5].Set(_min.x, _max.y, _min.z);
330 pVerts[2].Set(_min.x, _min.y, _max.z); pVerts[6].Set(_min);
331 pVerts[3].Set(_max.x, _min.y, _max.z); pVerts[7].Set(_max.x, _min.y, _min.z);