intersectConvexHull method
Performs a ray/convex hull intersection test and stores the intersection point to the given 3D vector. If no intersection is detected, null is returned. The implementation is based on "Fast Ray-Convex Polyhedron Intersection" by Eric Haines, GRAPHICS GEMS II
Implementation
Vector3? intersectConvexHull(ConvexHull convexHull, Vector3 result ) {
final faces = convexHull.faces;
double tNear = - double.infinity;
double tFar = double.infinity;
for ( int i = 0, l = faces.length; i < l; i ++ ) {
final face = faces[ i ];
final plane = face.plane;
final vN = plane.distanceToPoint( origin );
final vD = plane.normal.dot( direction );
// if the origin is on the positive side of a plane (so the plane can "see" the origin) and
// the ray is turned away or parallel to the plane, there is no intersection
if ( vN > 0 && vD >= 0 ) return null;
// compute the distance from the ray’s origin to the intersection with the plane
final double t = ( vD != 0 ) ? ( - vN / vD ) : 0;
// only proceed if the distance is positive. since the ray has a direction, the intersection point
// would lie "behind" the origin with a negative distance
if ( t <= 0 ) continue;
// now categorized plane as front-facing or back-facing
if ( vD > 0 ) {
// plane faces away from the ray, so this plane is a back-face
tFar = math.min( t, tFar );
}
else {
// front-face
tNear = math.max( t, tNear );
}
if ( tNear > tFar ) {
// if tNear ever is greater than tFar, the ray must miss the convex hull
return null;
}
}
// evaluate intersection point
// always try tNear first since its the closer intersection point
if ( tNear != - double.infinity ) {
at( tNear, result );
}
else {
at( tFar, result );
}
return result;
}