| 938 | //----------------------------------------------------------------------------- |
| 939 | |
| 940 | bool mRayQuadCollide( const Quad &quad, |
| 941 | const Ray &ray, |
| 942 | Point2F *outUV, |
| 943 | F32 *outT ) |
| 944 | { |
| 945 | static const F32 eps = F32(10e-6); |
| 946 | |
| 947 | // Rejects rays that are parallel to Q, and rays that intersect the plane of |
| 948 | // Q either on the left of the line V00V01 or on the right of the line V00V10. |
| 949 | |
| 950 | // p01-----eXX-----p11 |
| 951 | // ^ . ^ | |
| 952 | // | . | |
| 953 | // e03 e02 eXX |
| 954 | // | . | |
| 955 | // | . | |
| 956 | // p00-----e01---->p10 |
| 957 | |
| 958 | VectorF e01 = quad.p10 - quad.p00; |
| 959 | VectorF e03 = quad.p01 - quad.p00; |
| 960 | |
| 961 | // If the ray is perfectly perpendicular to e03, which |
| 962 | // represents the entire planes tangent, then the |
| 963 | // result of this cross product (P) will equal e01 |
| 964 | // If it is parallel it will result in a vector opposite e01. |
| 965 | |
| 966 | // If the ray is heading DOWN the cross product will point to the RIGHT |
| 967 | // If the ray is heading UP the cross product will point to the LEFT |
| 968 | // We do not reject based on this though... |
| 969 | // |
| 970 | // In either case cross product will be more parallel to e01 the more |
| 971 | // perpendicular the ray is to e03, and it will be more perpendicular to |
| 972 | // e01 the more parallel it is to e03. |
| 973 | VectorF P = mCross(ray.direction, e03); |
| 974 | |
| 975 | // det can be seen as 'the amount of vector e01 in the direction P' |
| 976 | F32 det = mDot(e01, P); |
| 977 | |
| 978 | // Take a Abs of the dot because we do not care if the ray is heading up or down, |
| 979 | // but if it is perfectly parallel to the quad we want to reject it. |
| 980 | if ( mFabs(det) < eps ) |
| 981 | return false; |
| 982 | |
| 983 | F32 inv_det = 1.0f / det; |
| 984 | |
| 985 | VectorF T = ray.origin - quad.p00; |
| 986 | |
| 987 | // alpha can be seen as 'the amount of vector T in the direction P' |
| 988 | // T is a vector up from the quads corner point 00 to the ray's origin. |
| 989 | // P is the cross product of the ray and e01, which should be "roughly" |
| 990 | // parallel with e03 but might be of either positive or negative magnitude. |
| 991 | F32 alpha = mDot(T, P) * inv_det; |
| 992 | if ( alpha < 0.0f ) |
| 993 | return false; |
| 994 | |
| 995 | // if (alpha > real(1.0)) return false; // Uncomment if VR is used. |
| 996 | |
| 997 | // The cross product of T and e01 should be roughly parallel to e03 |