2
0

IceBoundingSphere.h 6.8 KB

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