Speculative contacts and AABB vs AABB

Started by
1 comment, last by wildbunny 12 years, 8 months ago
I've been playing with speculative contacts as described by Paul here: http://www.wildbunny...pproach-part-1/

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:

2011-08-05_1729.png


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.
[size=2]
Advertisement
separation.X = Math.Max(0, separation.X);
separation.Y = Math.Max(0, separation.Y);
separation.Z = Math.Max(0, separation.Z);
distance = Math.Sqrt(separation.X * separation.X + separation.Y * separation.Y + separation.Z * separation.Z)


naturally, if you're going to be doing a simple comparison, it's better to discard the square root, and have something like:

if (distanceSquared <= testDistance * testDistance)
Two things are infinite: the universe and human stupidity; and Im not sure about the universe. -- Albert Einstein
The distance between two AABBs can be found by expanding one AABB by the half extents of the other, and shrinking the other to a point.

Then you can use the same maths I describe in the case of circle vs AABB on this page:

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

The AABB which was shrunk to a point becomes a circle of 0 radius. :)

Cheers, Paul.

This topic is closed to new replies.

Advertisement