# 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...

-

Take a look at SAT (Separating Axis Theorem):

-
The codezealot example is good, but it fails to explain how to deal with the situation in `Figure 6`; where all projected axii (from edges) overlap, yet the shapes do not collide. The axii perpendicular to those edges must also be tested. This case is also shown in the AABB v Triangle example on this page: metanetsoftware.com/technique/tutorialA.html. – dcousens Mar 12 '12 at 14:50
What? I don't see any axes overlapping in figure 6, and the AABB vs Triangle one just has some overlapping. What do you mean? – TravisG Mar 12 '12 at 22:19
@Heishe, in Figure 6 (codezealot.org/post/images/sat-ex-2.png), every axis parallel to an edge in that picture is overlapping. The only axis that is not overlapping, is one that is perpendicular to an edge (the triangles hypotenuse in this case). – dcousens Mar 13 '12 at 2:18
Oh, yes. Now I see what you mean. But I was under the impression that you always only test axes which are perpendicular to the edges with the algorithm anyways. At least that's how I did it until now. – TravisG Mar 13 '12 at 9:33

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.

# Concept

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

"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.

What you're left with: Points on an axis

# SAT says:

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:

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:

These are the extents. They do overlap.

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

# Algorithm:

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<Vector3f>& 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 ;
}
``````
-
Hullinator implements the SAT test for convex hulls – bobobobo Aug 8 '13 at 1:47
awesome explanation! thanks. I think you may have a typo in the line: "so lets try a few axes to show were an overlap doesn't happen.", because then you proceed to give examples where they do overlap. thanks again! – JoeRocc Sep 12 '15 at 13:56

You should definitely look up Separating Axis Theorem. It's for convex objects. There is a rule: "If two convex objects don't intersect, then there is a plane where the projection of these two objects will not intersect".

You can find some examples on the wiki. But it's a little more complicated than for your case.

Something more suitable for your problem can be found here (two cars colliding).

-

More SAT articles.

The last article on this site comes with complete code, i think it's in FLASH, i've no idea, but i had exactly 0 issues converting it to C++ when i had to use SAT for the first time, shouldn't be hard to do the same for other languages. The only thing you'll have to add is storing of the displacement vector on each calculation (if it's the smallest, ofcourse, you'll understand this when you learn about SAT), the code in this tutorial doesn't do it, so you end up with the last calculated vector.

http://rocketmandevelopment.com/tag/separation-axis-theorem/

Good, old N-Game tutorials. Best SAT theory on the web.

http://www.metanetsoftware.com/technique/tutorialA.html

-
It's so irritating no one posts the full working source with all the required classes. I ported his code over into a demo of my own but it just doesn't work. :( This is my project so far if anyone could help me debug it that would be great. link – SyntheCypher Mar 13 '12 at 10:35
what do you mean it doesn't work? pay attention to how you're storing your vertices, in the image you have them in a cartesian coordinate system, in the tutorial he stores the vertices as vectors relative to the centroid (all you have to do is subtract centroid from your own vertices or remove the lines where he modifies his own vertices), functions like dot product you can create yourself, you don't need a guide for those, rest should be straight forward, it's not a copy paste material, learn SAT before trying to implement it – dreta Mar 13 '12 at 12:11
This is how I've implemented it: SAT.as, Shape2D.as, What do you mean by centroid? The centre of the polygon such as (x, y)? – SyntheCypher Mar 13 '12 at 13:03
At the moment I have a function getOBB() which returns vertices as detailed in my original image. This is calculated from the a Vector<b2Vec2> containing the vertices of the shape, a angle variable, and a position variable. – SyntheCypher Mar 13 '12 at 13:07
yes, the center, the way this guy creates his polygons is by giving offsets from the center, idk AS3, but from what i see you project your vertices as they are, when calculating dot product try to subtract centroid from the vertices (vector subraction), beside this you aren't checking which separation vector is the smallest still, you only store the last one calculated – dreta Mar 13 '12 at 17:27