2
0

Sphere.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #ifndef ANKI_COLLISION_SPHERE_H
  2. #define ANKI_COLLISION_SPHERE_H
  3. #include "anki/collision/CollisionShape.h"
  4. #include "anki/Math.h"
  5. namespace anki {
  6. /// @addtogroup Collision
  7. /// @{
  8. /// Sphere collision shape
  9. class Sphere: public CollisionShape
  10. {
  11. public:
  12. /// @name Constructors
  13. /// @{
  14. /// Default constructor
  15. Sphere()
  16. : CollisionShape(CST_SPHERE)
  17. {}
  18. /// Copy constructor
  19. Sphere(const Sphere& b)
  20. : CollisionShape(CST_SPHERE), center(b.center), radius(b.radius)
  21. {}
  22. /// Constructor
  23. Sphere(const Vec3& center_, F32 radius_)
  24. : CollisionShape(CST_SPHERE), center(center_), radius(radius_)
  25. {}
  26. /// @}
  27. /// @name Accessors
  28. /// @{
  29. const Vec3& getCenter() const
  30. {
  31. return center;
  32. }
  33. Vec3& getCenter()
  34. {
  35. return center;
  36. }
  37. void setCenter(const Vec3& x)
  38. {
  39. center = x;
  40. }
  41. F32 getRadius() const
  42. {
  43. return radius;
  44. }
  45. F32& getRadius()
  46. {
  47. return radius;
  48. }
  49. void setRadius(const F32 x)
  50. {
  51. radius = x;
  52. }
  53. /// @}
  54. /// @name Operators
  55. /// @{
  56. Sphere& operator=(const Sphere& b)
  57. {
  58. center = b.center;
  59. radius = b.radius;
  60. return *this;
  61. }
  62. /// @}
  63. /// Check for collision
  64. template<typename T>
  65. Bool collide(const T& x) const
  66. {
  67. return detail::collide(*this, x);
  68. }
  69. /// Implements CollisionShape::accept
  70. void accept(MutableVisitor& v)
  71. {
  72. v.visit(*this);
  73. }
  74. /// Implements CollisionShape::accept
  75. void accept(ConstVisitor& v) const
  76. {
  77. v.visit(*this);
  78. }
  79. /// Implements CollisionShape::testPlane
  80. F32 testPlane(const Plane& p) const;
  81. /// Implements CollisionShape::transform
  82. void transform(const Transform& trf)
  83. {
  84. *this = getTransformed(trf);
  85. }
  86. /// Implements CollisionShape::toAabb
  87. void toAabb(Aabb& b) const;
  88. Sphere getTransformed(const Transform& transform) const;
  89. /// Get the sphere that includes this sphere and the given. See a
  90. /// drawing in the docs dir for more info about the algorithm
  91. Sphere getCompoundShape(const Sphere& b) const;
  92. /// Calculate from a set of points
  93. template<typename Container>
  94. void set(const Container& container);
  95. private:
  96. Vec3 center;
  97. F32 radius;
  98. };
  99. /// @}
  100. //==============================================================================
  101. template<typename Container>
  102. void Sphere::set(const Container& container)
  103. {
  104. ANKI_ASSERT(container.size() >= 1);
  105. Vec3 min(container.front());
  106. Vec3 max(container.front());
  107. // for all the Vec3 calc the max and min
  108. typename Container::const_iterator it = container.begin() + 1;
  109. for(; it != container.end(); ++it)
  110. {
  111. const Vec3& v = *it;
  112. for(U j = 0; j < 3; j++)
  113. {
  114. if(v[j] > max[j])
  115. {
  116. max[j] = v[j];
  117. }
  118. else if(v[j] < min[j])
  119. {
  120. min[j] = v[j];
  121. }
  122. }
  123. }
  124. center = (min + max) * 0.5; // average
  125. // max distance between center and the vec3 arr
  126. F32 maxDist = (container.front() - center).getLengthSquared();
  127. typename Container::const_iterator it_ = container.begin() + 1;
  128. for(; it_ != container.end(); ++it_)
  129. {
  130. const Vec3& v = *it_;
  131. F32 dist = (v - center).getLengthSquared();
  132. if(dist > maxDist)
  133. {
  134. maxDist = dist;
  135. }
  136. }
  137. radius = sqrt(maxDist);
  138. }
  139. } // end namespace
  140. #endif