| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
|---|---|
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #include "Math/BsTorus.h" |
| 4 | #include "Math/BsRay.h" |
| 5 | #include "Math/BsMath.h" |
| 6 | #include "Debug/BsDebug.h" |
| 7 | |
| 8 | namespace bs |
| 9 | { |
| 10 | std::pair<bool, float> Torus::intersects(const Ray& ray) const |
| 11 | { |
| 12 | const Vector3& org = ray.getOrigin(); |
| 13 | const Vector3& dir = ray.getDirection(); |
| 14 | |
| 15 | float u = normal.dot(org); |
| 16 | float v = normal.dot(dir); |
| 17 | |
| 18 | float a = dir.dot(dir) - v * v; |
| 19 | float b = 2 * (org.dot(dir) - u * v); |
| 20 | float c = org.dot(org) - u * u; |
| 21 | float d = org.dot(org) + outerRadius*outerRadius - innerRadius*innerRadius; |
| 22 | |
| 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 | |
| 29 | float roots[4]; |
| 30 | UINT32 numRoots = Math::solveQuartic(A, B, C, D, E, roots); |
| 31 | |
| 32 | if (numRoots > 0) |
| 33 | { |
| 34 | float nearestT = std::numeric_limits<float>::max(); |
| 35 | |
| 36 | for (UINT32 i = 0; i < numRoots; i++) |
| 37 | { |
| 38 | float t = roots[i]; |
| 39 | if (t > 0 && t < nearestT) |
| 40 | nearestT = t; |
| 41 | } |
| 42 | |
| 43 | if (nearestT > std::numeric_limits<float>::epsilon()) |
| 44 | return std::make_pair(true, nearestT); |
| 45 | } |
| 46 | |
| 47 | return std::make_pair(false, 0.0f); |
| 48 | } |
| 49 | } |
| 50 |