BsTorus.cpp 1.3 KB

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