//Checks if 2 colliders are intersecting and will run resolve if they are public void DetectCollision(Rigid_Body body1, Rigid_Body body2) { //1st collider in detection Base_Collider col1 = body1.Collider; //2nd collider in detection Base_Collider col2 = body2.Collider; CollisionInfo collision = new CollisionInfo(); //Check what type of collision check needs to happen if (col1.Collider_Type == ColliderType.AABB && col2.Collider_Type == ColliderType.AABB) { collision = AABBvsAABB((AABB_Collider)col1, (AABB_Collider)col2); } else if (col1.Collider_Type == ColliderType.CIRCLE && col2.Collider_Type == ColliderType.CIRCLE) { collision = CIRCLEvsCIRCLE((Circle_Collider)col1, (Circle_Collider)col2); } else if (col1.Collider_Type == ColliderType.CIRCLE && col2.Collider_Type == ColliderType.AABB) { collision = CIRCLEvsAABB((Circle_Collider)col1, (AABB_Collider)col2, false); } else if (col1.Collider_Type == ColliderType.AABB && col2.Collider_Type == ColliderType.CIRCLE) { collision = CIRCLEvsAABB((Circle_Collider)col2, (AABB_Collider)col1, true); } if (collision.hit) { ResolveCollision(collision, body1, body2); } }
//Creates an explosion force in world at position of body public void CreateExplosion(float explosionForce, Rigid_Body source) { Vec2 force = Vec2.Zero; Vec2 acceleration = Vec2.Zero; Vec2 direction = Vec2.Zero; //Debug.Log(dynamicBodies.Count); for (int i = 0; i < dynamicBodies.Count; i++) { //Debug.Log(dynamicBodies[i].gameObject.name); //Debug.Log(source.gameObject.name); if (dynamicBodies[i].gameObject.name != source.gameObject.name) { direction = dynamicBodies[i].Position - source.Position; if (direction.Magnitude() < explosionForce) { force = explosionForce * direction.Normalized * ((explosionForce - direction.Magnitude()) / explosionForce); dynamicBodies[i].ApplyForceInstant(force); } } } }
public CollisionPair(Rigid_Body a, Rigid_Body b) { A = a; B = b; }
//This function handles the separating of collider, Resolution handles restitution, friction and positional correction public void ResolveCollision(CollisionInfo collisionInfo, Rigid_Body _collider, Rigid_Body _collided) { if (!_collider.Collider.Trigger && !_collided.Collider.Trigger) { //impulse resolution, applies velocity to both rigid bodies involved in collision and positional correction is done for resting objects to stop //colliders sinking in to eachother. Mass is taken in to account any time velocity is changed. float invMassCollider = 0; float invMassCollided = 0; if (_collider.Mass != 0) { invMassCollider = 1 / _collider.Mass; } if (_collided.Mass != 0) { invMassCollided = 1 / _collided.Mass; } // Calculate relative velocity Vec2 rv = _collided.velocity - _collider.velocity; // Calculate relative velocity in terms of the normal direction float velAlongNormal = rv.DotProduct(collisionInfo.collisionNormal); // Do not resolve if velocities are separating if (velAlongNormal > 0) { return; } // Calculate restitution float e = Mathf.Min(_collider.Collider.P_Mat.restitution, _collided.Collider.P_Mat.restitution); // Calculate impulse scalar float j = -(1 + e) * velAlongNormal; j /= invMassCollider + invMassCollided; // Apply impulse Vec2 impulse = j * collisionInfo.collisionNormal; _collider.velocity -= invMassCollider * impulse; _collided.velocity += invMassCollided * impulse; // Re-calculate relative velocity after normal impulse is applied Vec2 impulseVel = _collided.velocity - _collider.velocity; // Solve for the tangent vector Vec2 tangent = impulseVel - impulseVel.DotProduct(collisionInfo.collisionNormal) * collisionInfo.collisionNormal; tangent.Normalize(); // Solve for magnitude to apply along the friction vector float jt = -impulseVel.DotProduct(tangent); jt = jt / (invMassCollider + invMassCollided); //Get coefficient based on Material attached to colliders float mu = Physics_Material.CombineFrictions(_collider.Collider.P_Mat.staticFriction, _collided.Collider.P_Mat.staticFriction, _collider.Collider.P_Mat.frictionCombine); // Clamp magnitude of friction and create impulse vector Vec2 frictionImpulse; if (Mathf.Abs(jt) < j * mu) { frictionImpulse = jt * tangent; } else { frictionImpulse = -j *tangent *Physics_Material.CombineFrictions(_collider.Collider.P_Mat.dynamicFriction, _collided.Collider.P_Mat.dynamicFriction, _collider.Collider.P_Mat.frictionCombine); } // Apply friction impulse _collider.velocity -= invMassCollider * frictionImpulse; _collided.velocity += invMassCollided * frictionImpulse; //Correct for float precision error so object does not sink in to resting colliders const float percent = 0.8f; // usually 20% to 80% Vec2 correction = Vec2.Zero; correction.x = (Mathf.Abs(collisionInfo.depth.x) / (invMassCollider + invMassCollided)) * percent * collisionInfo.collisionNormal.x; correction.y = (Mathf.Abs(collisionInfo.depth.y) / (invMassCollider + invMassCollided)) * percent * collisionInfo.collisionNormal.y; //Debug.Log("correction: " + _collider.gameObject.name + " " + correction.x + " " + correction.y); _collider.Position -= invMassCollider * correction; _collided.Position += invMassCollided * correction; } //Trigger on collision enter delegate. Default is an empty function _collider.Collider.CollisionEnter(_collided.Collider, collisionInfo); collisionInfo.collisionNormal *= -1f; _collided.Collider.CollisionEnter(_collider.Collider, collisionInfo); }