BsSphere.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "BsSphere.h"
  2. #include "BsRay.h"
  3. #include "BsPlane.h"
  4. #include "BsAABox.h"
  5. namespace BansheeEngine
  6. {
  7. void Sphere::merge(const Sphere& rhs)
  8. {
  9. Vector3 newCenter = (mCenter + rhs.mCenter) * 0.5f;
  10. float newRadiusA = newCenter.distance(mCenter) + getRadius();
  11. float newRadiusB = newCenter.distance(rhs.mCenter) + rhs.getRadius();
  12. mCenter = newCenter;
  13. mRadius = std::max(newRadiusA, newRadiusB);
  14. }
  15. void Sphere::merge(const Vector3& point)
  16. {
  17. float dist = point.distance(mCenter);
  18. mRadius = std::max(mRadius, dist);
  19. }
  20. void Sphere::transform(const Matrix4& matrix)
  21. {
  22. Vector3 edge = mCenter + Vector3::UNIT_X * mRadius;
  23. mCenter = matrix.multiplyAffine(mCenter);
  24. edge = matrix.multiplyAffine(edge);
  25. mRadius = mCenter.distance(edge);
  26. }
  27. std::pair<bool, float> Sphere::intersects(const Ray& ray, bool discardInside) const
  28. {
  29. const Vector3& raydir = ray.getDirection();
  30. const Vector3& rayorig = ray.getOrigin() - getCenter();
  31. float radius = getRadius();
  32. // Check origin inside first
  33. if (rayorig.squaredLength() <= radius*radius && discardInside)
  34. {
  35. return std::pair<bool, float>(true, 0.0f);
  36. }
  37. // t = (-b +/- sqrt(b*b + 4ac)) / 2a
  38. float a = raydir.dot(raydir);
  39. float b = 2 * rayorig.dot(raydir);
  40. float c = rayorig.dot(rayorig) - radius*radius;
  41. // Determinant
  42. float d = (b*b) - (4 * a * c);
  43. if (d < 0)
  44. {
  45. // No intersection
  46. return std::pair<bool, float>(false, 0.0f);
  47. }
  48. else
  49. {
  50. // If d == 0 there is one intersection, if d > 0 there are 2.
  51. // We only return the first one.
  52. float t = ( -b - Math::sqrt(d) ) / (2 * a);
  53. if (t < 0)
  54. t = ( -b + Math::sqrt(d) ) / (2 * a);
  55. return std::pair<bool, float>(true, t);
  56. }
  57. }
  58. bool Sphere::intersects(const Plane& plane) const
  59. {
  60. return (Math::abs(plane.getDistance(getCenter())) <= getRadius());
  61. }
  62. bool Sphere::intersects(const AABox& box) const
  63. {
  64. return box.intersects(*this);
  65. }
  66. }