Friday, October 9, 2015

bounding boxes - OBB vs OBB Collision Detection


Say you have two Bounding Box Objects each of them storing the current vertices of the box in a vector with all the vertices of the object rotated and translated relative to a common axis.


Here is an image to illustrate my problem:


How can I work out if the two OBB's are overlapping any links to help explain the solution to the problem would be welcome. Nothing too convoluted please...




Answer



An OBB is a convex hull. A convex hull is a 3D shape that has no "crannies" on its surface. Every "bump" (vertex) on the convex hull protrudes outward, never inward. If you slice a plane through a convex hull you will get (only one) convex polygon. If you are inside a convex hull and fire a laser pointing outward you will only punch through the hull's surface once (never twice).


The Separating Axis Theorem test can be used to detect collision of convex hulls. The SAT test is simple. It works in 2D and 3D. Although the pictures below will be in 2D, they could just as easily be applied to 3D.



This is the key concept you're using with SAT:



  • Two shapes only intersect if they have overlap when "projected" onto every normal axis of both shapes.


"Projection" of a shape onto a 1D vector looks like this (what I call "crushing")


A shape with red verts, and an axis



enter image description here


"Projecting the shape to the axis" means dropping a perpendicular from each point on the shape just to land on the axis. You can think of this as "crushing" the points by a hand that gathers everything and perpendicularly crushes it down to the axis.


enter image description here


What you're left with: Points on an axis


enter image description here



For 2 convex hulls to intersect, they have to overlap on every axis (where every normal on either shape counts as an axis we must check).


Take these 2 shapes:


enter image description here


You see they don't intersect, so lets try a few axes to show were an overlap doesn't happen.



Trying the top normal of the pentagon:


enter image description here


These are the extents. They do overlap.


enter image description here


Try left side of the rectangle. Now they do not overlap in this axis, therefore NO INTERSECTION.


enter image description here



For each face normal on both shapes:



  • Find the minimum and maximum extents (largest and smallest value) of the projection of all the vertex corner points of both shapes onto that axis


  • If they don't overlap, no intersection.


And that's really it. The code to make SAT work is very short and simple.


Here is some code that demonstrates how to do an SAT axis projection:


void SATtest( const Vector3f& axis, const vector& ptSet, float& minAlong, float& maxAlong )
{
minAlong=HUGE, maxAlong=-HUGE;
for( int i = 0 ; i < ptSet.size() ; i++ )
{
// just dot it to get the min/max along this axis.

float dotVal = ptSet[i].dot( axis ) ;
if( dotVal < minAlong ) minAlong=dotVal;
if( dotVal > maxAlong ) maxAlong=dotVal;
}
}

Calling code:


// Shape1 and Shape2 must be CONVEX HULLS
bool intersects( Shape shape1, Shape shape2 )
{

// Get the normals for one of the shapes,
for( int i = 0 ; i < shape1.normals.size() ; i++ )
{
float shape1Min, shape1Max, shape2Min, shape2Max ;
SATtest( normals[i], shape1.corners, shape1Min, shape1Max ) ;
SATtest( normals[i], shape2.corners, shape2Min, shape2Max ) ;
if( !overlaps( shape1Min, shape1Max, shape2Min, shape2Max ) )
{
return 0 ; // NO INTERSECTION
}


// otherwise, go on with the next test
}

// TEST SHAPE2.normals as well

// if overlap occurred in ALL AXES, then they do intersect
return 1 ;
}


bool overlaps( float min1, float max1, float min2, float max2 )
{
return isBetweenOrdered( min2, min1, max1 ) || isBetweenOrdered( min1, min2, max2 ) ;
}

inline bool isBetweenOrdered( float val, float lowerBound, float upperBound ) {
return lowerBound <= val && val <= upperBound ;
}

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...