00001 #define LOCAL_EPSILON 0.000001f 00002 00004 00015 00016 inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) 00017 { 00018 // Stats 00019 mNbRayPrimTests++; 00020 00021 // Find vectors for two edges sharing vert0 00022 Point edge1 = vert1 - vert0; 00023 Point edge2 = vert2 - vert0; 00024 00025 // Begin calculating determinant - also used to calculate U parameter 00026 Point pvec = mDir^edge2; 00027 00028 // If determinant is near zero, ray lies in plane of triangle 00029 float det = edge1|pvec; 00030 00031 if(mCulling) 00032 { 00033 if(det<LOCAL_EPSILON) return FALSE; 00034 // From here, det is > 0. So we can use integer cmp. 00035 00036 // Calculate distance from vert0 to ray origin 00037 Point tvec = mOrigin - vert0; 00038 00039 // Calculate U parameter and test bounds 00040 mStabbedFace.mU = tvec|pvec; 00041 // if(IR(u)&0x80000000 || u>det) return FALSE; 00042 if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IR(det)) return FALSE; 00043 00044 // Prepare to test V parameter 00045 Point qvec = tvec^edge1; 00046 00047 // Calculate V parameter and test bounds 00048 mStabbedFace.mV = mDir|qvec; 00049 if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>det) return FALSE; 00050 00051 // Calculate t, scale parameters, ray intersects triangle 00052 mStabbedFace.mDistance = edge2|qvec; 00053 // Det > 0 so we can early exit here 00054 // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) 00055 if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; 00056 // Else go on 00057 float OneOverDet = 1.0f / det; 00058 mStabbedFace.mDistance *= OneOverDet; 00059 mStabbedFace.mU *= OneOverDet; 00060 mStabbedFace.mV *= OneOverDet; 00061 } 00062 else 00063 { 00064 // the non-culling branch 00065 if(det>-LOCAL_EPSILON && det<LOCAL_EPSILON) return FALSE; 00066 float OneOverDet = 1.0f / det; 00067 00068 // Calculate distance from vert0 to ray origin 00069 Point tvec = mOrigin - vert0; 00070 00071 // Calculate U parameter and test bounds 00072 mStabbedFace.mU = (tvec|pvec) * OneOverDet; 00073 // if(IR(u)&0x80000000 || u>1.0f) return FALSE; 00074 if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IEEE_1_0) return FALSE; 00075 00076 // prepare to test V parameter 00077 Point qvec = tvec^edge1; 00078 00079 // Calculate V parameter and test bounds 00080 mStabbedFace.mV = (mDir|qvec) * OneOverDet; 00081 if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>1.0f) return FALSE; 00082 00083 // Calculate t, ray intersects triangle 00084 mStabbedFace.mDistance = (edge2|qvec) * OneOverDet; 00085 // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) 00086 if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; 00087 } 00088 return TRUE; 00089 }