Sphere.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Geometry/AABox.h>
  6. JPH_NAMESPACE_BEGIN
  7. class [[nodiscard]] Sphere
  8. {
  9. public:
  10. JPH_OVERRIDE_NEW_DELETE
  11. /// Constructor
  12. inline Sphere() = default;
  13. inline Sphere(const Float3 &inCenter, float inRadius) : mCenter(inCenter), mRadius(inRadius) { }
  14. inline Sphere(Vec3Arg inCenter, float inRadius) : mRadius(inRadius) { inCenter.StoreFloat3(&mCenter); }
  15. /// Calculate the support vector for this convex shape.
  16. inline Vec3 GetSupport(Vec3Arg inDirection) const
  17. {
  18. float length = inDirection.Length();
  19. return length > 0.0f ? Vec3::sLoadFloat3Unsafe(mCenter) + (mRadius/ length) * inDirection : Vec3::sLoadFloat3Unsafe(mCenter);
  20. }
  21. // Properties
  22. inline Vec3 GetCenter() const { return Vec3::sLoadFloat3Unsafe(mCenter); }
  23. inline float GetRadius() const { return mRadius; }
  24. /// Test if two spheres overlap
  25. inline bool Overlaps(const Sphere &inB) const
  26. {
  27. return (Vec3::sLoadFloat3Unsafe(mCenter) - Vec3::sLoadFloat3Unsafe(inB.mCenter)).LengthSq() <= Square(mRadius + inB.mRadius);
  28. }
  29. /// Check if this sphere overlaps with a box
  30. inline bool Overlaps(const AABox &inOther) const
  31. {
  32. return inOther.GetSqDistanceTo(GetCenter()) <= Square(mRadius);
  33. }
  34. /// Create the minimal sphere that encapsulates this sphere and inPoint
  35. inline void EncapsulatePoint(Vec3Arg inPoint)
  36. {
  37. // Calculate distance between point and center
  38. Vec3 center = GetCenter();
  39. Vec3 d_vec = inPoint - center;
  40. float d_sq = d_vec.LengthSq();
  41. if (d_sq > Square(mRadius))
  42. {
  43. // It is further away than radius, we need to widen the sphere
  44. // The diameter of the new sphere is radius + d, so the new radius is half of that
  45. float d = sqrt(d_sq);
  46. float radius = 0.5f * (mRadius + d);
  47. // The center needs to shift by new radius - old radius in the direction of d
  48. center += (radius - mRadius) / d * d_vec;
  49. // Store new sphere
  50. center.StoreFloat3(&mCenter);
  51. mRadius = radius;
  52. }
  53. }
  54. private:
  55. Float3 mCenter;
  56. float mRadius;
  57. };
  58. JPH_NAMESPACE_END