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 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
RayTriOverlap(const Point & vert0,const Point & vert1,const Point & vert2)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 }
90