]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/SkyMinMaxBox.cpp
Tweak lib name.
[simgear.git] / simgear / scene / sky / clouds3d / SkyMinMaxBox.cpp
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 
12 // restrictions. 
13 //
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 
17 // implied warranty.
18 /**
19  * @file SkyMinMaxBox.cpp
20  * 
21  * Implementation of a bounding box class.  Modified from Wes Hunt's BoundingBox.
22  */
23 #include "SkyMinMaxBox.hpp"
24 #include "camutils.hpp"
25 #include <GL/glut.h>
26 #include <float.h>
27
28
29 //------------------------------------------------------------------------------
30 // Function               : SkyMinMaxBox::SkyMinMaxBox
31 // Description      : 
32 //------------------------------------------------------------------------------
33 /**
34  * @fn SkyMinMaxBox::SkyMinMaxBox()
35  * @brief Constructor
36  */ 
37 SkyMinMaxBox::SkyMinMaxBox()
38 {
39   Clear();
40 }
41
42
43 //------------------------------------------------------------------------------
44 // Function               : SkyMinMaxBox::Clear
45 // Description      : 
46 //------------------------------------------------------------------------------
47 /**
48  * @fn SkyMinMaxBox::Clear()
49  * @brief Reset the min and max to floating point extremes.
50  * 
51  */ 
52 void SkyMinMaxBox::Clear()
53 {
54         _min.x =  FLT_MAX;
55         _min.y =  FLT_MAX;
56         _min.z =  FLT_MAX;
57         _max.x = -FLT_MAX;
58         _max.y = -FLT_MAX;
59         _max.z = -FLT_MAX;
60 }
61
62
63 //------------------------------------------------------------------------------
64 // Function               : SkyMinMaxBox::PointInBBox
65 // Description      : 
66 //------------------------------------------------------------------------------
67 /**
68  * @fn SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
69  * @brief Queries pt to see if it is inside the SkyMinMaxBox.
70  * 
71  */ 
72 bool SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
73 {
74         if( (pt.x >= _min.x) && ( pt.x <= _max.x ) )
75         {
76                 if( (pt.y >= _min.y) && ( pt.y <= _max.y ) )
77                 {
78                         if( (pt.z >= _min.z) && ( pt.z <= _max.z ) )
79                                 return true;
80                 }
81         }
82
83         return false;
84 }
85
86
87 //------------------------------------------------------------------------------
88 // Function               : SkyMinMaxBox::AddPoint
89 // Description      : 
90 //------------------------------------------------------------------------------
91 /**
92  * @fn SkyMinMaxBox::AddPoint( float x , float y , float z )
93  * @brief Adds a point and adjusts bounds if necessary.             
94  */ 
95 void SkyMinMaxBox::AddPoint( float x , float y , float z )
96 {
97         if( x > _max.x )
98                 _max.x = x;
99         if( x < _min.x )
100                 _min.x = x;
101         
102         if( y > _max.y )
103                 _max.y = y;
104         if( y < _min.y )
105                 _min.y = y;
106
107         if( z > _max.z )
108                 _max.z = z;
109         if( z < _min.z )
110                 _min.z = z;
111
112   // update the center and radius
113   _UpdateSphere();
114 }
115
116
117 //------------------------------------------------------------------------------
118 // Function               : SkyMinMaxBox::AddPoint
119 // Description      : 
120 //------------------------------------------------------------------------------
121 /**
122  * @fn SkyMinMaxBox::AddPoint( const Vec3f &pt )
123  * @brief Adds a point and adjusts bounds if necessary.             
124  */ 
125 void SkyMinMaxBox::AddPoint( const Vec3f &pt )
126 {
127         if( pt.x > _max.x )
128                 _max.x = pt.x;
129         if( pt.x < _min.x )
130                 _min.x = pt.x;
131         
132         if( pt.y > _max.y )
133                 _max.y = pt.y;
134         if( pt.y < _min.y )
135                 _min.y = pt.y;
136
137         if( pt.z > _max.z )
138                 _max.z = pt.z;
139         if( pt.z < _min.z )
140                 _min.z = pt.z;
141
142   // update the center and radius
143   _UpdateSphere();
144 }
145
146
147 //------------------------------------------------------------------------------
148 // Function               : SkyMinMaxBox::ViewFrustumCull
149 // Description      : 
150 //------------------------------------------------------------------------------
151 /**
152  * @fn SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
153  * @brief Returns true if bounding volume culled against cam.
154  * 
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.
159  */ 
160 bool SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
161 {
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
166   Vec3f tmp;
167
168   xBV.Clear(); // Clear the values first
169
170   // First find the new minimum x,y,z
171   // Find min + x
172   tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
173   tmp *= offset.x;
174   tmp += xMin;
175   xBV.AddPoint(tmp);
176
177   // Find min + y
178   tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
179   tmp *= offset.y;
180   tmp += xMin;
181   xBV.AddPoint(tmp);
182
183   // Find min + z
184   tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
185   tmp *= offset.z;
186   tmp += xMin;
187   xBV.AddPoint(tmp);
188   
189   // Second find the new maximum x,y,z
190   // Find max - x
191   tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
192   tmp *= -offset.x;
193   tmp += xMax;
194   xBV.AddPoint(tmp);
195   
196   // Find max - y
197   tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
198   tmp *= -offset.y;
199   tmp += xMax;
200   xBV.AddPoint(tmp);
201   
202   // Find max - z
203   tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
204   tmp *= -offset.z;
205   tmp += xMax;
206   xBV.AddPoint(tmp);
207   
208   // Use the camera utility function that already exists for minmax boxes
209   return VFC(&cam, xBV.GetMin(), xBV.GetMax());
210 }
211
212
213 //------------------------------------------------------------------------------
214 // Function               : SkyMinMaxBox::Transform
215 // Description      : 
216 //------------------------------------------------------------------------------
217 /**
218  * @fn SkyMinMaxBox::Transform(const Mat44f& mat)
219  * @brief @todo <WRITE BRIEF SkyMinMaxBox::Transform DOCUMENTATION>
220  * 
221  * @todo <WRITE EXTENDED SkyMinMaxBox::Transform FUNCTION DOCUMENTATION>
222  */ 
223 void SkyMinMaxBox::Transform(const Mat44f& mat)
224 {
225   Vec3f verts[8];
226   _CalcVerts(verts);
227   Clear();
228   for (int i = 0; i < 8; ++i)
229   {
230     AddPoint(mat * verts[i]);
231   }
232 }
233
234 //------------------------------------------------------------------------------
235 // Function               : SkyMinMaxBox::_UpdateSphere
236 // Description      : 
237 //------------------------------------------------------------------------------
238 /**
239 * @fn SkyMinMaxBox::_UpdateSphere()
240 * @brief Updates the bounding sphere based on min and max.
241 */ 
242 void SkyMinMaxBox::_UpdateSphere()
243 {
244   _vecCenter =  _min;
245   _vecCenter += _max;
246   _vecCenter *= 0.5f;
247   
248   Vec3f rad  =  _max;
249   rad        -= _vecCenter;
250   _rRadius   =  rad.Length();
251 }
252
253
254
255 //------------------------------------------------------------------------------
256 // Function               : SkyMinMaxBox::Display
257 // Description      : 
258 //------------------------------------------------------------------------------
259 /**
260  * @fn SkyMinMaxBox::Display() const
261  * @brief @todo <WRITE BRIEF SkyMinMaxBox::Display DOCUMENTATION>
262  * 
263  * @todo <WRITE EXTENDED SkyMinMaxBox::Display FUNCTION DOCUMENTATION>
264  */ 
265 void SkyMinMaxBox::Display() const
266 {
267   Vec3f V[8];
268   _CalcVerts(V);
269   
270   glPushAttrib(GL_LINE_BIT);
271   glLineWidth(1.0);
272   
273   glBegin(GL_LINE_LOOP);  // TOP FACE
274   glVertex3fv(V[4]); glVertex3fv(V[5]); glVertex3fv(V[1]); glVertex3fv(V[0]);
275   glEnd();
276   glBegin(GL_LINE_LOOP);  // BOTTOM FACE
277   glVertex3fv(V[3]); glVertex3fv(V[2]); glVertex3fv(V[6]); glVertex3fv(V[7]); 
278   glEnd();
279   glBegin(GL_LINE_LOOP);  // LEFT FACE
280   glVertex3fv(V[1]); glVertex3fv(V[5]); glVertex3fv(V[6]); glVertex3fv(V[2]); 
281   glEnd();
282   glBegin(GL_LINE_LOOP);  // RIGHT FACE
283   glVertex3fv(V[0]); glVertex3fv(V[3]); glVertex3fv(V[7]); glVertex3fv(V[4]); 
284   glEnd();
285   glBegin(GL_LINE_LOOP);  // NEAR FACE
286   glVertex3fv(V[1]); glVertex3fv(V[2]); glVertex3fv(V[3]); glVertex3fv(V[0]); 
287   glEnd();
288   glBegin(GL_LINE_LOOP);  // FAR FACE
289   glVertex3fv(V[4]); glVertex3fv(V[7]); glVertex3fv(V[6]); glVertex3fv(V[5]); 
290   glEnd();
291   
292   glPopAttrib();
293 }
294
295 //-----------------------------------------------------------------------------
296 // Calculates the eight corner vertices of the MinMaxBox.
297 // V must be prealloced.
298 //       5---4
299 //      /   /|
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)
302 //     |   |/
303 //     2---3
304 //-----------------------------------------------------------------------------
305
306 //------------------------------------------------------------------------------
307 // Function               : SkyMinMaxBox::_CalcVerts
308 // Description      : 
309 //------------------------------------------------------------------------------
310 /**
311  * @fn SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
312  * @brief @todo <WRITE BRIEF SkyMinMaxBox::_CalcVerts DOCUMENTATION>
313  * 
314  * @todo <WRITE EXTENDED SkyMinMaxBox::_CalcVerts FUNCTION DOCUMENTATION>
315  */ 
316 void SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
317 {
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);
322 }