Sign in to follow this  

Speculative contacts and AABB vs AABB

This topic is 2313 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been playing with speculative contacts as described by Paul here: [url="http://www.wildbunny.co.uk/blog/2011/03/25/speculative-contacts-an-continuous-collision-engine-approach-part-1/"]http://www.wildbunny...pproach-part-1/[/url]

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:

[code]

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();
}
}
[/code]

Kinda ugly but seemed to work well enough. The problem I ran into is this case:

[img]http://content.screencast.com/users/hahanoob/folders/Jing/media/4c201ce5-ca4a-4058-9ab9-95c2e638ab77/2011-08-05_1729.png[/img]


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.

Share this post


Link to post
Share on other sites
[code]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)[/code]

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

[code]if (distanceSquared <= testDistance * testDistance)
[/code]

Share this post


Link to post
Share on other sites
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:

[url="http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/"]http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/[/url]

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

Cheers, Paul.

Share this post


Link to post
Share on other sites

This topic is 2313 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this