1 /* Copyright Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file TriangleMesh_IntersectRay_CPP.inl
16         @author Jukka Jyl�nki
17         @brief Non-SIMD implementation of ray-mesh intersection routines. */
18 MATH_BEGIN_NAMESPACE
19
20 float TriangleMesh::IntersectRay_CPP(const Ray &ray) const
21 float TriangleMesh::IntersectRay_TriangleIndex_CPP(const Ray &ray, int &outIndex) const
22 float TriangleMesh::IntersectRay_TriangleIndex_UV_CPP(const Ray &ray, int &outIndex, float &outU, float &outV) const
23 {
24
25 float TriangleMesh::IntersectLineTriSSE(const float3 &linePos, const float3 &lineDir,
26                 const float3 &v0, const float3 &v1, const float3 &v2,
27                 float &u, float &v)
28 {
29         float3 vE1, vE2;
30         float3 vT, vP, vQ;
31
32         const float epsilon = 1e-6f;
33
34         // Edge vectors
35         vE1 = v1 - v0;
36         vE2 = v2 - v0;
37
38         // begin calculating determinant - also used to calculate U parameter
39         vP.x = lineDir.y * vE2.z - lineDir.z * vE2.y;
40         vP.y = lineDir.z * vE2.x - lineDir.x * vE2.z;
41         vP.z = lineDir.x * vE2.y - lineDir.y * vE2.x;
42
43         // If det < 0, intersecting backfacing tri, > 0, intersecting frontfacing tri, 0, parallel to plane.
44         const float det = vE1.x * vP.x + vE1.y * vP.y + vE1.z * vP.z;
45
46         // If determinant is near zero, ray lies in plane of triangle.
47         if (fabs(det) <= epsilon)
48                 return FLOAT_INF;
49         const float recipDet = 1.f / det;
50
51         // Calculate distance from v0 to ray origin
52         vT = linePos - v0;
53
54         // Output barycentric u
55         u = (vT.x * vP.x + vT.y * vP.y + vT.z * vP.z) * recipDet;
56         if (u < 0.f || u > 1.f)
57                 return FLOAT_INF// Barycentric U is outside the triangle - early out.
58
59         // Prepare to test V parameter
60         vQ.x = vT.y * vE1.z - vT.z * vE1.y;
61         vQ.y = vT.z * vE1.x - vT.x * vE1.z;
62         vQ.z = vT.x * vE1.y - vT.y * vE1.x;
63
64         // Output barycentric v
65         v = (lineDir.x * vQ.x + lineDir.y * vQ.y + lineDir.z * vQ.z) * recipDet;
66         if (v < 0.f || u + v > 1.f) // Barycentric V or the combination of U and V are outside the triangle - no intersection.
67                 return FLOAT_INF;
68
69         // Barycentric u and v are in limits, the ray intersects the triangle.
70         
71         // Output signed distance from ray to triangle.
72         return (vE2.x * vQ.x + vE2.y * vQ.y + vE2.z * vQ.z) * recipDet;
73 }
74
75 MATH_END_NAMESPACE

Go back to previous page