• Create Account

Banner advertising on our site currently available from just \$5!

# Speculative contacts and AABB vs AABB

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

2 replies to this topic

### #1wild_pointer  Members   -  Reputation: 230

Like
0Likes
Like

Posted 05 August 2011 - 03:42 PM

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:

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.

### #2coder0xff  Members   -  Reputation: 225

Like
0Likes
Like

Posted 08 August 2011 - 06:51 PM

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

### #3wildbunny  Members   -  Reputation: 550

Like
1Likes
Like

Posted 12 August 2011 - 09:08 AM

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.

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS