BsSphere.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. Vector3 newCenter = (mCenter + point) * 0.5f;
  18. float newRadiusA = newCenter.distance(mCenter) + getRadius();
  19. float newRadiusB = newCenter.distance(point);
  20. mCenter = newCenter;
  21. mRadius = std::max(newRadiusA, newRadiusB);
  22. }
  23. void Sphere::transform(const Matrix4& matrix)
  24. {
  25. Vector3 edge = mCenter + Vector3::UNIT_X * mRadius;
  26. mCenter = matrix.multiply3x4(mCenter);
  27. edge = matrix.multiply3x4(edge);
  28. mRadius = mCenter.distance(edge);
  29. }
  30. std::pair<bool, float> Sphere::intersects(const Ray& ray, bool discardInside) const
  31. {
  32. const Vector3& raydir = ray.getDirection();
  33. const Vector3& rayorig = ray.getOrigin() - getCenter();
  34. float radius = getRadius();
  35. // Check origin inside first
  36. if (rayorig.squaredLength() <= radius*radius && discardInside)
  37. {
  38. return std::pair<bool, float>(true, 0.0f);
  39. }
  40. // t = (-b +/- sqrt(b*b + 4ac)) / 2a
  41. float a = raydir.dot(raydir);
  42. float b = 2 * rayorig.dot(raydir);
  43. float c = rayorig.dot(rayorig) - radius*radius;
  44. // Determinant
  45. float d = (b*b) - (4 * a * c);
  46. if (d < 0)
  47. {
  48. // No intersection
  49. return std::pair<bool, float>(false, 0.0f);
  50. }
  51. else
  52. {
  53. // If d == 0 there is one intersection, if d > 0 there are 2.
  54. // We only return the first one.
  55. float t = ( -b - Math::sqrt(d) ) / (2 * a);
  56. if (t < 0)
  57. t = ( -b + Math::sqrt(d) ) / (2 * a);
  58. return std::pair<bool, float>(true, t);
  59. }
  60. }
  61. bool Sphere::intersects(const Plane& plane) const
  62. {
  63. return (Math::abs(plane.getDistance(getCenter())) <= getRadius());
  64. }
  65. bool Sphere::intersects(const AABox& box) const
  66. {
  67. return box.intersects(*this);
  68. }
  69. }