I'm using the IntersectMovingAABBAABB
implementation from the book Realtime Collision Detection
and I'm having a little bit of an issue. When I have two AABBs next to each other (not touching), A being stationnary and B moving up or down, I'm getting a result saying there's a collision. Obviously this is wrong.
_______ _______
| | | |
| A | | B | B moving up/down
|_______| |_______|
I've rechecked my code multiple times to make sure I had the same thing as in the book. Stepping through the code, I realized that the check for v[i] < 0
and v[i] > 0
will never be true for either X or Z axis when moving straight up or down. Therefor, no checks for intersections on these axis will be done. I find that quite weird, and I was wondering if I was missing something, or if this code is simply bad.
Here's my implementation for reference:
public static bool IntersectMovingAABBAABB(AABB a, AABB b, Vector3 va, Vector3 vb, out float first, out float last, out BlockFace face)
{
face = BlockFace.None;
if (TestAABB(a, b))
{
first = last = 0;
return true;
}
Vector3 v = vb - va;
float current;
first = 0;
last = 1;
for (int i = 0; i < 3; i++)
{
if (v[i] < 0)
{
if (b.Max[i] < a.Min[i]) return false;
if (a.Max[i] < b.Min[i]) if ((first = Math.Max(current= (a.Max[i] - b.Min[i]) / v[i], first)) == current) face = (BlockFace)(1 << (i));
if (b.Max[i] > a.Min[i]) last = Math.Min((a.Min[i] - b.Max[i]) / v[i], last);
}
if (v[i] > 0)
{
if (a.Max[i] < b.Min[i]) return false;
if (b.Max[i] < a.Min[i]) if ((first = Math.Max(current = (a.Min[i] - b.Max[i]) / v[i], first)) == current) face = (BlockFace)(1 << (i + 3));
if (a.Max[i] > b.Min[i]) last = Math.Min((a.Max[i] - b.Min[i]) / v[i], last);
}
if (first > last) return false;
}
return true;
}