intersectAABB method
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 );
}