/// <summary> /// Non-allocating version of Ray / Triangle intersection. /// </summary> /// <param name="origin"></param> /// <param name="dir"></param> /// <param name="vert0"></param> /// <param name="vert1"></param> /// <param name="vert2"></param> /// <param name="distance"></param> /// <param name="normal"></param> /// <returns></returns> internal static bool RayIntersectsTriangle2(Vector3 origin, Vector3 dir, Vector3 vert0, Vector3 vert1, Vector3 vert2, out float distance, out Vector3 normal) { Math.Subtract(vert0, vert1, ref tv1); Math.Subtract(vert0, vert2, ref tv2); normal = Vector3.Cross(tv1, tv2); distance = 0f; // backface culling if (Vector3.Dot(dir, normal) > 0) { return(false); } Math.Cross(dir, tv2, ref tv4); float det = Vector3.Dot(tv1, tv4); if (det < Mathf.Epsilon) { return(false); } Math.Subtract(vert0, origin, ref tv3); float u = Vector3.Dot(tv3, tv4); if (u < 0f || u > det) { return(false); } Math.Cross(tv3, tv1, ref tv4); float v = Vector3.Dot(dir, tv4); if (v < 0f || u + v > det) { return(false); } distance = Vector3.Dot(tv2, tv4) * (1f / det); // no hit if point is behind the ray origin return(distance > 0f); }
/// <summary> /// Non-allocating version of Ray / Triangle intersection. /// </summary> /// <param name="origin"></param> /// <param name="dir"></param> /// <param name="vert0"></param> /// <param name="vert1"></param> /// <param name="vert2"></param> /// <param name="distance"></param> /// <param name="normal"></param> /// <returns></returns> internal static bool RayIntersectsTriangle2(Vector3 origin, Vector3 dir, Vector3 vert0, Vector3 vert1, Vector3 vert2, ref float distance, ref Vector3 normal) { Math.Subtract(vert0, vert1, ref tv1); Math.Subtract(vert0, vert2, ref tv2); Math.Cross(dir, tv2, ref tv4); float det = Vector3.Dot(tv1, tv4); if (det < Mathf.Epsilon) { return(false); } Math.Subtract(vert0, origin, ref tv3); float u = Vector3.Dot(tv3, tv4); if (u < 0f || u > det) { return(false); } Math.Cross(tv3, tv1, ref tv4); float v = Vector3.Dot(dir, tv4); if (v < 0f || u + v > det) { return(false); } distance = Vector3.Dot(tv2, tv4) * (1f / det); Math.Cross(tv1, tv2, ref normal); return(true); }