I\'m doing triangle to AABB intersection tests, and I\'m taking this sample code from Real-Time Collision Detection by Christer Ericson. What the author says in the boo
The reason that I was getting false positives for my tests was related to the triangle test.
To test a triangle, which is a plane in 3D space, you have to test against 4 axes(aka normals).
So in the end, to get a proper (at least it is working correctly so far) collision test between a cube and a triangle, you have to perform 7 axes tests.
Each test consists of checking the triangle and box vertices against the axis (normal). This can be broken down into a triangle and box test, and if one has a separating axis, then you don't have to do the other.
Note: This test will only give you true/false results. No other data is provided.
public static boolean testTriangleAABB( Triangle triangle,
Vector3d origin, double size ) {
setTriangleNormal( triangle.getNormal( true ) );
Vector3d[] aabbVertices = calculateAABBVertices( origin, size );
// Triangle Normal axis test, false = No Collision.
if( !testTriangleNormal( triangle, aabbVertices ) ) {
return false;
}
// Triangle Edge Normals axis test, false = No Collision.
if( !testTriangleEdgeNormals( triangle, aabbVertices ) ) {
return false;
}
// Axis-Aligned Bounding Box X, Y, Z axis test, false = No Collision.
if( !testAABBAxis( triangle, aabbVertices ) ) {
return false;
}
// if we get here then we know that every axis had overlap on it
// so we can guarantee an intersection
return true;
}
...
private static boolean testTriangleEdgeNormals( Triangle triangle, Vector3d[] aabbVertices ) {
Vector3d edge = new Vector3d();
Vector3d edgeNormal = new Vector3d();
// loop over the triangle edge normals
Vector3d[] points = triangle.getPoints();
for( int i = 0; i < points.length; i++ ) {
int iOverflow = i + 1 == points.length ? 0 : i + 1;
edge.sub( points[ i ], points[ iOverflow ] );
edge.normalize();
edgeNormal.cross( getTriangleNormal(), edge );
// project both shapes onto the axis
projectionAABB = project2D1D( aabbVertices, edgeNormal );
projectionTriangle = project2D1D( triangle.getPoints(), edgeNormal );
// do the projections overlap?
if ( !projectionAABB.hasOverlap( projectionTriangle ) ) {
// then we can guarantee that the shapes do not overlap
return false;
}
}
return true;
}
Furthermore, there is no need to calculate Axis-Aligned Bounding Box axes..since they are axis aligned the axes will be like so:
private static final Vector3d[] AABB_AXES = {
new Vector3d( -1.0, 0.0, 0.0 ),
new Vector3d( 0.0, -1.0, 0.0 ),
new Vector3d( 0.0, 0.0, -1.0 ) };
You can check my c# (almost identical to java in this case...) implantation in a game i made a little while ago. http://code.google.com/p/gotcha/source/browse/trunk/Gotcha/trunk/Gotcha/Gotcha/GameEnteties/GameEntity.cs#171
Look for the method : IsSATCollision
Think about the parameter it accepts as just something that has vertices for simplicity.