bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj)
{
float tol = m_floatToleranceInCastRay;
posHitProj = Vector3.Zero;
// Calculate triangle edge vectors
Vector3 vec1Proj = triProj.p2 - triProj.p1;
Vector3 vec2Proj = triProj.p3 - triProj.p2;
Vector3 vec3Proj = triProj.p1 - triProj.p3;
// Calculate triangle normal
normalProj = Vector3.Cross(vec1Proj, vec2Proj);
// Skip if degenerate triangle or ray parallell with triangle plane
float divisor = Vector3.Dot(vecRayProj, normalProj);
if (Math.Abs(divisor) < tol)
return false;
// Skip if exit and not configured to detect
if (divisor > tol && !m_detectExitsInCastRay)
return false;
// Skip if outside ray ends
float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor;
if (distanceProj < -tol || distanceProj > 1 + tol)
return false;
// Calculate hit position in triangle
posHitProj = pos1RayProj + vecRayProj * distanceProj;
// Skip if outside triangle bounding box
Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3);
Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3);
if (
posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol ||
posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol
)
return false;
// Skip if outside triangle
if (
Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol ||
Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol ||
Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol
)
return false;
// Return hit
return true;
}