2
0

BsTorus.cpp 1.6 KB

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