1 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 /** 3 * Contains code to compute the minimal bounding sphere. 4 * \file IceBoundingSphere.h 5 * \author Pierre Terdiman 6 * \date January, 29, 2000 7 */ 8 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9 10 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 11 // Include Guard 12 #ifndef __ICEBOUNDINGSPHERE_H__ 13 #define __ICEBOUNDINGSPHERE_H__ 14 15 enum BSphereMethod 16 { 17 BS_NONE, 18 BS_GEMS, 19 BS_MINIBALL, 20 21 BS_FORCE_DWORD = 0x7fffffff 22 }; 23 24 class ICEMATHS_API Sphere 25 { 26 public: 27 //! Constructor Sphere()28 inline_ Sphere() {} 29 //! Constructor Sphere(const Point & center,float radius)30 inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {} 31 //! Constructor 32 Sphere(udword nb_verts, const Point* verts); 33 //! Copy constructor Sphere(const Sphere & sphere)34 inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {} 35 //! Destructor ~Sphere()36 inline_ ~Sphere() {} 37 38 BSphereMethod Compute(udword nb_verts, const Point* verts); 39 bool FastCompute(udword nb_verts, const Point* verts); 40 41 // Access methods GetCenter()42 inline_ const Point& GetCenter() const { return mCenter; } GetRadius()43 inline_ float GetRadius() const { return mRadius; } 44 Center()45 inline_ const Point& Center() const { return mCenter; } Radius()46 inline_ float Radius() const { return mRadius; } 47 Set(const Point & center,float radius)48 inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; } SetCenter(const Point & center)49 inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; } SetRadius(float radius)50 inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; } 51 52 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 53 /** 54 * Tests if a point is contained within the sphere. 55 * \param p [in] the point to test 56 * \return true if inside the sphere 57 */ 58 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Contains(const Point & p)59 inline_ bool Contains(const Point& p) const 60 { 61 return mCenter.SquareDistance(p) <= mRadius*mRadius; 62 } 63 64 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 65 /** 66 * Tests if a sphere is contained within the sphere. 67 * \param sphere [in] the sphere to test 68 * \return true if inside the sphere 69 */ 70 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Contains(const Sphere & sphere)71 inline_ bool Contains(const Sphere& sphere) const 72 { 73 // If our radius is the smallest, we can't possibly contain the other sphere 74 if(mRadius < sphere.mRadius) return false; 75 // So r is always positive or null now 76 float r = mRadius - sphere.mRadius; 77 return mCenter.SquareDistance(sphere.mCenter) <= r*r; 78 } 79 80 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 81 /** 82 * Tests if a box is contained within the sphere. 83 * \param aabb [in] the box to test 84 * \return true if inside the sphere 85 */ 86 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Contains(const AABB & aabb)87 inline_ BOOL Contains(const AABB& aabb) const 88 { 89 // I assume if all 8 box vertices are inside the sphere, so does the whole box. 90 // Sounds ok but maybe there's a better way? 91 float R2 = mRadius * mRadius; 92 #ifdef USE_MIN_MAX 93 const Point& Max = ((ShadowAABB&)&aabb).mMax; 94 const Point& Min = ((ShadowAABB&)&aabb).mMin; 95 #else 96 Point Max; aabb.GetMax(Max); 97 Point Min; aabb.GetMin(Min); 98 #endif 99 Point p; 100 p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; 101 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; 102 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; 103 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; 104 p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; 105 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; 106 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; 107 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; 108 109 return TRUE; 110 } 111 112 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 113 /** 114 * Tests if the sphere intersects another sphere 115 * \param sphere [in] the other sphere 116 * \return true if spheres overlap 117 */ 118 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Intersect(const Sphere & sphere)119 inline_ bool Intersect(const Sphere& sphere) const 120 { 121 float r = mRadius + sphere.mRadius; 122 return mCenter.SquareDistance(sphere.mCenter) <= r*r; 123 } 124 125 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 126 /** 127 * Checks the sphere is valid. 128 * \return true if the box is valid 129 */ 130 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IsValid()131 inline_ BOOL IsValid() const 132 { 133 // Consistency condition for spheres: Radius >= 0.0f 134 if(mRadius < 0.0f) return FALSE; 135 return TRUE; 136 } 137 public: 138 Point mCenter; //!< Sphere center 139 float mRadius; //!< Sphere radius 140 }; 141 142 #endif // __ICEBOUNDINGSPHERE_H__ 143