BsTorus.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include "BsTorus.h"
  2. #include "BsRay.h"
  3. #include "BsMath.h"
  4. #include "BsDebug.h"
  5. namespace BansheeEngine
  6. {
  7. Torus::Torus()
  8. :outerRadius(0.0f), innerRadius(0.0f)
  9. { }
  10. Torus::Torus(const Vector3& normal, float outerRadius, float innerRadius)
  11. :normal(normal), outerRadius(outerRadius), innerRadius(innerRadius)
  12. { }
  13. std::pair<bool, float> Torus::intersects(const Ray& ray) const
  14. {
  15. const Vector3& org = ray.getOrigin();
  16. const Vector3& dir = ray.getDirection();
  17. float u = normal.dot(org);
  18. float v = normal.dot(dir);
  19. float a = dir.dot(dir) - v * v;
  20. float b = 2 * (org.dot(dir) - u * v);
  21. float c = org.dot(org) - u * u;
  22. float d = org.dot(org) + outerRadius*outerRadius - innerRadius*innerRadius;
  23. float A = 1.0f;
  24. float B = 4 * org.dot(dir);
  25. float C = 2 * d + 0.25f * B * B - 4 * outerRadius * outerRadius * a;
  26. float D = B * d - 4 * outerRadius * outerRadius * b;
  27. float E = d * d - 4 * outerRadius * outerRadius * c;
  28. float roots[4];
  29. UINT32 numRoots = Math::solveQuartic(A, B, C, D, E, roots);
  30. if (numRoots > 0)
  31. {
  32. float nearestT = std::numeric_limits<float>::max();
  33. for (UINT32 i = 0; i < numRoots; i++)
  34. {
  35. float t = roots[i];
  36. float x = org.x + t*dir.x;
  37. float y = org.y + t*dir.y;
  38. float l = outerRadius*(Math::PI / 2 - Math::atan2(y, x).valueRadians());
  39. if (l >= 0 && t < nearestT)
  40. nearestT = t;
  41. }
  42. return std::make_pair(true, nearestT);
  43. }
  44. return std::make_pair(false, 0.0f);
  45. }
  46. }