public static bool getAABBAABBCollision(Shape s1, Shape s2) { // Safe type conversion AxisAlignedBox aabb1 = (AxisAlignedBox)s1; AxisAlignedBox aabb2 = (AxisAlignedBox)s2; // Collision test (axis separating theorem) return aabb1.max.X > aabb2.min.X && aabb1.min.X < aabb2.max.X && aabb1.max.Y > aabb2.min.Y && aabb1.min.Y < aabb2.max.Y && aabb1.max.Z > aabb2.min.Z && aabb1.min.Z < aabb2.max.Z; }
public static bool getSphereSphereCollision(Shape s1, Shape s2) { // Safe type conversion Sphere sphere1 = (Sphere)s1; Sphere sphere2 = (Sphere)s2; // Collision test return (sphere1.center - sphere2.center).LengthSquared() <= (sphere1.radius + sphere2.radius) * (sphere1.radius + sphere2.radius); }
public static void addCollisionTest(Shape.Type t1, Shape.Type t2, CollisionTest test) { collisionTests[new KeyValuePair<Type, Type>(t1, t2)] = new CollisionTest(test); }
public static bool getSphereOBBCollision(Shape s1, Shape s2) { return false; }
public static bool getSphereAABBCollision(Shape s1, Shape s2) { Sphere sphere; AxisAlignedBox aabb; // Safe type conversion if (s1.type == Shape.Type.Sphere) { sphere = (Sphere)s1; aabb = (AxisAlignedBox)s2; } else { sphere = (Sphere)s2; aabb = (AxisAlignedBox)s1; } // Test float s = 0.0f; float d = 0.0f; // Check if the sphere is inside the AABB bool centerInsideAABB = (sphere.center.X <= aabb.max.X && sphere.center.X <= aabb.min.X && sphere.center.Y <= aabb.max.Y && sphere.center.Y <= aabb.min.Y && sphere.center.Z <= aabb.max.Z && sphere.center.Z <= aabb.min.Z); if (centerInsideAABB) { return true; } // Check if the sphere and the AABB intersect if (sphere.center.X < aabb.min.X) { s = sphere.center.X - aabb.min.X; d += s * s; } else if (sphere.center.X > aabb.max.X) { s = sphere.center.X - aabb.max.X; d += s * s; } if (sphere.center.Y < aabb.min.Y) { s = sphere.center.Y - aabb.min.Y; d += s * s; } else if (sphere.center.Y > aabb.max.Y) { s = sphere.center.Y - aabb.max.Y; d += s * s; } if (sphere.center.Z < aabb.min.Z) { s = sphere.center.Z - aabb.min.Z; d += s * s; } else if (sphere.center.Z > aabb.max.Z) { s = sphere.center.Z - aabb.max.Z; d += s * s; } return d <= sphere.radius * sphere.radius; }
public static bool getOBBOBBCollision(Shape s1, Shape s2) { OrientedBox o1 = (OrientedBox)s1; OrientedBox o2 = (OrientedBox)s2; // Matrix to transform other OBB into my reference to allow me to be treated as an AABB Matrix toMe = o2.transform * Matrix.Invert(o1.transform); Vector3 centerOther = Utility.Multiply(o2.center, toMe); Vector3 extentsOther = o2.extent; Vector3 separation = centerOther - o1.center; Matrix3 rotations = new Matrix3(toMe); Matrix3 absRotations = Utility.Abs(rotations); float r, r0, r1, r01; //--- Test case 1 - X axis r = Math.Abs(separation.X); r1 = Vector3.Dot(extentsOther, absRotations.Column(0)); r01 = o1.extent.X + r1; if (r > r01) return false; //--- Test case 1 - Y axis r = Math.Abs(separation.Y); r1 = Vector3.Dot(extentsOther, absRotations.Column(1)); r01 = o1.extent.Y + r1; if (r > r01) return false; //--- Test case 1 - Z axis r = Math.Abs(separation.Z); r1 = Vector3.Dot(extentsOther, absRotations.Column(2)); r01 = o1.extent.Z + r1; if (r > r01) return false; //--- Test case 2 - X axis r = Math.Abs(Vector3.Dot(rotations.Row(0), separation)); r0 = Vector3.Dot(o1.extent, absRotations.Row(0)); r01 = r0 + extentsOther.X; if (r > r01) return false; //--- Test case 2 - Y axis r = Math.Abs(Vector3.Dot(rotations.Row(1), separation)); r0 = Vector3.Dot(o1.extent, absRotations.Row(1)); r01 = r0 + extentsOther.Y; if (r > r01) return false; //--- Test case 2 - Z axis r = Math.Abs(Vector3.Dot(rotations.Row(2), separation)); r0 = Vector3.Dot(o1.extent, absRotations.Row(2)); r01 = r0 + extentsOther.Z; if (r > r01) return false; //--- Test case 3 # 1 r = Math.Abs(separation.Z * rotations[0, 1] - separation.Y * rotations[0, 2]); r0 = o1.extent.Y * absRotations[0, 2] + o1.extent.Z * absRotations[0, 1]; r1 = extentsOther.Y * absRotations[2, 0] + extentsOther.Z * absRotations[1, 0]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 2 r = Math.Abs(separation.Z * rotations[1, 1] - separation.Y * rotations[1, 2]); r0 = o1.extent.Y * absRotations[1, 2] + o1.extent.Z * absRotations[1, 1]; r1 = extentsOther.X * absRotations[2, 0] + extentsOther.Z * absRotations[0, 0]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 3 r = Math.Abs(separation.Z * rotations[2, 1] - separation.Y * rotations[2, 2]); r0 = o1.extent.Y * absRotations[2, 2] + o1.extent.Z * absRotations[2, 1]; r1 = extentsOther.X * absRotations[1, 0] + extentsOther.Y * absRotations[0, 0]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 4 r = Math.Abs(separation.X * rotations[0, 2] - separation.Z * rotations[0, 0]); r0 = o1.extent.X * absRotations[0, 2] + o1.extent.Z * absRotations[0, 0]; r1 = extentsOther.Y * absRotations[2, 1] + extentsOther.Z * absRotations[1, 1]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 5 r = Math.Abs(separation.X * rotations[1, 2] - separation.Z * rotations[1, 0]); r0 = o1.extent.X * absRotations[1, 2] + o1.extent.Z * absRotations[1, 0]; r1 = extentsOther.X * absRotations[2, 1] + extentsOther.Z * absRotations[0, 1]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 6 r = Math.Abs(separation.X * rotations[2, 2] - separation.Z * rotations[2, 0]); r0 = o1.extent.X * absRotations[2, 2] + o1.extent.Z * absRotations[2, 0]; r1 = extentsOther.X * absRotations[1, 1] + extentsOther.Y * absRotations[0, 1]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 7 r = Math.Abs(separation.Y * rotations[0, 0] - separation.X * rotations[0, 1]); r0 = o1.extent.X * absRotations[0, 1] + o1.extent.Y * absRotations[0, 0]; r1 = extentsOther.Y * absRotations[2, 2] + extentsOther.Z * absRotations[1, 2]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 8 r = Math.Abs(separation.Y * rotations[1, 0] - separation.X * rotations[1, 1]); r0 = o1.extent.X * absRotations[1, 1] + o1.extent.Y * absRotations[1, 0]; r1 = extentsOther.X * absRotations[2, 2] + extentsOther.Z * absRotations[0, 2]; r01 = r0 + r1; if (r > r01) return false; //--- Test case 3 # 9 r = Math.Abs(separation.Y * rotations[2, 0] - separation.X * rotations[2, 1]); r0 = o1.extent.X * absRotations[2, 1] + o1.extent.Y * absRotations[2, 0]; r1 = extentsOther.X * absRotations[1, 2] + extentsOther.Y * absRotations[0, 2]; r01 = r0 + r1; if (r > r01) return false; return true; // No separating axis, then we have intersection }
public static bool getCollision(Shape s1, Shape s2) { KeyValuePair<Shape.Type, Shape.Type> key = new KeyValuePair<Shape.Type, Shape.Type>(s1.type, s2.type); CollisionTest collisionTest; if (collisionTests.TryGetValue(key, out collisionTest)) return collisionTest(s1, s2); else return false; }
public static bool getAABBOBBCollision(Shape s1, Shape s2) { AxisAlignedBox aabb; OrientedBox obb; // Safe type conversion if (s1.type == Shape.Type.AABB) { aabb = (AxisAlignedBox)s1; obb = (OrientedBox)s2; } else { aabb = (AxisAlignedBox)s2; obb = (OrientedBox)s1; } OrientedBox o2 = new OrientedBox(aabb.min, aabb.max); return getOBBOBBCollision(obb, o2); }