// This function calculates OBB to OBB colisions public static CollisionInfo OBBToOBBCollision(CollisionHull2D a, CollisionHull2D b) { // Compute the R hat and U hat for both collision hulls Vector2 ARHat = new Vector2(Mathf.Abs(Mathf.Cos(a.GetRotation())), Mathf.Abs(-Mathf.Sin(a.GetRotation()))); Vector2 BRHat = new Vector2(Mathf.Abs(Mathf.Cos(b.GetRotation())), Mathf.Abs(-Mathf.Sin(b.GetRotation()))); Vector2 AUHat = new Vector2(Mathf.Abs(Mathf.Sin(a.GetRotation())), Mathf.Abs(Mathf.Cos(a.GetRotation()))); Vector2 BUHat = new Vector2(Mathf.Abs(Mathf.Sin(b.GetRotation())), Mathf.Abs(Mathf.Cos(b.GetRotation()))); // Create a list of all penetrations on each axis List <float> overlaps = new List <float>(); // Do axis checks overlaps.Add(CheckOBBAxis(a, b, ARHat)); // Does the check pass? if (overlaps[0] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, AUHat)); // Does the check pass? if (overlaps[1] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, BRHat)); // Does the check pass? if (overlaps[2] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, AUHat)); // Do the axis checks pass? if (overlaps[3] != Mathf.Infinity) { // If yes, then inform the parents of the complex shape object (if applicable) ReportCollisionToParent(a, b); } else { // If no, return nothing return(null); } // Return full details of the Collision list if the two collide return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps))); }
// This function calculates OBB to OBB colisions public static CollisionInfo OBBToOBBCollision(CollisionHull3D a, CollisionHull3D b) { List <float> overlaps = new List <float>(); List <Vector3> axes = new List <Vector3>(); // Get the transform values for each axis for each shape Vector3 x1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(0); Vector3 y1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(1); Vector3 z1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(2); Vector3 x2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(0); Vector3 y2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(1); Vector3 z2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(2); // Go through and check through all overlapping axes // Face/Face Object 1 overlaps.Add(CheckOBBAxis(a, b, x1)); axes.Add(x1); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, y1)); axes.Add(y1); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, z1)); axes.Add(z1); if (overlaps[overlaps.Count - 1] < 0) { return(null); } // Face/Face Object 2 overlaps.Add(CheckOBBAxis(a, b, x2)); axes.Add(x2); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, y2)); axes.Add(y2); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, z2)); axes.Add(z2); if (overlaps[overlaps.Count - 1] < 0) { return(null); } // Edge/Edge overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, x2))); axes.Add(Vector3.Cross(x1, x2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, y2))); axes.Add(Vector3.Cross(x1, y2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, z2))); axes.Add(Vector3.Cross(x1, z2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, x2))); axes.Add(Vector3.Cross(y1, x2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, y2))); axes.Add(Vector3.Cross(y1, y2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, z2))); axes.Add(Vector3.Cross(y1, z2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, x2))); axes.Add(Vector3.Cross(z1, x2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, y2))); axes.Add(Vector3.Cross(z1, y2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, z2))); axes.Add(Vector3.Cross(z1, z2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } float bestOverlap = Mathf.Infinity; int bestIndex = 0; for (int i = 0; i < overlaps.Count; i++) { if (overlaps[i] < bestOverlap) { bestOverlap = overlaps[i]; bestIndex = i; } } if (bestIndex > 2) { Vector3 normal = axes[bestIndex]; Vector3 axis = axes[bestIndex]; if (Vector3.Dot(axis, (b.GetPosition() - a.GetPosition())) > 0) { axis *= -1; } Vector3 vertex = a.GetDimensions(); if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(0), normal) > 0) { vertex.x = -vertex.x; } if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(1), normal) > 0) { vertex.y = -vertex.y; } if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(2), normal) > 0) { vertex.z = -vertex.z; } vertex = a.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(vertex); // If all axis are overlaping, then we have a collision ReportCollisionToParent(a, b); return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), normal, vertex, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition()))); } else if (bestIndex > 5) { Vector3 normal = axes[bestIndex]; Vector3 axis = axes[bestIndex]; if (Vector3.Dot(axis, (a.GetPosition() - b.GetPosition())) > 0) { axis *= -1; } Vector3 vertex = b.GetDimensions(); if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(0), normal) > 0) { vertex.x = -vertex.x; } if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(1), normal) > 0) { vertex.y = -vertex.y; } if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(2), normal) > 0) { vertex.z = -vertex.z; } vertex = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(vertex); // If all axis are overlaping, then we have a collision ReportCollisionToParent(a, b); return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), normal, vertex, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition()))); } else { int index = bestIndex - 6; int oneIndex = index / 3; int twoIndex = index % 3; Vector3 oneAxis = axes[oneIndex]; Vector3 twoAxis = axes[twoIndex]; Vector3 axis = axes[bestIndex].normalized; if (Vector3.Dot(axis, b.GetPosition() - a.GetPosition()) > 0) { axis *= -1; } Vector3 pointOnOneEdge = a.GetDimensions(); Vector3 pointOnTwoEdge = b.GetDimensions(); if (oneIndex == 0) { pointOnOneEdge.x = 0; } else if (Vector2.Dot(x1, axis) > 0) { pointOnOneEdge.x = -pointOnOneEdge.x; } if (twoIndex == 3) { pointOnTwoEdge.x = 0; } else if (Vector2.Dot(x2, axis) > 0) { pointOnTwoEdge.x = -pointOnTwoEdge.x; } if (oneIndex == 1) { pointOnOneEdge.y = 0; } else if (Vector2.Dot(y1, axis) > 0) { pointOnOneEdge.y = -pointOnOneEdge.y; } if (twoIndex == 4) { pointOnTwoEdge.y = 0; } else if (Vector2.Dot(y2, axis) > 0) { pointOnTwoEdge.y = -pointOnTwoEdge.y; } if (oneIndex == 2) { pointOnOneEdge.z = 0; } else if (Vector2.Dot(z1, axis) > 0) { pointOnOneEdge.z = -pointOnOneEdge.z; } if (twoIndex == 5) { pointOnTwoEdge.z = 0; } else if (Vector2.Dot(z2, axis) > 0) { pointOnTwoEdge.z = -pointOnTwoEdge.z; } pointOnOneEdge = a.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(pointOnOneEdge); pointOnTwoEdge = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(pointOnTwoEdge); Vector3 contactPoint = GetCollisionPoint(pointOnOneEdge, oneAxis, a.GetDimensions().x, pointOnTwoEdge, twoAxis, b.GetDimensions().x, bestIndex > 2); ReportCollisionToParent(a, b); return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), axis, contactPoint, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition()))); } }
// This function calculates OBB to OBB colisions public static CollisionInfo OBBToOBBCollision(CollisionHull3D a, CollisionHull3D b) { List <float> overlaps = new List <float>(); // Get the transform values for each axis for each shape Vector3 x1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(0); Vector3 y1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(1); Vector3 z1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(2); Vector3 x2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(0); Vector3 y2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(1); Vector3 z2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(2); // Go through and check through all overlapping axes overlaps.Add(CheckOBBAxis(a, b, x1)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, y1)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, z1)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, x2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, y2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, z2)); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, x2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, y2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, z2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, x2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, y2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, z2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, x2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, y2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, z2))); if (overlaps[overlaps.Count - 1] < 0) { return(null); } // If all axis are overlaping, then we have a collision ReportCollisionToParent(a, b); return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps))); }