| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #ifndef ANKI_COLLISION_SPHERE_H
- #define ANKI_COLLISION_SPHERE_H
- #include "anki/collision/CollisionShape.h"
- #include "anki/Math.h"
- namespace anki {
- /// @addtogroup Collision
- /// @{
- /// Sphere collision shape
- class Sphere: public CollisionShape
- {
- public:
- /// @name Constructors
- /// @{
- /// Default constructor
- Sphere()
- : CollisionShape(CST_SPHERE)
- {}
- /// Copy constructor
- Sphere(const Sphere& b)
- : CollisionShape(CST_SPHERE), center(b.center), radius(b.radius)
- {}
- /// Constructor
- Sphere(const Vec3& center_, F32 radius_)
- : CollisionShape(CST_SPHERE), center(center_), radius(radius_)
- {}
- /// @}
- /// @name Accessors
- /// @{
- const Vec3& getCenter() const
- {
- return center;
- }
- Vec3& getCenter()
- {
- return center;
- }
- void setCenter(const Vec3& x)
- {
- center = x;
- }
- F32 getRadius() const
- {
- return radius;
- }
- F32& getRadius()
- {
- return radius;
- }
- void setRadius(const F32 x)
- {
- radius = x;
- }
- /// @}
- /// @name Operators
- /// @{
- Sphere& operator=(const Sphere& b)
- {
- center = b.center;
- radius = b.radius;
- return *this;
- }
- /// @}
- /// Check for collision
- template<typename T>
- Bool collide(const T& x) const
- {
- return detail::collide(*this, x);
- }
- /// Implements CollisionShape::accept
- void accept(MutableVisitor& v)
- {
- v.visit(*this);
- }
- /// Implements CollisionShape::accept
- void accept(ConstVisitor& v) const
- {
- v.visit(*this);
- }
- /// Implements CollisionShape::testPlane
- F32 testPlane(const Plane& p) const;
- /// Implements CollisionShape::transform
- void transform(const Transform& trf)
- {
- *this = getTransformed(trf);
- }
- /// Implements CollisionShape::toAabb
- void toAabb(Aabb& b) const;
- Sphere getTransformed(const Transform& transform) const;
- /// Get the sphere that includes this sphere and the given. See a
- /// drawing in the docs dir for more info about the algorithm
- Sphere getCompoundShape(const Sphere& b) const;
- /// Calculate from a set of points
- template<typename Container>
- void set(const Container& container);
- private:
- Vec3 center;
- F32 radius;
- };
- /// @}
- //==============================================================================
- template<typename Container>
- void Sphere::set(const Container& container)
- {
- ANKI_ASSERT(container.size() >= 1);
- Vec3 min(container.front());
- Vec3 max(container.front());
- // for all the Vec3 calc the max and min
- typename Container::const_iterator it = container.begin() + 1;
- for(; it != container.end(); ++it)
- {
- const Vec3& v = *it;
- for(U j = 0; j < 3; j++)
- {
- if(v[j] > max[j])
- {
- max[j] = v[j];
- }
- else if(v[j] < min[j])
- {
- min[j] = v[j];
- }
- }
- }
- center = (min + max) * 0.5; // average
- // max distance between center and the vec3 arr
- F32 maxDist = (container.front() - center).getLengthSquared();
- typename Container::const_iterator it_ = container.begin() + 1;
- for(; it_ != container.end(); ++it_)
- {
- const Vec3& v = *it_;
- F32 dist = (v - center).getLengthSquared();
- if(dist > maxDist)
- {
- maxDist = dist;
- }
- }
- radius = sqrt(maxDist);
- }
- } // end namespace
- #endif
|