intersectAABB method

Vector3? intersectAABB(
  1. AABB aabb,
  2. Vector3 result
)

Performs a ray/AABB intersection test and stores the intersection point to the given 3D vector. If no intersection is detected, null is returned.

Implementation

Vector3? intersectAABB(AABB aabb, Vector3 result ) {
	double tmin, tmax, tymin, tymax, tzmin, tzmax;

	final invdirx = 1 / direction.x,
		invdiry = 1 / direction.y,
		invdirz = 1 / direction.z;

	final origin = this.origin;

	if ( invdirx >= 0 ) {
		tmin = ( aabb.min.x - origin.x ) * invdirx;
		tmax = ( aabb.max.x - origin.x ) * invdirx;
	}
    else {
		tmin = ( aabb.max.x - origin.x ) * invdirx;
		tmax = ( aabb.min.x - origin.x ) * invdirx;
	}

	if ( invdiry >= 0 ) {
		tymin = ( aabb.min.y - origin.y ) * invdiry;
		tymax = ( aabb.max.y - origin.y ) * invdiry;
	}
    else {
		tymin = ( aabb.max.y - origin.y ) * invdiry;
		tymax = ( aabb.min.y - origin.y ) * invdiry;
	}

	if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;

	// these lines also handle the case where tmin or tmax is NaN
	// (result of 0 * double.infinity). x !== x returns true if x is NaN

	if ( tymin > tmin || tmin != tmin ) tmin = tymin;

	if ( tymax < tmax || tmax != tmax ) tmax = tymax;

	if ( invdirz >= 0 ) {
		tzmin = ( aabb.min.z - origin.z ) * invdirz;
		tzmax = ( aabb.max.z - origin.z ) * invdirz;
	}
    else {
		tzmin = ( aabb.max.z - origin.z ) * invdirz;
		tzmax = ( aabb.min.z - origin.z ) * invdirz;
	}

	if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;

	if ( tzmin > tmin || tmin != tmin ) tmin = tzmin;

	if ( tzmax < tmax || tmax != tmax ) tmax = tzmax;

	// return point closest to the ray (positive side)

	if ( tmax < 0 ) return null;

	return at( tmin >= 0 ? tmin : tmax, result );
}