My game world is made up mostly of AABBs which I use as tiles. The speculative contacts require that I supply a positive "penetration distance" to the contact solver so collisions can be dealt with before they're actually solved. To do this in the AABB vs AABB case, I just kinda adapted the normal overlap test:
public void Collide(Vector3 position, Shape otherShape, Vector3 otherPosition, ref List<Contact> contacts)
{
if (otherShape is AABB)
{
AABB otherAABB = (AABB)otherShape;
Vector3 displacement = position - otherPosition;
Vector3 seperation = Utils.Abs(displacement) - (HalfWidth + otherAABB.HalfWidth);
bool overlapping = seperation.X < 0 && seperation.Y < 0 && seperation.Z < 0;
if (seperation.X >= seperation.Y && seperation.X >= seperation.Z)
{
contacts.Add(new Contact(displacement.X > 0 ? Vector3.UnitX : -Vector3.UnitX, overlapping ? -seperation.X : seperation.X, seperation));
}
else if (seperation.Y >= seperation.X && seperation.Y >= seperation.Z)
{
contacts.Add(new Contact(displacement.Y > 0 ? Vector3.UnitY : -Vector3.UnitY, overlapping ? -seperation.Y : seperation.Y, seperation));
}
else if (seperation.Z >= seperation.X && seperation.Z >= seperation.Y)
{
contacts.Add(new Contact(displacement.Z > 0 ? Vector3.UnitZ : -Vector3.UnitZ, overlapping ? -seperation.Z : seperation.Z, seperation));
}
}
else
{
throw new NotImplementedException();
}
}
Kinda ugly but seemed to work well enough. The problem I ran into is this case:
The red arrow represents the blocks velocity. The rest are static (my ground). In this case, the penetration in X and Y are equal so my logic above will just select the first case and a contact will be created along the X-axis with distance = 0. That is.. not quite right. I kinda hacked around this by just throwing away contacts that have 2 or more components of the penetration = 0 but obviously that's not right either.
The problem seems to be that my distance check is completely wrong in the case where they are not overlapping as checking the distance along each axis like I'm doing is only really works when they overlap on at least one of those axes. Unfortunately, it seems finding the distance between 2 AABB is a fairly uncommon operation since google isn't much help. I think the minimum amount of work I would need to do is to find the distance between each point on 1 aabb and each face on the other?
I think I'm mostly looking for a sanity check before I go forward, so any thoughts would be appreciated.