diff options
Diffstat (limited to 'libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h')
-rw-r--r-- | libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h | 89 |
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 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
16 | inline_ 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 | } | ||