This algorithm comes from Microsoft DirectX SDK. Lanfortic Grass Recommended. The basic algorithm wants to understand. It is why there is no negative sign. I haven't thought about it. I don't know why the result is basically correct. It should be better.
Bool Intertion (Xray & Ray, Xtriangle & Tri, XPoint & Point, Float & T, Float & U, FLOAT & T, FLOAT & U, FLOAT & V) {// Find Vector for Two Edges Sharing Vert0 / ***
The triangle is V1, V2, V3 two sides of E1 = V2-V1 E2 = V3 - V1 rays to RAY = P0 D * T triangular internal one P = V1 U * E1 V * E2 (U V < 1)
So: V1 U * E1 V * E2 = P0 D * T ===> U * E1 V * E2 - T * D = P0 - V1 ===> - T * D V * E2 U * E1 = P0 - V1 ===>
D.X D.Y D.Z | [-T, V, U] | E2.x E2.Y E2.Z | = P0 - P1 ===> | E1.X E1.Y E1.Z |
[-t, v, u] * m = p0 - p1;
[-t, v, u] = (p0 - p1) * INV (m);
T = (p0 - p1) * E1 x E2 / DET (M) = (p0 - p1) x e1 * E2 / DET (M)
v = (p0 - p1) * E1 x d / DET (m) = (p0 - p1) x e1 * D / DET (m)
u = (p0 - p1) * D x E2 / DET (M)
** / xvector3d e1 = tri.m_points [1] - tri.m_points [0]; xVector3d e2 = tri.m_points [2] - Tri.m_points [0];
/ / See the DET (M) of the matrix M. And record D x E2; XVector3D VCP_DIR_E2; ray.m_dir.cp (E2, VCP_DIR_E2);
/ / Get the value of the row of matrices float DET = E1.DP (VCP_DIR_E2);
/ / Save (P0 - P1) XVector3D V_P0_P1;
// For the sake of judgment. DET = ABS (DET) IF (DET> 0) {v_p0_p1 = ray.m_point - tri.m_points [0];} else {v_p0_p1 = tri.m_points [0] - ray.m_point; Det = -det;}
IF (DET <0.0000001F) RETURN FALSE;
// u = (p0 - p1) * D x E2 / DET (m) DET (m) will then except U = V_P0_P1.DP (VCP_DIR_E2); if (u <0.0f || u> DET) Return False;
/ / Save (P0 - P1) X E1 XVECTOR3D VCP_P0P1_E1; V_P0_P1.CP (E1, VCP_P0P1_E1); // V = (P0 - P1) * E1 X D / DET (M) = (P0 - P1) X E1 * D / DET (m) // DET (m) will then except v = ray.m_dir.dp (VCP_P0P1_E1); if (V <0.0F || U V> DET) Return False;
// Calculate T, Scale parameters, ray intersects Triangle T = E2.DP (VCP_P0P1_E1); float finvdet = 1.0f / DET; T * = finvdet; u * = finvdet; v * = finvdet;
Point = ray.m_point ray.m_dir * t;
Return True;}