BsSphere.cpp 2.2 KB

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