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
8namespace 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