When testing all potential separating axes for an AABB OBB intersection I must use the cross product of two axes.
If the cross product of the 2 axes for the 2 shapes is (0,0,0) then the intersection test fails.
For example if the y axis is the same for both the AABB and the OBB is the same then the axis will equal (0,0,0)
axis = Vector3.Cross(Vector3.UnitY, b.Axis_Y); // A1 x B1
If I then project the vertices for each shape onto this axis then the intersection test will fail.
If I say that the axis is Vector3.UnitY then the collision response is incorrect, but it is still correct for all other axes.
This is my axis test code:
public static bool TestAABBOBB(Shape3D s1, Shape3D s2, ref Contact3D contact)
{
// [Test Encompassing Spheres]
// • If the two spheres based on each shape's radius overlap then it is worth checking for collision
// • This is cheaper than testing doing a full test for collision each time
if (!TestRadiusRadius(s1, s2))
{
return false;
}
CD_AABB a = (CD_AABB)s1;
CD_OBB b = (CD_OBB)s2;
// Minimum Translation Vector parameters
float mtv_Distance = float.MaxValue; // Set current minimum distance (max float value so next value is always less)
Vector3 mtv_Axis = Vector3.Zero; // Axis along which to travel with the minimum distance
// [Axes of potential separation]
// • Each shape must be projected on these axes to test for intersection
//
// (1, 0, 0) A0
// (0, 1, 0) A1
// (0, 0, 1) A2
//
// obb.axis(0) B0
// obb.axis(1) B1
// obb.axis(2) B2
//
// (1, 0, 0) x obb.axis(0) A0 x B0
// (1, 0, 0) x obb.axis(1) A0 x B1
// (1, 0, 0) x obb.axis(2) A0 x B2
//
// (0, 1, 0) x obb.axis(0) A1 x B0
// (0, 1, 0) x obb.axis(1) A1 x B1
// (0, 1, 0) x obb.axis(2) A1 x B2
//
// (0, 0, 1) x obb.axis(0) A2 x B0
// (0, 0, 1) x obb.axis(1) A2 x B1
// (0, 0, 1) x obb.axis(2) A2 x B2
Vector3 axis = Vector3.Zero;
// For each separating axes
for (int i = 0; i < 15; ++i)
{
switch (i)
{
case 0:
axis = Vector3.UnitX; // A0
break;
case 1:
axis = Vector3.UnitY; // A1
break;
case 2:
axis = Vector3.UnitZ; // A2
break;
case 3:
axis = b.Axis_X; // B0
break;
case 4:
axis = b.Axis_Y; // B1
break;
case 5:
axis = b.Axis_Z; // B2
break;
case 6:
axis = Vector3.Cross(Vector3.UnitX, b.Axis_X); // A0 x B0
break;
case 7:
axis = Vector3.Cross(Vector3.UnitX, b.Axis_Y); // A0 x B1
break;
case 8:
axis = Vector3.Cross(Vector3.UnitX, b.Axis_Z); // A0 x B2
break;
case 9:
axis = Vector3.Cross(Vector3.UnitY, b.Axis_X); // A1 x B0
break;
case 10:
axis = Vector3.Cross(Vector3.UnitY, b.Axis_Y); // A1 x B1
break;
case 11:
axis = Vector3.Cross(Vector3.UnitY, b.Axis_Z); // A1 x B2
break;
case 12:
axis = Vector3.Cross(Vector3.UnitZ, b.Axis_X); // A2 x B0
break;
case 13:
axis = Vector3.Cross(Vector3.UnitZ, b.Axis_Y); // A2 x B1
break;
case 14:
axis = Vector3.Cross(Vector3.UnitZ, b.Axis_Z); // A2 x B2
break;
}
if (!IntersectThruAxis(axis, a, b, ref mtv_Distance, ref mtv_Axis))
{
return false;
}
}
// Calculate Minimum Translation Vector (MTV)
Vector3 d = a.Position - b.Position;
mtv_Axis = Vector3.Dot(d, mtv_Axis) < 0 ? -mtv_Axis : mtv_Axis;
contact.normal = mtv_Axis;
contact.penetration = Math.Abs(mtv_Distance) + Settings.EPSILON;
// Objects are intersecting
return true;
}
How do I deal with this scenario correctly?
Thank you.