2 * ICE / OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 * Contains code to compute the minimal bounding sphere.
20 * \file IceBoundingSphere.h
21 * \author Pierre Terdiman
22 * \date January, 29, 2000
24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28 #ifndef __ICEBOUNDINGSPHERE_H__
29 #define __ICEBOUNDINGSPHERE_H__
37 BS_FORCE_DWORD = 0x7fffffff
40 class ICEMATHS_API Sphere
46 inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {}
48 Sphere(udword nb_verts, const Point* verts);
50 inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {}
54 BSphereMethod Compute(udword nb_verts, const Point* verts);
55 bool FastCompute(udword nb_verts, const Point* verts);
58 inline_ const Point& GetCenter() const { return mCenter; }
59 inline_ float GetRadius() const { return mRadius; }
61 inline_ const Point& Center() const { return mCenter; }
62 inline_ float Radius() const { return mRadius; }
64 inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; }
65 inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; }
66 inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; }
68 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 * Tests if a point is contained within the sphere.
71 * \param p [in] the point to test
72 * \return true if inside the sphere
74 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
75 inline_ bool Contains(const Point& p) const
77 return mCenter.SquareDistance(p) <= mRadius*mRadius;
80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82 * Tests if a sphere is contained within the sphere.
83 * \param sphere [in] the sphere to test
84 * \return true if inside the sphere
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87 inline_ bool Contains(const Sphere& sphere) const
89 // If our radius is the smallest, we can't possibly contain the other sphere
90 if(mRadius < sphere.mRadius) return false;
91 // So r is always positive or null now
92 float r = mRadius - sphere.mRadius;
93 return mCenter.SquareDistance(sphere.mCenter) <= r*r;
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
98 * Tests if a box is contained within the sphere.
99 * \param aabb [in] the box to test
100 * \return true if inside the sphere
102 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
103 inline_ BOOL Contains(const AABB& aabb) const
105 // I assume if all 8 box vertices are inside the sphere, so does the whole box.
106 // Sounds ok but maybe there's a better way?
107 float R2 = mRadius * mRadius;
109 const Point& Max = ((ShadowAABB&)&aabb).mMax;
110 const Point& Min = ((ShadowAABB&)&aabb).mMin;
112 Point Max; aabb.GetMax(Max);
113 Point Min; aabb.GetMin(Min);
116 p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
117 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
118 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
119 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
120 p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
121 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
122 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
123 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
128 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130 * Tests if the sphere intersects another sphere
131 * \param sphere [in] the other sphere
132 * \return true if spheres overlap
134 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
135 inline_ bool Intersect(const Sphere& sphere) const
137 float r = mRadius + sphere.mRadius;
138 return mCenter.SquareDistance(sphere.mCenter) <= r*r;
141 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 * Checks the sphere is valid.
144 * \return true if the box is valid
146 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147 inline_ BOOL IsValid() const
149 // Consistency condition for spheres: Radius >= 0.0f
150 if(mRadius < 0.0f) return FALSE;
154 Point mCenter; //!< Sphere center
155 float mRadius; //!< Sphere radius
158 #endif // __ICEBOUNDINGSPHERE_H__