public static bool Intersects(XMVector origin, XMVector direction, XMVector v0, XMVector v1, XMVector v2, out float uCoordinate, out float vCoordinate, out float distance) { Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed"); XMVector zero = XMGlobalConstants.Zero; XMVector e1 = v1 - v0; XMVector e2 = v2 - v0; // p = Direction ^ e2; XMVector p = XMVector3.Cross(direction, e2); // det = e1 * p; XMVector det = XMVector3.Dot(e1, p); XMVector u, v, t; if (XMVector3.GreaterOrEqual(det, CollisionGlobalConstants.RayEpsilon)) { // Determinate is positive (front side of the triangle). XMVector s = origin - v0; // u = s * p; u = XMVector3.Dot(s, p); XMVector noIntersection = XMVector.Less(u, zero); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u, det)); // q = s ^ e1; XMVector q = XMVector3.Cross(s, e1); // v = Direction * q; v = XMVector3.Dot(direction, q); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(v, zero)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u + v, det)); // t = e2 * q; t = XMVector3.Dot(e2, q); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(t, zero)); if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt)) { uCoordinate = 0.0f; vCoordinate = 0.0f; distance = 0.0f; return(false); } } else if (XMVector3.LessOrEqual(det, CollisionGlobalConstants.RayNegEpsilon)) { // Determinate is negative (back side of the triangle). XMVector s = origin - v0; // u = s * p; u = XMVector3.Dot(s, p); XMVector noIntersection = XMVector.Greater(u, zero); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u, det)); // q = s ^ e1; XMVector q = XMVector3.Cross(s, e1); // v = Direction * q; v = XMVector3.Dot(direction, q); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(v, zero)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u + v, det)); // t = e2 * q; t = XMVector3.Dot(e2, q); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(t, zero)); if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt)) { uCoordinate = 0.0f; vCoordinate = 0.0f; distance = 0.0f; return(false); } } else { // Parallel ray. uCoordinate = 0.0f; vCoordinate = 0.0f; distance = 0.0f; return(false); } // (u / det) and (v / dev) are the barycentric coordinates of the intersection. u = XMVector.Divide(u, det); v = XMVector.Divide(v, det); t = XMVector.Divide(t, det); // Store the x-component to *pDist u.StoreFloat(out uCoordinate); v.StoreFloat(out vCoordinate); t.StoreFloat(out distance); return(true); }