intersectConvexHull method

Vector3? intersectConvexHull(
  1. ConvexHull convexHull,
  2. Vector3 result
)

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;
}