intersectsOBB method

bool intersectsOBB(
  1. OBB obb, [
  2. double epsilon = MathUtils.epsilon
])

Returns true if the given OBB intersects this OBB.

Reference: OBB-OBB Intersection in Real-Time Collision Detection by Christer Ericson (chapter 4.4.1)

Implementation

bool intersectsOBB(OBB obb, [double epsilon = MathUtils.epsilon] ) {
	// prepare data structures (the code uses the same nomenclature like the reference)
	a['c'] = center;
	a['e'][ 0 ] = halfSizes.x;
	a['e'][ 1 ] = halfSizes.y;
	a['e'][ 2 ] = halfSizes.z;
	rotation.extractBasis( a['u'][ 0 ], a['u'][ 1 ], a['u'][ 2 ] );

	b['c'] = obb.center;
	b['e'][ 0 ] = obb.halfSizes.x;
	b['e'][ 1 ] = obb.halfSizes.y;
	b['e'][ 2 ] = obb.halfSizes.z;
	obb.rotation.extractBasis( b['u'][ 0 ], b['u'][ 1 ], b['u'][ 2 ] );

	// compute rotation matrix expressing b in a’s coordinate frame
	for ( int i = 0; i < 3; i ++ ) {
		for ( int j = 0; j < 3; j ++ ) {
			R[ i ][ j ] = a['u'][ i ].dot( b['u'][ j ] );
		}
	}

	// compute translation vector
	_v1.subVectors( b['c'], a['c'] );

	// bring translation into a’s coordinate frame
	t[ 0 ] = _v1.dot( a['u'][ 0 ] );
	t[ 1 ] = _v1.dot( a['u'][ 1 ] );
	t[ 2 ] = _v1.dot( a['u'][ 2 ] );

	// compute common subexpressions. Add in an epsilon term to
	// counteract arithmetic errors when two edges are parallel and
	// their cross product is (near) null

	for ( int i = 0; i < 3; i ++ ) {
		for ( int j = 0; j < 3; j ++ ) {
			absR[i][j] = R[i][j].abs() + epsilon;
		}
	}

	double ra, rb;

	// test axes L = A0, L = A1, L = A2
	for ( int i = 0; i < 3; i ++ ) {
		ra = a['e'][ i ];
		rb = b['e'][ 0 ] * absR[ i ][ 0 ] + b['e'][ 1 ] * absR[ i ][ 1 ] + b['e'][ 2 ] * absR[ i ][ 2 ];
		if ( t[ i ].abs() > ra + rb ) return false;
	}

	// test axes L = B0, L = B1, L = B2

	for ( int i = 0; i < 3; i ++ ) {
		ra = a['e'][ 0 ] * absR[ 0 ][ i ] + a['e'][ 1 ] * absR[ 1 ][ i ] + a['e'][ 2 ] * absR[ 2 ][ i ];
		rb = b['e'][ i ];
		if ( ( t[ 0 ] * R[ 0 ][ i ] + t[ 1 ] * R[ 1 ][ i ] + t[ 2 ] * R[ 2 ][ i ] ).abs() > ra + rb ) return false;
	}

	// test axis L = A0 x B0

	ra = a['e'][ 1 ] * absR[ 2 ][ 0 ] + a['e'][ 2 ] * absR[ 1 ][ 0 ];
	rb = b['e'][ 1 ] * absR[ 0 ][ 2 ] + b['e'][ 2 ] * absR[ 0 ][ 1 ];
	if ( ( t[ 2 ] * R[ 1 ][ 0 ] - t[ 1 ] * R[ 2 ][ 0 ] ).abs() > ra + rb ) return false;

	// test axis L = A0 x B1

	ra = a['e'][ 1 ] * absR[ 2 ][ 1 ] + a['e'][ 2 ] * absR[ 1 ][ 1 ];
	rb = b['e'][ 0 ] * absR[ 0 ][ 2 ] + b['e'][ 2 ] * absR[ 0 ][ 0 ];
	if ( ( t[ 2 ] * R[ 1 ][ 1 ] - t[ 1 ] * R[ 2 ][ 1 ] ).abs() > ra + rb ) return false;

	// test axis L = A0 x B2

	ra = a['e'][ 1 ] * absR[ 2 ][ 2 ] + a['e'][ 2 ] * absR[ 1 ][ 2 ];
	rb = b['e'][ 0 ] * absR[ 0 ][ 1 ] + b['e'][ 1 ] * absR[ 0 ][ 0 ];
	if ( ( t[ 2 ] * R[ 1 ][ 2 ] - t[ 1 ] * R[ 2 ][ 2 ] ).abs() > ra + rb ) return false;

	// test axis L = A1 x B0

	ra = a['e'][ 0 ] * absR[ 2 ][ 0 ] + a['e'][ 2 ] * absR[ 0 ][ 0 ];
	rb = b['e'][ 1 ] * absR[ 1 ][ 2 ] + b['e'][ 2 ] * absR[ 1 ][ 1 ];
	if ( ( t[ 0 ] * R[ 2 ][ 0 ] - t[ 2 ] * R[ 0 ][ 0 ] ).abs() > ra + rb ) return false;

	// test axis L = A1 x B1

	ra = a['e'][ 0 ] * absR[ 2 ][ 1 ] + a['e'][ 2 ] * absR[ 0 ][ 1 ];
	rb = b['e'][ 0 ] * absR[ 1 ][ 2 ] + b['e'][ 2 ] * absR[ 1 ][ 0 ];
	if ( ( t[ 0 ] * R[ 2 ][ 1 ] - t[ 2 ] * R[ 0 ][ 1 ] ).abs() > ra + rb ) return false;

	// test axis L = A1 x B2

	ra = a['e'][ 0 ] * absR[ 2 ][ 2 ] + a['e'][ 2 ] * absR[ 0 ][ 2 ];
	rb = b['e'][ 0 ] * absR[ 1 ][ 1 ] + b['e'][ 1 ] * absR[ 1 ][ 0 ];
	if ( ( t[ 0 ] * R[ 2 ][ 2 ] - t[ 2 ] * R[ 0 ][ 2 ] ).abs() > ra + rb ) return false;

	// test axis L = A2 x B0

	ra = a['e'][ 0 ] * absR[ 1 ][ 0 ] + a['e'][ 1 ] * absR[ 0 ][ 0 ];
	rb = b['e'][ 1 ] * absR[ 2 ][ 2 ] + b['e'][ 2 ] * absR[ 2 ][ 1 ];
	if ( ( t[ 1 ] * R[ 0 ][ 0 ] - t[ 0 ] * R[ 1 ][ 0 ] ).abs() > ra + rb ) return false;

	// test axis L = A2 x B1

	ra = a['e'][ 0 ] * absR[ 1 ][ 1 ] + a['e'][ 1 ] * absR[ 0 ][ 1 ];
	rb = b['e'][ 0 ] * absR[ 2 ][ 2 ] + b['e'][ 2 ] * absR[ 2 ][ 0 ];
	if ( ( t[ 1 ] * R[ 0 ][ 1 ] - t[ 0 ] * R[ 1 ][ 1 ] ).abs() > ra + rb ) return false;

	// test axis L = A2 x B2

	ra = a['e'][ 0 ] * absR[ 1 ][ 2 ] + a['e'][ 1 ] * absR[ 0 ][ 2 ];
	rb = b['e'][ 0 ] * absR[ 2 ][ 1 ] + b['e'][ 1 ] * absR[ 2 ][ 0 ];
	if ( ( t[ 1 ] * R[ 0 ][ 2 ] - t[ 0 ] * R[ 1 ][ 2 ] ).abs() > ra + rb ) return false;

	// since no separating axis is found, the OBBs must be intersecting

	return true;

}