aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h')
-rw-r--r--libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h
new file mode 100644
index 0000000..7fe37c9
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h
@@ -0,0 +1,89 @@
1#define LOCAL_EPSILON 0.000001f
2
3///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4/**
5 * Computes a ray-triangle intersection test.
6 * Original code from Tomas Möller's "Fast Minimum Storage Ray-Triangle Intersection".
7 * It's been optimized a bit with integer code, and modified to return a non-intersection if distance from
8 * ray origin to triangle is negative.
9 *
10 * \param vert0 [in] triangle vertex
11 * \param vert1 [in] triangle vertex
12 * \param vert2 [in] triangle vertex
13 * \return true on overlap. mStabbedFace is filled with relevant info.
14 */
15///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2)
17{
18 // Stats
19 mNbRayPrimTests++;
20
21 // Find vectors for two edges sharing vert0
22 Point edge1 = vert1 - vert0;
23 Point edge2 = vert2 - vert0;
24
25 // Begin calculating determinant - also used to calculate U parameter
26 Point pvec = mDir^edge2;
27
28 // If determinant is near zero, ray lies in plane of triangle
29 float det = edge1|pvec;
30
31 if(mCulling)
32 {
33 if(det<LOCAL_EPSILON) return FALSE;
34 // From here, det is > 0. So we can use integer cmp.
35
36 // Calculate distance from vert0 to ray origin
37 Point tvec = mOrigin - vert0;
38
39 // Calculate U parameter and test bounds
40 mStabbedFace.mU = tvec|pvec;
41// if(IR(u)&0x80000000 || u>det) return FALSE;
42 if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IR(det)) return FALSE;
43
44 // Prepare to test V parameter
45 Point qvec = tvec^edge1;
46
47 // Calculate V parameter and test bounds
48 mStabbedFace.mV = mDir|qvec;
49 if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>det) return FALSE;
50
51 // Calculate t, scale parameters, ray intersects triangle
52 mStabbedFace.mDistance = edge2|qvec;
53 // Det > 0 so we can early exit here
54 // Intersection point is valid if distance is positive (else it can just be a face behind the orig point)
55 if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE;
56 // Else go on
57 float OneOverDet = 1.0f / det;
58 mStabbedFace.mDistance *= OneOverDet;
59 mStabbedFace.mU *= OneOverDet;
60 mStabbedFace.mV *= OneOverDet;
61 }
62 else
63 {
64 // the non-culling branch
65 if(det>-LOCAL_EPSILON && det<LOCAL_EPSILON) return FALSE;
66 float OneOverDet = 1.0f / det;
67
68 // Calculate distance from vert0 to ray origin
69 Point tvec = mOrigin - vert0;
70
71 // Calculate U parameter and test bounds
72 mStabbedFace.mU = (tvec|pvec) * OneOverDet;
73// if(IR(u)&0x80000000 || u>1.0f) return FALSE;
74 if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IEEE_1_0) return FALSE;
75
76 // prepare to test V parameter
77 Point qvec = tvec^edge1;
78
79 // Calculate V parameter and test bounds
80 mStabbedFace.mV = (mDir|qvec) * OneOverDet;
81 if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>1.0f) return FALSE;
82
83 // Calculate t, ray intersects triangle
84 mStabbedFace.mDistance = (edge2|qvec) * OneOverDet;
85 // Intersection point is valid if distance is positive (else it can just be a face behind the orig point)
86 if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE;
87 }
88 return TRUE;
89}