//------------------------------------Private Functions------------------------------------- private void CheckForCollision(PSI_Collider col1, PSI_Collider col2) { // Sphere on sphere. if (col1.pColliderType == ColliderType.Sphere && col2.pColliderType == ColliderType.Sphere) { if (PSI_Physics.SphereSphereCollisionOccured((PSI_SphereCollider)col1, (PSI_SphereCollider)col2)) { PSI_Physics.HandleSphereSphereCollision((PSI_SphereCollider)col1, (PSI_SphereCollider)col2); FindObjectOfType <DebugManager>().CollisionOccured(col1, col2); } } // AABB on AABB. if (col1.pColliderType == ColliderType.AABB && col2.pColliderType == ColliderType.AABB) { if (PSI_Physics.AABBAABBCollisionOccured((PSI_AABBCollider)col1, (PSI_AABBCollider)col2)) { PSI_Physics.HandleAABBAABBCollision((PSI_AABBCollider)col1, (PSI_AABBCollider)col2); FindObjectOfType <DebugManager>().CollisionOccured(col1, col2); } } // Sphere on plane. if ((col1.pColliderType == ColliderType.Sphere && col2.pColliderType == ColliderType.Plane) || (col1.pColliderType == ColliderType.Plane && col2.pColliderType == ColliderType.Sphere)) { PSI_SphereCollider sphere = (PSI_SphereCollider)((col1.pColliderType == ColliderType.Sphere) ? col1 : col2); PSI_PlaneCollider plane = (PSI_PlaneCollider)((col1.pColliderType == ColliderType.Sphere) ? col2 : col1); if (PSI_Physics.SpherePlaneCollisionOccured(sphere, plane)) { PSI_Physics.HandleSpherePlaneCollision(sphere, plane); FindObjectOfType <DebugManager>().CollisionOccured(col1, col2); } } }
public static bool SpherePlaneCollisionOccured(PSI_SphereCollider sphereCol, PSI_PlaneCollider planeCol) { float distToProjectedPoint = Vector3.Dot(planeCol.pNormal, (sphereCol.pPosition - planeCol.pPosition)); Vector3 projectedPoint = sphereCol.pPosition - distToProjectedPoint * planeCol.pNormal; // Generate 4 triangles between the corners of the plane and the projected point. var planeVerts = planeCol.GetPlaneVertices(); var triangles = new Vector3[4, 3]; for (int i = 0; i < 4; i++) { triangles[i, 0] = projectedPoint; triangles[i, 1] = planeVerts[i]; triangles[i, 2] = planeVerts[(i == 3)?0:i + 1]; } // Sum the area of the traingles. float totalTriArea = 0.0f; for (int i = 0; i < 4; i++) { float a = Vector3.Distance(triangles[i, 0], triangles[i, 1]); float b = Vector3.Distance(triangles[i, 1], triangles[i, 2]); float c = Vector3.Distance(triangles[i, 2], triangles[i, 0]); float s = (a + b + c) / 2; totalTriArea += Mathf.Sqrt(s * (s - a) * (s - b) * (s - c)); } // Check if the sum area is equal to the area of the plane. // If so then the projected point is within the bounds of the plane. if (Mathf.Abs(totalTriArea - planeCol.pArea) > sphereCol.Radius) { return(false); } // Check if the sphere is intersecting with the plane. return(Mathf.Abs(distToProjectedPoint) <= sphereCol.Radius); }
public static void HandleSpherePlaneCollision(PSI_SphereCollider sphereCol, PSI_PlaneCollider planeCol) { float distToProjectedPoint = Vector3.Dot(planeCol.pNormal, (sphereCol.pPosition - planeCol.pPosition)); Vector3 projectedPoint = sphereCol.pPosition - distToProjectedPoint * planeCol.pNormal; // Calculating the collision vector. var colVector = sphereCol.pPosition - projectedPoint; // Calculating the minimum translation vector needed to reset the sphere. var minTranslationVector = colVector * ((sphereCol.Radius - colVector.magnitude) / colVector.magnitude); // Moving the sphere collider so it is not overlapping. sphereCol.transform.Translate(minTranslationVector); // Applying the impulse to the bodies. if (planeCol.pRigidBody != null) { sphereCol.pRigidBody.Velocity += PSI_Physics.CalculateImpulseAgainstStaticRB(sphereCol.pRigidBody, planeCol.pRigidBody, minTranslationVector); } else { sphereCol.pRigidBody.Velocity += PSI_Physics.CalculateImpulseAgainstStaticCollider(sphereCol.pRigidBody, minTranslationVector); } }