source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h @ 2802

Revision 2802, 11.6 KB checked in by mattausch, 16 years ago (diff)

worked on renderqueue

Line 
1#ifndef _AxisAlignedBox3_H__
2#define _AxisAlignedBox3_H__
3
4
5#include "Matrix4x4.h"
6#include "Vector3.h"
7
8
9namespace CHCDemoEngine
10{
11
12struct Triangle3;
13class Plane3;
14
15/** Axis alignedd box class.
16    This is a box in 3-space, defined by min and max
17        corner vectors.  Many useful operations are defined.
18*/
19class AxisAlignedBox3
20{
21
22public:
23
24        ///////////
25        //-- Constructors.
26
27        AxisAlignedBox3();
28
29        AxisAlignedBox3(const Vector3 &nMin, const Vector3 &nMax);
30        /** initialization to the non existing bounding box
31        */
32        void Initialize();
33        /** The center of the box
34        */
35        Vector3 Center() const;
36        /** The diagonal of the box
37        */
38        Vector3 Diagonal() const;
39
40        float Center(const int axis) const;
41
42        float Min(const int axis) const;
43
44        float Max(const int axis) const;
45
46        float Size(const int axis) const;
47
48        // Read-only const access tomMin and max vectors using references
49        const Vector3& Min() const;
50        const Vector3& Max() const;
51
52        void Enlarge(const Vector3 &v);
53
54        void EnlargeToMinSize();
55
56        void SetMin(const Vector3 &v);
57
58        void SetMax(const Vector3 &v);
59
60        void SetMin(int axis, const float value);
61
62        void SetMax(int axis, const float value);
63        /** Decrease box by given splitting plane
64        */
65        void Reduce(int axis, int right, float value);
66
67        bool Intersects(const Vector3 &lStart, const Vector3 &lEnd) const;
68
69        // the size of the box along all the axes
70        Vector3 Size() const;
71        float Radius() const { return 0.5f * Magnitude(Size()); }
72        float SqrRadius() const { return 0.5f * SqrMagnitude(Size()); }
73
74        // Return whether the box is unbounded.  Unbounded boxes appear
75        // when unbounded objects such as quadric surfaces are included.
76        bool Unbounded() const;
77
78        // Expand the axis-aligned box to include the given object.
79        void Include(const Vector3 &newpt);
80        void Include(const AxisAlignedBox3 &bbox);
81        /** Expand the axis-aligned box to include given values in particular axis.
82        */
83        void Include(const int &axis, const float &newBound);
84        /** Includes returns true if a includes b (completely)
85        */
86        bool Includes(const AxisAlignedBox3 &b) const;
87        /** Returns true if this point is inside box.
88        */
89        virtual int IsInside(const Vector3 &v) const;
90        /** Test if the box makes sense.
91        */
92        virtual bool IsCorrect();
93        /** To answer true requires the box of real volume of non-zero value.
94        */
95        bool IsSingularOrIncorrect() const;
96        /** When the box is not of non-zero or negative surface area.
97        */
98        bool IsCorrectAndNotPoint() const;
99        /** Returns true when the box degenerates to a point.
100        */
101        bool IsPoint() const;
102        /** Scales the box with the factor.
103        */
104        void Scale(float scale);
105
106        void Scale(const Vector3 &scale);
107        /** Translates the box with the factor.
108        */
109        void Translate(const Vector3 &shift);
110        /** Returns the square of the minimal and maximal distance to
111            a point on the box.
112        */
113        void GetSqrDistances(const Vector3 &point,
114                                 float &minDistance,
115                                                 float &maxDistance) const;
116        /** return random point in box.
117        */
118        Vector3 GetRandomPoint() const;
119        /** Returns surface area of the box.
120        */
121        float SurfaceArea() const;
122        /** Returns volume of the box.
123        */
124        float GetVolume() const;
125
126        // Six faces are distuinguished by their name.
127        enum EFaces {ID_Back = 0,
128                ID_Left = 1,
129                ID_Bottom = 2,
130                ID_Front = 3,
131                ID_Right = 4,
132                ID_Top = 5};
133
134        // Writes a brief description of the object, indenting by the given
135        // number of spaces first.
136        virtual void Describe(std::ostream& app, int ind) const;
137
138        // For edge .. number <0..11> returns two incident vertices
139        void GetEdge(int edge, Vector3 *a, Vector3 *b) const;
140
141        // Compute the coordinates of one vertex of the box for 0/1 in each axis
142        // 0 .. smaller coordinates, 1 .. large coordinates
143        Vector3 GetVertex(int xAxis, int yAxis, int zAxis) const;
144
145        // Compute the vertex for number N=<0..7>, N = 4*x + 2*y + z, where
146        // x,y,z are either 0 or 1; (0 .. lower coordinate, 1 .. large coordinate)
147        // (xmin,ymin, zmin) .. N = 0, (xmax, ymax, zmax) .. N= 7
148        void GetVertex(int N, Vector3 &vertex) const;
149
150        Vector3 GetVertex(int N) const;
151        /** get the extent of face.
152        */
153        float GetExtent(int face) const;
154        /** Returns 1, if the box includes on arbitrary face a given box
155        */
156        int IsPiercedByBox(const AxisAlignedBox3 &box, int &axis) const;
157
158        int GetFaceVisibilityMask(const Vector3 &position) const;
159        /** Returns vertex indices of edge.
160        */
161        void GetEdge(int edge, int  &aIdx, int &bIdx) const;
162        /** Get distance of plane to vertex with specified index.
163        */
164        float GetDistance(int index, const Plane3 &plane) const;
165        /** Returns the distance between the plane given by 'vecNearplaneNormal' and the vertex that
166            is closest to it (this vertex is unequivocally identified by the direction of the vector)
167        */
168        float GetMinVisibleDistance(const Plane3 &near) const;
169
170
171        ////////////
172        //-- friend functions
173
174        /// Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly
175        friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &);
176
177        /// Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly
178        friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &);
179
180        /** Overlap returns 1 if the two axis-aligned boxes overlap for a given
181        epsilon. If eps > 0.0, then the boxes has to have the real intersection
182        box, if eps < 0.0, then the boxes need not intersect really, they
183        can be at eps distance in the projection.
184        */
185        friend inline bool Overlap(const AxisAlignedBox3 &,     const AxisAlignedBox3 &, float eps);
186
187
188        // Returns the smallest axis-aligned box that includes all points
189        // inside the two given boxes.
190        friend inline AxisAlignedBox3 Union(const AxisAlignedBox3 &x,
191                                                const AxisAlignedBox3 &y);
192
193        // Returns the intersection of two axis-aligned boxes.
194        friend inline AxisAlignedBox3 Intersect(const AxisAlignedBox3 &x,
195                                                    const AxisAlignedBox3 &y);
196
197        // Given 4x4 matrix, transform the current box to new one.
198        friend inline AxisAlignedBox3 Transform(const AxisAlignedBox3 &box,
199                                                    const Matrix4x4 &tform);
200
201
202        // returns true when two boxes are completely equal
203        friend inline int operator== (const AxisAlignedBox3 &A,
204                                          const AxisAlignedBox3 &B);
205
206        // input and output operator with stream
207        friend std::ostream& operator<<(std::ostream &s, const AxisAlignedBox3 &A);
208        friend std::istream& operator>>(std::istream &s, AxisAlignedBox3 &A);
209
210
211
212        // The vertices that form boundaries of the projected bounding box
213        // for all the regions possible, number of regions is 3^3 = 27,
214        // since two parallel sides of bbox forms three disjoint spaces
215        // the vertices are given in anti-clockwise order .. stopped by -1 elem.
216        static const int bvertices[27][9];
217
218        // The list of all faces visible from a given region (except region 13)
219        // the faces are identified by triple: (axis, min-vertex, max-vertex),
220        // that is maximaly three triples are defined. axis = 0 (x-axis),
221        // axis = 1 (y-axis), axis = 2 (z-axis), -1 .. terminator. Is is always
222        // true that: min-vertex < max-vertex for all coordinates excluding axis
223        static const int bfaces[27][10];
224
225        // The correct corners indexed starting from entry face to exit face
226        // first index determines entry face, second index exit face, and
227        // the two numbers (indx, inc) determines: ind = the index on the exit
228        // face, when starting from the vertex 0 on entry face, 'inc' is
229        // the increment when we go on entry face in order 0,1,2,3 to create
230        // convex shaft with the rectangle on exit face. That is, inc = -1 or 1.
231        static const int pairFaceRects[6][6][2];
232
233        // The vertices that form CLOSEST points with respect to the region
234        // for all the regions possible, number of regions is 3^3 = 27,
235        // since two parallel sides of bbox forms three disjoint spaces.
236        // The vertices are given in anti-clockwise order, stopped by -1 elem,
237        // at most 8 points, at least 1 point.
238        static const int cvertices[27][9];
239        static const int csvertices[27][6];
240
241        // The vertices that form FARTHEST points with respect to the region
242        // for all the regions possible, number of regions is 3^3 = 27,
243        // since two parallel sides of bbox forms three disjoint spaces.
244        // The vertices are given in anti-clockwise order, stopped by -1 elem,
245        // at most 8 points, at least 1 point.
246        static const int fvertices[27][9]; 
247        static const int fsvertices[27][9];
248
249        /** Returns the vertex index nearest from the plane specified by the normal.
250        */
251        static int GetIndexNearestVertex(const Vector3 &vecPlaneNormal);
252        /** Returns the vertwx index farthest from the plane specified by the normal.
253        */
254        static int GetIndexFarthestVertex(const Vector3 &vecPlaneNormal);
255
256
257
258protected:
259
260        Vector3 mMin, mMax;
261};
262
263
264// --------------------------------------------------------------------------
265// Implementation of inline (member) functions
266
267inline bool
268Overlap(const AxisAlignedBox3 &x, const AxisAlignedBox3 &y)
269{
270        if (x.mMax.x < y.mMin.x ||
271                x.mMin.x > y.mMax.x ||
272                x.mMax.y < y.mMin.y ||
273                x.mMin.y > y.mMax.y ||
274                x.mMax.z < y.mMin.z ||
275                x.mMin.z > y.mMax.z) {
276                        return false;
277        }
278        return true;
279}
280
281inline bool
282OverlapS(const AxisAlignedBox3 &x, const AxisAlignedBox3 &y)
283{
284        if (x.mMax.x <= y.mMin.x ||
285                x.mMin.x >= y.mMax.x ||
286                x.mMax.y <= y.mMin.y ||
287                x.mMin.y >= y.mMax.y ||
288                x.mMax.z <= y.mMin.z ||
289                x.mMin.z >= y.mMax.z) {
290                        return false;
291        }
292        return true;
293}
294
295inline bool
296Overlap(const AxisAlignedBox3 &x, const AxisAlignedBox3 &y, float eps)
297{
298        if ( (x.mMax.x - eps) < y.mMin.x ||
299                (x.mMin.x + eps) > y.mMax.x ||
300                (x.mMax.y - eps) < y.mMin.y ||
301                (x.mMin.y + eps) > y.mMax.y ||
302                (x.mMax.z - eps) < y.mMin.z ||
303                (x.mMin.z + eps) > y.mMax.z ) {
304                        return false;
305        }
306        return true;
307}
308
309inline AxisAlignedBox3
310Intersect(const AxisAlignedBox3 &x, const AxisAlignedBox3 &y)
311{
312        if (x.Unbounded())
313                return y;
314        else
315                if (y.Unbounded())
316                        return x;
317        AxisAlignedBox3 ret = x;
318        if (Overlap(ret, y)) {
319                Maximize(ret.mMin, y.mMin);
320                Minimize(ret.mMax, y.mMax);
321                return ret;
322        }
323        else      // Null intersection.
324                return AxisAlignedBox3(Vector3(0), Vector3(0));
325        // return AxisAlignedBox3(Vector3(0), Vector3(-1));
326}
327
328inline AxisAlignedBox3
329Union(const AxisAlignedBox3 &x, const AxisAlignedBox3 &y)
330{
331        Vector3 min = x.mMin;
332        Vector3 max = x.mMax;
333        Minimize(min, y.mMin);
334        Maximize(max, y.mMax);
335        return AxisAlignedBox3(min, max);
336}
337
338inline AxisAlignedBox3
339Transform(const AxisAlignedBox3 &box, const Matrix4x4 &tform)
340{
341        Vector3 mmin(MAXFLOAT);
342        Vector3 mmax(-MAXFLOAT);
343       
344        AxisAlignedBox3 ret(mmin, mmax);
345       
346        ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMin.z));
347        ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMax.z));
348        ret.Include(tform * Vector3(box.mMin.x, box.mMax.y, box.mMin.z));
349        ret.Include(tform * Vector3(box.mMin.x, box.mMax.y, box.mMax.z));
350        ret.Include(tform * Vector3(box.mMax.x, box.mMin.y, box.mMin.z));
351        ret.Include(tform * Vector3(box.mMax.x, box.mMin.y, box.mMax.z));
352        ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMin.z));
353        ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMax.z));
354       
355        return ret;
356}
357
358inline float RatioOfOverlap(const AxisAlignedBox3 &box1, const AxisAlignedBox3 &box2)
359{
360        // return ratio of intersection to union
361        const AxisAlignedBox3 bisect = Intersect(box1, box2);
362        const AxisAlignedBox3 bunion = Union(box1, box2);
363
364        return bisect.GetVolume() / bunion.GetVolume();
365}
366
367inline int operator==(const AxisAlignedBox3 &A, const AxisAlignedBox3 &B)
368{
369        return (A.mMin == B.mMin) && (A.mMax == B.mMax);
370}
371
372
373}
374
375
376#endif
Note: See TracBrowser for help on using the repository browser.