   Testing Swept Axis. How can a collision normal of (0,0,0) be avoided properly?
  If I am testing all axes of separation using the following swept test:  if (axis.LengthSquared() < Math_Util.EPSILON * Math_Util.EPSILON)  { return true; // This causes nEnter of (0,0,0)?  }  // Intervals along the axis  float minA = float.MaxValue;  float minB = float.MaxValue;  float maxA = float.MinValue;  float maxB = float.MinValue;  float speed = Vector3.Dot(axis, velocityRelative);  a.CalculateSlab(axis, ref minA, ref maxA);  b.CalculateSlab(axis, ref minB, ref maxB);  if (speed < 0.0f)  { if (maxB < minA) {return false; } if (maxA < minB) {float t0 = (maxA - minB) / speed;if (t0 > tEnter){    tEnter = t0;    nEnter = -axis;} } if (maxB > minA) {float t1 = (minA - maxB) / speed;if (t1 < tExit){    tExit = t1;    nExit = axis;} }  }  if (speed > 0.0f)  { if (minB > maxA) {return false; } if (maxB < minA) {float t0 = (minA - maxB) / speed;if (t0 > tEnter){    tEnter = t0;    nEnter = axis;} } if (maxA > minB) {float t1 = (maxA - minB) / speed;if (t1 < tExit){    tExit = t1;    nExit = -axis;} }  }  if (tEnter > tExit)  { return false;  }  return true;and nEnter is initialised to (0,0,0):  Vector3 nEnter = Vector3.Zero;  Vector3 nExit = Vector3.Zero;  float tEnter = 0.0f;  float tExit = 1.0f;  Vector3 velocityRelative = b.Velocity - a.Velocity; What causes nEnter (collision normal) to remain at (0,0,0) when all axes tested have returned positive for the above test?Is there any way this can be avoided?   
  looks like there is no case to handle when your boxes are intersecting, and then setup the enter time and normal. ;  I've tried that with the complete method:   private static bool TestAABBTriangleSwept(Shape3D s1, Shape3D s2, ref Contact3D contact)   {  CD_AABB a = (CD_AABB)s1;  CD_Triangle b = (CD_Triangle)s2;  Vector3 nEnter = Vector3.Zero;  Vector3 nExit = Vector3.Zero;  float tEnter = 0.0f;  float tExit = 1.0f;  Vector3 velocityRelative = a.Velocity - b.Velocity;  // [Axes of potential separation]  // N  if (!TestAxis(b.Normal, ref a, ref b, ref velocityRelative, ref nEnter, ref nExit, ref tEnter, ref tExit))  { return false;  }  // A0, A1, A2  for (int i = 0; i < 3; ++i)  { if (!TestAxis(a.Axes, ref a, ref b, ref velocityRelative, ref nEnter, ref nExit, ref tEnter, ref tExit)) {return false; }  }  // A0 x E0, A0 x E1, A0 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = 0.0f; axis.Y = -b.Edges.Z; axis.Z = b.Edges.Y; if (!TestAxis(axis, ref a, ref b, ref velocityRelative, ref nEnter, ref nExit, ref tEnter, ref tExit)) {return false; }  }  // A1 x E0, A1 x E1, A1 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = b.Edges.Z; axis.Y = 0.0f; axis.Z = -b.Edges.X; if (!TestAxis(axis, ref a, ref b, ref velocityRelative, ref nEnter, ref nExit, ref tEnter, ref tExit)) {return false; }  }  // A2 x E0, A2 x E1, A2 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = -b.Edges.Y; axis.Y = b.Edges.X; axis.Z = 0.0f; if (!TestAxis(axis, ref a, ref b, ref velocityRelative, ref nEnter, ref nExit, ref tEnter, ref tExit)) {return false; }  }  if (nEnter == Vector3.Zero)  { return TestAABBTriangle(s1, s2, ref contact);  }  contact.isColliding = true;  contact.nEnter = Vector3.Normalize(nEnter);  contact.tEnter = tEnter;  contact.nExit = Vector3.Normalize(nExit);  contact.tExit = tExit;  return true;   }The main difference being that I test for intersection if nEnter is (0,0,0): if (nEnter == Vector3.Zero)  { return TestAABBTriangle(s1, s2, ref contact);  }The problem is that this still returns as nEnter as (0,0,0) and penetration depth of 0.The code for intersection test is as follows:   private static bool TestAABBTriangle(Shape3D s1, Shape3D s2, ref Contact3D contact)   {  CD_AABB a = (CD_AABB)s1;  CD_Triangle b = (CD_Triangle)s2;  // Minimum Translation Vector parameters  float mtv_Distance = float.MaxValue;  // Set current minimum distance (max float value so next value is always less)  Vector3 mtv_Axis = Vector3.Zero; // Axis along which to travel with the minimum distance  // [Axes of potential separation]  // N  if (!TestAxisStatic(b.Normal, a, b, ref mtv_Axis, ref mtv_Distance))  { return false;  }  // A0, A1, A2  for (int i = 0; i < 3; ++i)  { if (!TestAxisStatic(a.Axes, a, b, ref mtv_Axis, ref mtv_Distance)) {return false; }  }  // A0 x E0, A0 x E1, A0 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = 0; axis.Y = -b.Edges.Z; axis.Z = b.Edges.Y; if (!TestAxisStatic(axis, a, b, ref mtv_Axis, ref mtv_Distance)) {return false; }  }  // A1 x E0, A1 x E1, A1 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = b.Edges.Z; axis.Y = 0; axis.Z = -b.Edges.X; if (!TestAxisStatic(axis, a, b, ref mtv_Axis, ref mtv_Distance)) {return false; }  }  // A2 x E0, A2 x E1, A2 x E2  for (int i = 0; i < 3; ++i)  { Vector3 axis = new Vector3(); axis.X = -b.Edges.Y; axis.Y = b.Edges.X; axis.Z = 0; if (!TestAxisStatic(axis, a, b, ref mtv_Axis, ref mtv_Distance)) {return false; }  }  contact.isIntersecting = true;  // Calculate Minimum Translation Vector (MTV) [normal * penetration]  contact.nEnter = Vector3.Normalize(mtv_Axis);  // Multiply the penetration depth by itself plus a small increment  // When the penetration is resolved using the MTV, it will no longer intersect  contact.penetration = (float)Math.Sqrt(mtv_Distance) * 1.001f;  // Objects are intersecting  return true;   }I still don't understand how both tests can return true and yet nEnter = (0,0,0)?When performing just the static test, there are no such errors.  It only occurs when using it in combination with the swept test.   ;Jon Shafer, lead designer on Firaxis' Civilization V, is now at Galactic Civilizations developer Stardock. Here, he explains his move from a major publisher to a small independent studio, his reaction to fan criticism for the well-reviewed Civ V and why he never felt he was living in the shadow of Sid Meier.  View the full article