CmSphere.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include "CmSphere.h"
  2. #include "CmRay.h"
  3. #include "CmPlane.h"
  4. #include "CmAABox.h"
  5. namespace CamelotFramework
  6. {
  7. std::pair<bool, float> Sphere::intersects(const Ray& ray, bool discardInside) const
  8. {
  9. const Vector3& raydir = ray.getDirection();
  10. // Adjust ray origin relative to sphere center
  11. const Vector3& rayorig = ray.getOrigin() - getCenter();
  12. float radius = getRadius();
  13. // Check origin inside first
  14. if (rayorig.squaredLength() <= radius*radius && discardInside)
  15. {
  16. return std::pair<bool, float>(true, 0.0f);
  17. }
  18. // Mmm, quadratics
  19. // Build coeffs which can be used with std quadratic solver
  20. // ie t = (-b +/- sqrt(b*b + 4ac)) / 2a
  21. float a = raydir.dot(raydir);
  22. float b = 2 * rayorig.dot(raydir);
  23. float c = rayorig.dot(rayorig) - radius*radius;
  24. // Calc determinant
  25. float d = (b*b) - (4 * a * c);
  26. if (d < 0)
  27. {
  28. // No intersection
  29. return std::pair<bool, float>(false, 0.0f);
  30. }
  31. else
  32. {
  33. // BTW, if d=0 there is one intersection, if d > 0 there are 2
  34. // But we only want the closest one, so that's ok, just use the
  35. // '-' version of the solver
  36. float t = ( -b - Math::sqrt(d) ) / (2 * a);
  37. if (t < 0)
  38. t = ( -b + Math::sqrt(d) ) / (2 * a);
  39. return std::pair<bool, float>(true, t);
  40. }
  41. }
  42. bool Sphere::intersects(const Plane& plane) const
  43. {
  44. return (Math::abs(plane.getDistance(getCenter())) <= getRadius());
  45. }
  46. bool Sphere::intersects(const AABox& box) const
  47. {
  48. return box.intersects(*this);
  49. }
  50. }