Sphere.h 2.1 KB

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