root/OpenSceneGraph/trunk/include/osg/BoundingBox @ 13041

Revision 13041, 8.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_BOUNDINGBOX
15#define OSG_BOUNDINGBOX 1
16
17#include <osg/Config>
18#include <osg/Export>
19#include <osg/Vec3>
20#include <osg/Vec3d>
21#include <float.h>
22
23namespace osg {
24
25template<typename VT>
26class BoundingSphereImpl;
27
28/** General purpose axis-aligned bounding box class for enclosing objects/vertices.
29  * Bounds leaf objects in a scene such as osg::Drawable objects. Used for frustum
30  * culling etc.
31*/
32template<typename VT>
33class BoundingBoxImpl
34{
35    public:
36        typedef VT vec_type;
37        typedef typename VT::value_type value_type;
38
39        /** Minimum extent. (Smallest X, Y, and Z values of all coordinates.) */
40        vec_type _min;
41        /** Maximum extent. (Greatest X, Y, and Z values of all coordinates.) */
42        vec_type _max;
43
44        /** Creates an uninitialized bounding box. */
45        inline BoundingBoxImpl() :
46            _min(FLT_MAX,
47                 FLT_MAX,
48                 FLT_MAX),
49            _max(-FLT_MAX,
50                 -FLT_MAX,
51                 -FLT_MAX)
52        {}
53
54        /** Creates a bounding box initialized to the given extents. */
55        inline BoundingBoxImpl(value_type xmin, value_type ymin, value_type zmin,
56                           value_type xmax, value_type ymax, value_type zmax) :
57                           _min(xmin,ymin,zmin),
58                           _max(xmax,ymax,zmax) {}
59
60        /** Creates a bounding box initialized to the given extents. */
61        inline BoundingBoxImpl(const vec_type& min,const vec_type& max) :
62                    _min(min),
63                    _max(max) {}
64
65        /** Clear the bounding box. Erases existing minimum and maximum extents. */
66        inline void init()
67        {
68            _min.set(FLT_MAX,
69                     FLT_MAX,
70                     FLT_MAX);
71            _max.set(-FLT_MAX,
72                     -FLT_MAX,
73                     -FLT_MAX);
74        }
75
76        /** Returns true if the bounding box extents are valid, false otherwise. */
77        inline bool valid() const
78        {
79            return _max.x()>=_min.x() &&  _max.y()>=_min.y() &&  _max.z()>=_min.z();
80        }
81
82        /** Sets the bounding box extents. */
83        inline void set (value_type xmin, value_type ymin, value_type zmin,
84                         value_type xmax, value_type ymax, value_type zmax)
85        {
86            _min.set(xmin,ymin,zmin);
87            _max.set(xmax,ymax,zmax);
88        }
89
90        /** Sets the bounding box extents. */
91        inline void set(const vec_type& min,const vec_type& max)
92        {
93            _min = min;
94            _max = max;
95        }
96
97
98        inline value_type& xMin() { return _min.x(); }
99        inline value_type xMin() const { return _min.x(); }
100
101        inline value_type& yMin() { return _min.y(); }
102        inline value_type yMin() const { return _min.y(); }
103
104        inline value_type& zMin() { return _min.z(); }
105        inline value_type zMin() const { return _min.z(); }
106
107        inline value_type& xMax() { return _max.x(); }
108        inline value_type xMax() const { return _max.x(); }
109
110        inline value_type& yMax() { return _max.y(); }
111        inline value_type yMax() const { return _max.y(); }
112
113        inline value_type& zMax() { return _max.z(); }
114        inline value_type zMax() const { return _max.z(); }
115
116        /** Calculates and returns the bounding box center. */
117        inline const vec_type center() const
118        {
119            return (_min+_max)*0.5;
120        }
121
122        /** Calculates and returns the bounding box radius. */
123        inline value_type radius() const
124        {
125            return sqrt(radius2());
126        }
127
128        /** Calculates and returns the squared length of the bounding box radius.
129          * Note, radius2() is faster to calculate than radius(). */
130        inline value_type radius2() const
131        {
132            return 0.25*((_max-_min).length2());
133        }
134
135        /** Returns a specific corner of the bounding box.
136          * pos specifies the corner as a number between 0 and 7.
137          * Each bit selects an axis, X, Y, or Z from least- to
138          * most-significant. Unset bits select the minimum value
139          * for that axis, and set bits select the maximum. */
140        inline const vec_type corner(unsigned int pos) const
141        {
142            return vec_type(pos&1?_max.x():_min.x(),pos&2?_max.y():_min.y(),pos&4?_max.z():_min.z());
143        }
144
145        /** Expands the bounding box to include the given coordinate.
146          * If the box is uninitialized, set its min and max extents to v. */
147        inline void expandBy(const vec_type& v)
148        {
149            if(v.x()<_min.x()) _min.x() = v.x();
150            if(v.x()>_max.x()) _max.x() = v.x();
151
152            if(v.y()<_min.y()) _min.y() = v.y();
153            if(v.y()>_max.y()) _max.y() = v.y();
154
155            if(v.z()<_min.z()) _min.z() = v.z();
156            if(v.z()>_max.z()) _max.z() = v.z();
157        }
158
159        /** Expands the bounding box to include the given coordinate.
160          * If the box is uninitialized, set its min and max extents to
161          * Vec3(x,y,z). */
162        inline void expandBy(value_type x,value_type y,value_type z)
163        {
164            if(x<_min.x()) _min.x() = x;
165            if(x>_max.x()) _max.x() = x;
166
167            if(y<_min.y()) _min.y() = y;
168            if(y>_max.y()) _max.y() = y;
169
170            if(z<_min.z()) _min.z() = z;
171            if(z>_max.z()) _max.z() = z;
172        }
173
174        /** Expands this bounding box to include the given bounding box.
175          * If this box is uninitialized, set it equal to bb. */
176        void expandBy(const BoundingBoxImpl& bb)
177        {
178            if (!bb.valid()) return;
179
180            if(bb._min.x()<_min.x()) _min.x() = bb._min.x();
181            if(bb._max.x()>_max.x()) _max.x() = bb._max.x();
182
183            if(bb._min.y()<_min.y()) _min.y() = bb._min.y();
184            if(bb._max.y()>_max.y()) _max.y() = bb._max.y();
185
186            if(bb._min.z()<_min.z()) _min.z() = bb._min.z();
187            if(bb._max.z()>_max.z()) _max.z() = bb._max.z();
188        }
189
190        /** Expands this bounding box to include the given sphere.
191          * If this box is uninitialized, set it to include sh. */
192        void expandBy(const BoundingSphereImpl<VT>& sh)
193        {
194            if (!sh.valid()) return;
195
196            if(sh._center.x()-sh._radius<_min.x()) _min.x() = sh._center.x()-sh._radius;
197            if(sh._center.x()+sh._radius>_max.x()) _max.x() = sh._center.x()+sh._radius;
198
199            if(sh._center.y()-sh._radius<_min.y()) _min.y() = sh._center.y()-sh._radius;
200            if(sh._center.y()+sh._radius>_max.y()) _max.y() = sh._center.y()+sh._radius;
201
202            if(sh._center.z()-sh._radius<_min.z()) _min.z() = sh._center.z()-sh._radius;
203            if(sh._center.z()+sh._radius>_max.z()) _max.z() = sh._center.z()+sh._radius;
204        }
205
206
207        /** Returns the intersection of this bounding box and the specified bounding box. */
208        BoundingBoxImpl intersect(const BoundingBoxImpl& bb) const
209        {    return BoundingBoxImpl(osg::maximum(xMin(),bb.xMin()),osg::maximum(yMin(),bb.yMin()),osg::maximum(zMin(),bb.zMin()),
210                                     osg::minimum(xMax(),bb.xMax()),osg::minimum(yMax(),bb.yMax()),osg::minimum(zMax(),bb.zMax()));
211
212        }
213
214        /** Return true if this bounding box intersects the specified bounding box. */
215        bool intersects(const BoundingBoxImpl& bb) const
216        {    return osg::maximum(xMin(),bb.xMin()) <= osg::minimum(xMax(),bb.xMax()) &&
217                    osg::maximum(yMin(),bb.yMin()) <= osg::minimum(yMax(),bb.yMax()) &&
218                    osg::maximum(zMin(),bb.zMin()) <= osg::minimum(zMax(),bb.zMax());
219
220        }
221
222        /** Returns true if this bounding box contains the specified coordinate. */
223        inline bool contains(const vec_type& v) const
224        {
225            return valid() &&
226                   (v.x()>=_min.x() && v.x()<=_max.x()) &&
227                   (v.y()>=_min.y() && v.y()<=_max.y()) &&
228                   (v.z()>=_min.z() && v.z()<=_max.z());
229        }
230};
231
232typedef BoundingBoxImpl<Vec3f> BoundingBoxf;
233typedef BoundingBoxImpl<Vec3d> BoundingBoxd;
234
235#ifdef OSG_USE_FLOAT_BOUNDINGBOX
236typedef BoundingBoxf BoundingBox;
237#else
238typedef BoundingBoxd BoundingBox;
239#endif
240
241}
242
243#endif
Note: See TracBrowser for help on using the browser.