public CollisionInfo(ObjectBoundingBoxCollision3D colA, AxisAllignedBoundingBoxCollision3D colB, Vector3 normal, float penetration) { RigidBodyA = colA.GetComponent <Particle3D>(); RigidBodyB = colB.GetComponent <Particle3D>(); RelativeVelocity = RigidBodyB.velocity - RigidBodyA.velocity; contacts[0].normal = normal; contacts[0].penetration = penetration; contacts[0].restitution = Mathf.Min(RigidBodyA.restitution, RigidBodyB.restitution); }
static public CollisionInfo CircleAABB(CircleCollision3D circle, AxisAllignedBoundingBoxCollision3D rect) { //Vector3 halfExtend = (rect.posMax - rect.posMin) / 2; // clamp(value, min, max) - limits value to the range min..max Vector3 circleBox = new Vector3( Mathf.Max(rect.posMin.x + rect.center.x, Mathf.Min(circle.center.x, rect.posMax.x + rect.center.x)), Mathf.Max(rect.posMin.y + rect.center.y, Mathf.Min(circle.center.y, rect.posMax.y + rect.center.y)), Mathf.Max(rect.posMin.z + rect.center.z, Mathf.Min(circle.center.z, rect.posMax.z + rect.center.z))); // Find the closest point to the circle within the rectangle float closestX = Mathf.Clamp(circle.center.x, -rect.halfExtends.x, rect.halfExtends.x); float closestY = Mathf.Clamp(circle.center.y, -rect.halfExtends.y, rect.halfExtends.y); float closestZ = Mathf.Clamp(circle.center.z, -rect.halfExtends.z, rect.halfExtends.z); Vector3 closestPoint = new Vector3(closestX, closestY, closestZ); // Calculate the distance between the circle's center and this closest point //float distanceX = circle.center.x - closestX; //float distanceY = circle.center.y - closestY; //float distanceZ = circle.center.z - closestZ; Vector3 disVec = circle.center - circleBox; //Vector3 distanceComplete = closestPoint - closestPoint; //possibly change to circle vox // If the distance is less than the circle's radius, an intersection occurs //float distSq = Vector3.Dot(distanceComplete, distanceComplete); float distSq = Vector3.Dot(disVec, disVec); //float distanceSquared = (distanceX * distanceX) + (distanceY * distanceY) + (distanceZ * distanceZ); float distance = Mathf.Sqrt(distSq); //Debug.DrawLine(closestPoint, circle.center); if (distSq <= (circle.radius * circle.radius)) { //Debug.Log("square circ collision)"); //return new CollisionInfo(circle, rect, -distanceComplete.normalized, circle.radius - distance); return(new CollisionInfo(circle, rect, -disVec.normalized, circle.radius - distance)); } return(null); //return distanceSquared < (circle.radius * circle.radius); }
static public CollisionInfo AABBAABB(AxisAllignedBoundingBoxCollision3D colA, AxisAllignedBoundingBoxCollision3D colB) { //test if max0>=min1 and max1>=min0 Vector3 distance = colB.center - colA.center; float x_overlap = colA.halfExtends.x + colB.halfExtends.x - Mathf.Abs(distance.x); if (x_overlap > 0.0f) { float y_overlap = colA.halfExtends.y + colB.halfExtends.y - Mathf.Abs(distance.y); if (y_overlap > 0.0f) { float z_overlap = colA.halfExtends.z + colB.halfExtends.z - Mathf.Abs(distance.z); if (z_overlap > 0.0f) { float minOverlap = Mathf.Min(x_overlap, y_overlap, z_overlap); if (minOverlap == x_overlap) { //Debug.Log("Square square collision"); return(new CollisionInfo(colA, colB, distance.x < 0.0f ? -Vector3.right : Vector3.right, x_overlap)); } else if (minOverlap == y_overlap) { //Debug.Log("Square square collision"); return(new CollisionInfo(colA, colB, distance.y < 0.0f ? -Vector3.up : Vector3.up, y_overlap)); } else if (minOverlap == z_overlap) { //Debug.Log("Square square collision"); return(new CollisionInfo(colA, colB, distance.z < 0.0f ? -Vector3.forward : Vector3.forward, z_overlap)); } } } } return(null); }
static public CollisionInfo AABBOBB(AxisAllignedBoundingBoxCollision3D colA, ObjectBoundingBoxCollision3D colB) { List <Vector3> allAxis = new List <Vector3>(); allAxis.AddRange(colA.normAxis); allAxis.AddRange(colB.normAxis); foreach (var axis in allAxis) { float AABBMin = float.MaxValue; float AABBMax = float.MinValue; foreach (var vert in colA.verticeCheck) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < AABBMin) { AABBMin = dotValue; } if (dotValue > AABBMax) { AABBMax = dotValue; } } float OBBMin = float.MaxValue; float OBBMax = float.MinValue; foreach (var vert in colB.verticeCheck) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBBMin) { OBBMin = dotValue; } if (dotValue > OBBMax) { OBBMax = dotValue; } } if (!(AABBMax < OBBMin && OBBMax < AABBMin)) { Vector3 AtoB = colB.center - colA.center; float x_overlap = colA.halfExtends.x + colB.halfExtends.x - Mathf.Abs(AtoB.x); if (x_overlap > 0.0f) { float y_overlap = colA.halfExtends.y + colB.halfExtends.y - Mathf.Abs(AtoB.y); if (y_overlap > 0.0f) { if (x_overlap < y_overlap) { //Debug.Log("ABB OBB"); return(new CollisionInfo(colA, colB, AtoB.x < 0.0f ? -Vector3.right : Vector3.right, x_overlap)); } else { //Debug.Log("ABB OBB"); return(new CollisionInfo(colA, colB, AtoB.y < 0.0f ? -Vector3.up : Vector3.up, y_overlap)); } } } } } return(null); }