MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / rayTriangleIntersect

Function rayTriangleIntersect

source/MRMesh/MRTriangleIntersection.h:365–404  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

363
364template <typename T>
365std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3<T>& oriA, const Vector3<T>& oriB, const Vector3<T>& oriC,
366 const IntersectionPrecomputes<T>& prec )
367{
368 const T& Sx = prec.Sx;
369 const T& Sy = prec.Sy;
370 const T& Sz = prec.Sz;
371
372 const T Ax = oriA[prec.idxX] - Sx * oriA[prec.maxDimIdxZ];
373 const T Ay = oriA[prec.idxY] - Sy * oriA[prec.maxDimIdxZ];
374 const T Bx = oriB[prec.idxX] - Sx * oriB[prec.maxDimIdxZ];
375 const T By = oriB[prec.idxY] - Sy * oriB[prec.maxDimIdxZ];
376 const T Cx = oriC[prec.idxX] - Sx * oriC[prec.maxDimIdxZ];
377 const T Cy = oriC[prec.idxY] - Sy * oriC[prec.maxDimIdxZ];
378
379 // due to fused multiply-add (FMA): (A*B-A*B) can be different from zero, so we need epsilon
380 const T eps = std::numeric_limits<T>::epsilon() * std::max( { Ax, Bx, Cx, Ay, By, Cy } );
381 T U = Cx * By - Cy * Bx;
382 T V = Ax * Cy - Ay * Cx;
383 T W = Bx * Ay - By * Ax;
384
385 if( U < -eps || V < -eps || W < -eps )
386 {
387 if( U > eps || V > eps || W > eps )
388 {
389 // U,V,W have clearly different signs, so the ray misses the triangle
390 return std::nullopt;
391 }
392 }
393
394 T det = U + V + W;
395 if( det == T( 0 ) )
396 return std::nullopt;
397 const T Az = Sz * oriA[prec.maxDimIdxZ];
398 const T Bz = Sz * oriB[prec.maxDimIdxZ];
399 const T Cz = Sz * oriC[prec.maxDimIdxZ];
400 const T t = U * Az + V * Bz + W * Cz;
401
402 auto invDet = T( 1 ) / det;
403 return TriIntersectResult( float( V * invDet ), float( W * invDet ), float( t * invDet ) );
404}
405
406MR_BIND_TEMPLATE( std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3<float >& oriA, const Vector3<float >& oriB, const Vector3<float >& oriC, const IntersectionPrecomputes<float >& prec ) )
407MR_BIND_TEMPLATE( std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3<double>& oriA, const Vector3<double>& oriB, const Vector3<double>& oriC, const IntersectionPrecomputes<double>& prec ) )

Callers 2

meshRayIntersect_Function · 0.85
rayMeshIntersectAll_Function · 0.85

Calls 2

maxFunction · 0.85
TriIntersectResultClass · 0.85

Tested by

no test coverage detected