Created
December 10, 2015 10:47
-
-
Save anonymous/8bb64b0556fecd13769f to your computer and use it in GitHub Desktop.
Swept AABB Collisions C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static bool TestAABBSweep(Vector2 extents1, Vector2 centre1, Vector2 velocity1, Vector2 extents2, Vector2 centre2, Vector2 velocity2, out float t0, out float t1) | |
{ | |
var aabb1 = new AABB(centre1, extents1); | |
var aabb2 = new AABB(centre2, extents2); | |
//Check if the boxes are currently overlapping | |
if (aabb1.Overlaps(aabb2)) | |
{ | |
t0 = t1 = 0; | |
return true; | |
} | |
//The problem is solved in A's frame of reference so get relative velocity (in normalized time) | |
var relativeVelocity = velocity2 - velocity1; | |
//First and last time of overlap along each axis | |
var firstOverlapTime = new Vector2(float.MinValue); | |
var lastOverlapTime = new Vector2(float.MaxValue); | |
var overlapX = false; | |
var overlapY = false; | |
//Find the first possible times of overlap... | |
if (relativeVelocity.X < 0) | |
{ | |
if (aabb1.MinX < aabb2.MaxX) | |
{ | |
overlapX = true; | |
firstOverlapTime.X = (aabb1.MaxX - aabb2.MinX) / relativeVelocity.X; | |
} | |
} | |
else if (relativeVelocity.X > 0) | |
{ | |
if (aabb2.MinX < aabb1.MaxX) | |
{ | |
overlapX = true; | |
firstOverlapTime.X = (aabb1.MinX - aabb2.MaxX) / relativeVelocity.X; | |
} | |
} | |
else if (aabb1.MinX <= aabb2.MaxX && aabb1.MaxX >= aabb2.MinX) | |
{ | |
overlapX = true; | |
firstOverlapTime.X = 0.0f; | |
lastOverlapTime.X = 1.0f; | |
} | |
if (relativeVelocity.Y < 0) | |
{ | |
if (aabb1.MinY < aabb2.MaxY) | |
{ | |
overlapY = true; | |
firstOverlapTime.Y = (aabb1.MaxY - aabb2.MinY) / relativeVelocity.Y; | |
} | |
} | |
else if (relativeVelocity.Y > 0) | |
{ | |
if (aabb2.MinY < aabb1.MaxY) | |
{ | |
overlapY = true; | |
firstOverlapTime.Y = (aabb1.MinY - aabb2.MaxY) / relativeVelocity.Y; | |
} | |
} | |
else if (aabb1.MinY <= aabb2.MaxY && aabb1.MaxY >= aabb2.MinY) | |
{ | |
overlapY = true; | |
firstOverlapTime.Y = 0.0f; | |
lastOverlapTime.Y = 1.0f; | |
} | |
//...and the last possible time of overlap | |
if (aabb2.MaxX > aabb1.MinX && relativeVelocity.X < 0) | |
lastOverlapTime.X = (aabb1.MinX - aabb2.MaxX) / relativeVelocity.X; | |
else if (aabb1.MaxX > aabb2.MinX && relativeVelocity.X > 0) | |
lastOverlapTime.X = (aabb1.MaxX - aabb2.MinX) / relativeVelocity.X; | |
if (aabb2.MaxY > aabb1.MinY && relativeVelocity.Y < 0) | |
lastOverlapTime.Y = (aabb1.MinY - aabb2.MaxY) / relativeVelocity.Y; | |
else if (aabb1.MaxY > aabb2.MinY && relativeVelocity.Y > 0) | |
lastOverlapTime.Y = (aabb1.MaxY - aabb2.MinY) / relativeVelocity.Y; | |
if (overlapX == false || overlapY == false) | |
{ | |
t0 = t1 = 0; | |
return false; | |
} | |
//Possible first time of overlap is the largest of the axis values | |
t0 = Math.Max(firstOverlapTime.X, firstOverlapTime.Y); | |
//So then the possible last time of overlap is the smallest of the overlaps values | |
t1 = Math.Min(lastOverlapTime.X, lastOverlapTime.Y); | |
//They could have only collided if the first time of overlap occurred before the last time of overlap | |
return t0 >= 0 && t0 <= 1 && t0 <= t1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment