I've been learning a bit of collision resolution through a tutorial here and I can't seem to get the AABBvsAABB resolution working, I have CirclevsCircle and AABBvsCircle resolution working with the same method,ResolveCollision
Essentially what happens is I have a test scenario where two AABBs collide with each other. The collision gets detected however, the AABBs will just keep going through each other. If two circles collide, they show the correct response.
If you need the full code you can nab it from my github. This has both Windows and Linux versions.
Here is the data class that is passed to the AABBvsAABB
method:
public struct Manifold
{
public PhysicsObject A, B;
public float PenetrationDepth;
public Vector2 Normal;
public bool AreColliding;
}
Here is the code for testing the collision between the AABB and AABB
public static bool AABBvsAABB (AABB a, AABB b, ref Manifold m)
{
m.A = a;
m.B = b;
m.Normal = b.Position - a.Position;
//Calculate the extent on the X axis
float aExtent = (a.Right - a.Left) / 2;
float bExtent = (b.Right - b.Left) / 2;
//Find the X overlap
float xExtent = aExtent + bExtent - Math.Abs (m.Normal.X);
//SAT Test on X
if (xExtent > 0) {
//There was overlap on the X axis, now lets try to Y
aExtent = (a.Bottom - a.Top) / 2;
bExtent = (b.Bottom - b.Top) / 2;
//Calculate Y overlap
float yExtent = aExtent + bExtent - Math.Abs(m.Normal.Y);
//SAT Test on Y axis
if (yExtent > 0){
//Find which axis has the biggest penetration ;D
if (xExtent > yExtent){
if(m.Normal.X < 0)
m.Normal = new Vector2(-1,0);
else
m.Normal= Vector2.Zero;
m.PenetrationDepth = xExtent;
m.AreColliding = true;
return true;
}
else {
if(m.Normal.Y < 0)
m.Normal = new Vector2(0,-1);
else
m.Normal= Vector2.Zero;
m.PenetrationDepth = yExtent;
m.AreColliding = true;
return true;
}
}
}
return false;
}
Lastly here is the ResolveCollision
Method.
public static void ResolveCollision(Manifold m)
{
Vector2 relVelocity = m.B.Velocity - m.A.Velocity;
//Finds out if the objects are moving towards each other.
//We only need to resolve collisions that are moving towards, not away.
float velAlongNormal = PhysicsMath.DotProduct(relVelocity, m.Normal);
if (velAlongNormal > 0)
return;
float e = Math.Min(m.A.Restitution, m.B.Restitution);
float j = -(1 + e)*velAlongNormal;
j /= m.A.InvertedMass + m.B.InvertedMass;
Vector2 impulse = j*m.Normal;
m.A.Velocity -= m.A.InvertedMass*impulse;
m.B.Velocity += m.B.InvertedMass*impulse;
}