2002-07-17 04:07:32 +08:00
|
|
|
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
2001-10-04 23:12:57 +08:00
|
|
|
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
|
|
|
//as published by the Free Software Foundation.
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_BOUNDINGBOX
|
|
|
|
#define OSG_BOUNDINGBOX 1
|
|
|
|
|
|
|
|
#include <osg/Export>
|
|
|
|
#include <osg/Vec3>
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
|
|
|
class BoundingSphere;
|
|
|
|
|
|
|
|
/** General purpose axis-aligned bounding box class for enclosing objects/vertices.
|
|
|
|
Used to bounding the leaf objects in the scene,
|
2002-06-26 04:27:51 +08:00
|
|
|
i.e. osg::Drawable's to assist in view frustum culling etc.
|
2001-01-11 00:32:10 +08:00
|
|
|
*/
|
|
|
|
class SG_EXPORT BoundingBox
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/** The corner with the smallest values for each coordinate of the
|
|
|
|
bounding box.*/
|
|
|
|
Vec3 _min;
|
|
|
|
/** The corner with the largest values for each coordinate of the
|
|
|
|
bounding box.*/
|
|
|
|
Vec3 _max;
|
|
|
|
|
|
|
|
/** construct to invalid values to represent an unset bounding box.*/
|
2001-11-06 18:34:51 +08:00
|
|
|
inline BoundingBox() : _min(FLT_MAX,FLT_MAX,FLT_MAX),
|
2001-01-11 00:32:10 +08:00
|
|
|
_max(-FLT_MAX,-FLT_MAX,-FLT_MAX) {}
|
|
|
|
|
2001-11-06 18:34:51 +08:00
|
|
|
/** construct to with specified min and max values.*/
|
|
|
|
inline BoundingBox(float xmin,float ymin,float zmin,
|
|
|
|
float xmax,float ymax,float zmax) :
|
|
|
|
_min(xmin,ymin,zmin),
|
|
|
|
_max(xmax,ymax,zmax) {}
|
|
|
|
|
|
|
|
/** construct to with specified min and max values.*/
|
|
|
|
inline BoundingBox(const Vec3& min,const Vec3& max) :
|
|
|
|
_min(min),
|
|
|
|
_max(max) {}
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** initialize to invalid values to represent an unset bounding box.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline void init()
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
_min.set(FLT_MAX,FLT_MAX,FLT_MAX);
|
|
|
|
_max.set(-FLT_MAX,-FLT_MAX,-FLT_MAX);
|
|
|
|
}
|
2002-08-28 23:28:11 +08:00
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
inline bool valid() const
|
2002-06-20 00:06:03 +08:00
|
|
|
{
|
|
|
|
return _max.x()>=_min.x();
|
|
|
|
}
|
|
|
|
|
2001-11-06 18:34:51 +08:00
|
|
|
inline void set (float xmin,float ymin,float zmin,
|
|
|
|
float xmax,float ymax,float zmax)
|
|
|
|
{
|
|
|
|
_min.set(xmin,ymin,zmin);
|
|
|
|
_max.set(xmax,ymax,zmax);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** construct to with specified min and max values.*/
|
|
|
|
inline void set(const Vec3& min,const Vec3& max)
|
|
|
|
{
|
|
|
|
_min = min;
|
|
|
|
_max = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& xMin() { return _min.x(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float xMin() const { return _min.x(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& yMin() { return _min.y(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float yMin() const { return _min.y(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& zMin() { return _min.z(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float zMin() const { return _min.z(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& xMax() { return _max.x(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float xMax() const { return _max.x(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& yMax() { return _max.y(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float yMax() const { return _max.y(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
inline float& zMax() { return _max.z(); }
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float zMax() const { return _max.z(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Calculate and return the center of the bounding box.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const Vec3 center() const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
return (_min+_max)*0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculate and return the radius of the bounding box.*/
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float radius() const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
return sqrtf(radius2());
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculate and return the radius squared of the bounding box.
|
|
|
|
Note, radius2() is faster to calculate than radius().*/
|
2002-09-02 20:31:35 +08:00
|
|
|
inline float radius2() const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
return 0.25f*((_max-_min).length2());
|
|
|
|
}
|
|
|
|
|
|
|
|
/** return the corner of the bounding box.
|
2001-09-29 04:10:41 +08:00
|
|
|
Position (pos) is specified by a number between 0 and 7,
|
2001-01-11 00:32:10 +08:00
|
|
|
the first bit toggles between x min and x max, second
|
|
|
|
bit toggles between y min and y max, third bit toggles
|
|
|
|
between z min and z max.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const Vec3 corner(unsigned int pos) const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
return Vec3(pos&1?_max.x():_min.x(),pos&2?_max.y():_min.y(),pos&4?_max.z():_min.z());
|
|
|
|
}
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** If the vertex is out-with the box expand to encompass vertex.
|
2001-01-11 00:32:10 +08:00
|
|
|
If this box is empty then move set this box's min max to vertex. */
|
2002-07-19 06:35:54 +08:00
|
|
|
inline void expandBy(const Vec3& v)
|
|
|
|
{
|
|
|
|
if(v.x()<_min.x()) _min.x() = v.x();
|
|
|
|
if(v.x()>_max.x()) _max.x() = v.x();
|
|
|
|
|
|
|
|
if(v.y()<_min.y()) _min.y() = v.y();
|
|
|
|
if(v.y()>_max.y()) _max.y() = v.y();
|
|
|
|
|
|
|
|
if(v.z()<_min.z()) _min.z() = v.z();
|
|
|
|
if(v.z()>_max.z()) _max.z() = v.z();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** If the vertex is out-with the box expand to encompass vertex.
|
|
|
|
If this box is empty then move set this box's min max to vertex. */
|
|
|
|
inline void expandBy(float x,float y,float z)
|
|
|
|
{
|
|
|
|
if(x<_min.x()) _min.x() = x;
|
|
|
|
if(x>_max.x()) _max.x() = x;
|
|
|
|
|
|
|
|
if(y<_min.y()) _min.y() = y;
|
|
|
|
if(y>_max.y()) _max.y() = y;
|
|
|
|
|
2002-07-19 23:49:43 +08:00
|
|
|
if(z<_min.z()) _min.z() = z;
|
|
|
|
if(z>_max.z()) _max.z() = z;
|
2002-07-19 06:35:54 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** If incoming box is out-with the box expand to encompass incoming box.
|
|
|
|
If this box is empty then move set this box to incoming box. */
|
2001-01-11 00:32:10 +08:00
|
|
|
void expandBy(const BoundingBox& bb);
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** If incoming sphere is out-with the box expand to encompass incoming sphere.
|
2001-01-11 00:32:10 +08:00
|
|
|
If this box is empty then move set this box to encompass the sphere. */
|
|
|
|
void expandBy(const BoundingSphere& sh);
|
|
|
|
|
|
|
|
/** return true is vertex v is within the box.*/
|
2002-09-02 20:31:35 +08:00
|
|
|
inline bool contains(const Vec3& v) const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
2002-07-11 22:32:21 +08:00
|
|
|
return valid() &&
|
2001-01-11 00:32:10 +08:00
|
|
|
(v.x()>=_min.x() && v.x()<=_max.x()) &&
|
|
|
|
(v.y()>=_min.y() && v.y()<=_max.y()) &&
|
|
|
|
(v.z()>=_min.z() && v.z()<=_max.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2002-02-03 20:33:41 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
#endif
|