private bool MissileToStatic(IMissile missile, IGameObject obj, CollisionParameters parameters) { //RemoveObject((IGameObject)missile); if (!(missile is Grenade)) { (missile as IGameObject).PhysicalData.Velocity = new MyVector(0, 0, 0); SoundSystem.SoundEngine.PlaySound(SoundSystem.Enums.SoundTypes.arrowOff1, (Vector3)parameters.CollisionPoint); } else { GrenadeExplosion(missile as Grenade, parameters); } return false; }
//private int ComputeDamage(CollisionParameters parameters) //{ // return parameters.RelativeVelocity.Length*(parameters.A.Ma //} private bool OnCollision(CollisionParameters parameters) { IPhysicalObject o1 = parameters.A; IPhysicalObject o2 = parameters.B; if (o1 is IMissile && o2 is DestroyableObj) return MissileToDestroyable(o1 as IMissile, o2 as DestroyableObj, parameters); else if (o2 is IMissile && o1 is DestroyableObj) return MissileToDestroyable(o2 as IMissile, o1 as DestroyableObj, parameters); else if (o1 is DestroyableObj && o2 is DestroyableObj) return DestroyableToDestroyable(o1 as DestroyableObj, o2 as DestroyableObj, parameters); else if (o1 is IGameObject && o2 is DestroyableObj) return DestroyableToStatic(o2 as DestroyableObj, o1 as IGameObject, parameters); else if (o2 is IGameObject && o1 is DestroyableObj) return DestroyableToStatic(o1 as DestroyableObj, o2 as IGameObject, parameters); else if (o1 is IMissile && o2 is IGameObject) return MissileToStatic(o1 as IMissile, o2 as IGameObject, parameters); else if (o2 is IMissile && o1 is IGameObject) return MissileToStatic(o2 as IMissile, o1 as IGameObject, parameters); return true; }
private void GrenadeExplosion(Grenade grenade, CollisionParameters parameters) { float maxDistance = grenade.ImpactDamage/4; float impactDamage = grenade.ImpactDamage; if (OnGrenadeHit != null) OnGrenadeHit(grenade, parameters.CollisionPoint); RemoveObject((IGameObject)grenade); for (int i = 0; i < players.Count; i++) { if (players[i].IsAlive) { MyVector pos = players[i].CurrentCharacter.Position; if ((pos - parameters.CollisionPoint).Length < maxDistance) { int damage = (int)(impactDamage * ((pos - parameters.CollisionPoint).Length / maxDistance)); players[i].OnMissileHit(grenade, parameters); if (remote) damage = 0; if (players[i].CurrentCharacter.TakeDamage(damage)) { ((Character)grenade.Owner).Player.OnEnemyDestroyed(players[i]); World.Instance.PlayerKilled(players[i]); } } } } }
private bool MissileToDestroyable(IMissile missile, DestroyableObj obj, CollisionParameters parameters) { if (obj is Character && missile.Owner == obj) return false; if (missile is Grenade) { if(missile.Owner!=obj) GrenadeExplosion(missile as Grenade, parameters); } else { int damage = missile.ImpactDamage; if (obj is Character) { (obj as Character).Player.OnMissileHit(missile, parameters); } if (remote) damage = 0; if (obj.TakeDamage(damage)) { if (obj is Character) { ((Character)missile.Owner).Player.OnEnemyDestroyed((obj as Character).Player); RemoveObject((IGameObject)missile); World.Instance.PlayerKilled((obj as Character).Player); } else { RemoveObject((IGameObject)missile); } } } return false; }
private bool DestroyableToDestroyable(DestroyableObj obj1, DestroyableObj obj2, CollisionParameters parameters) { //int damage = (int)Math.Abs(parameters.RelativeVelocity.Dot(parameters.CollisionNormal)); //obj1.TakeDamage(damage); //obj2.TakeDamage(damage); //if (obj1 is Ship) //{ // (obj1 as Ship).Pilot.OnShipCollision(obj2 as Ship, parameters); //} //if (obj2 is Ship) //{ // (obj2 as Ship).Pilot.OnShipCollision(obj1 as Ship, parameters); //} return false; }
private bool DestroyableToStatic(DestroyableObj obj1, IGameObject obj2, CollisionParameters parameters) { if (obj1 is Character && obj2 is WeaponPickup) { if ((obj2 as WeaponPickup).Ready && ((obj1 as Character).CharacterClass.GameTeam == (obj2 as WeaponPickup).WeaponClass.GameTeam || (obj2 as WeaponPickup).WeaponClass.GameTeam == GameTeam.Both)) { //zbieranie broni (obj1 as Character).Weapons.AddWeapon((obj2 as WeaponPickup).WeaponClass); (obj1 as Character).Player.OnWeaponPickup((obj2 as WeaponPickup)); (obj2 as WeaponPickup).Use(); } return false; } else { if (obj1 is Character) { (obj1 as Character).Player.OnStaticCollision(obj2, parameters); if (parameters.RelativeVelocity.Length > 100) { int damage = (int)parameters.RelativeVelocity.Length - 100; if (obj1.TakeDamage(damage)) { PlayerKilled((obj1 as Character).Player); } } } return true; } return false; }
private void ResolveStaticToRigidBody(CollisionParameters parameters) { IPhysicalObject A = parameters.A; RigidBody B = (RigidBody)parameters.B; float cr = A.CoefficientOfRestitution * B.CoefficientOfRestitution; float cf = A.FrictionCoefficient * B.FrictionCoefficient; MyVector r2; float j, Vrt; r2 = parameters.CollisionPoint - B.Position; RigidBodyData b2 = B.RigidBodyData; cr *= (0.1f + 0.9f * Math.Abs(r2 * parameters.CollisionNormal) / (r2.Length)); cf *= (0.1f + 0.9f * Math.Abs(r2 * parameters.CollisionNormal) / (r2.Length)); j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / ((1 / b2.Mass) + (parameters.CollisionNormal * (((r2 ^ parameters.CollisionNormal) * b2.InertiaInverseGlobal) ^ r2))); Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; if (Vrt != 0) { cf *= Vrt / parameters.RelativeVelocity.Length; b2.Velocity -= ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b2.Mass; b2.AngularVelocity -= ((r2 ^ ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent))) * b2.InertiaInverseGlobal).Rotate(~b2.Orientation); } else { b2.Velocity -= (j * parameters.CollisionNormal) / b2.Mass; b2.AngularVelocity -= ((r2 ^ ((j * parameters.CollisionNormal))) * b2.InertiaInverseGlobal).Rotate(~b2.Orientation); } B.RigidBodyData = b2; }
private void ResolveStaticToPointMass(CollisionParameters parameters) { IPhysicalObject A = parameters.A; PointMass B = (PointMass)parameters.B; float cr = A.CoefficientOfRestitution * B.CoefficientOfRestitution; float cf = A.FrictionCoefficient * B.FrictionCoefficient; float j, Vrt; PointMassData b2 = B.PointMassData; bool tempMass = false; if (b2.Mass == 0) { b2.Mass = 1; tempMass = true; } j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / (1 / b2.Mass); Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; if (Vrt != 0) { cf *= Vrt / parameters.RelativeVelocity.Length; b2.Velocity -= ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b2.Mass; } else { b2.Velocity -= (j * parameters.CollisionNormal) / b2.Mass; } if (tempMass) { b2.Mass = 0; } B.PointMassData = b2; }
private void ResolveRigidBodyToRigidBody(CollisionParameters parameters) { RigidBody A = (RigidBody)parameters.A; RigidBody B = (RigidBody)parameters.B; float cr = A.CoefficientOfRestitution * B.CoefficientOfRestitution; float cf = A.FrictionCoefficient * B.FrictionCoefficient; MyVector r1, r2; float j, Vrt; r1 = parameters.CollisionPoint - A.Position; r2 = parameters.CollisionPoint - B.Position; RigidBodyData b1 = A.RigidBodyData; RigidBodyData b2 = B.RigidBodyData; j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / ((1 / b1.Mass + 1 / b2.Mass) + (parameters.CollisionNormal * (((r1 ^ parameters.CollisionNormal) * b1.InertiaInverseGlobal) ^ r1)) + (parameters.CollisionNormal * (((r2 ^ parameters.CollisionNormal) * b2.InertiaInverseGlobal) ^ r2))); Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; if (Vrt != 0) { //MyVector frictionImpulse; cf *= Vrt / parameters.RelativeVelocity.Length; b1.Velocity += ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b1.Mass; b1.AngularVelocity += ((r1 ^ ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent))) * b1.InertiaInverseGlobal).Rotate(~b1.Orientation); b2.Velocity -= ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b2.Mass; b2.AngularVelocity -= ((r2 ^ ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent))) * b2.InertiaInverseGlobal).Rotate(~b2.Orientation); } else { b1.Velocity += (j * parameters.CollisionNormal) / b1.Mass; b1.AngularVelocity += ((r1 ^ (j * parameters.CollisionNormal)) * b1.InertiaInverseGlobal).Rotate(~b1.Orientation); b2.Velocity -= ((j * parameters.CollisionNormal)) / b2.Mass; b2.AngularVelocity -= ((r2 ^ (j * parameters.CollisionNormal)) * b2.InertiaInverseGlobal).Rotate(~b2.Orientation); } A.RigidBodyData = b1; B.RigidBodyData = b2; }
private void ResolvePointMassToPointMass(CollisionParameters parameters) { PointMass A = (PointMass)parameters.A; PointMass B = (PointMass)parameters.B; float cr = A.CoefficientOfRestitution * B.CoefficientOfRestitution; float cf = A.FrictionCoefficient * B.FrictionCoefficient; MyVector r1, r2; float j, Vrt; r1 = parameters.CollisionPoint - A.Position; r2 = parameters.CollisionPoint - B.Position; PointMassData b1 = A.PointMassData; PointMassData b2 = B.PointMassData; j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / (1 / b1.Mass + 1 / b2.Mass); Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; if (Vrt != 0) { //MyVector frictionImpulse; cf *= Vrt / parameters.RelativeVelocity.Length; b1.Velocity += ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b1.Mass; b2.Velocity -= ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b2.Mass; } else { b1.Velocity += (j * parameters.CollisionNormal) / b1.Mass; b2.Velocity -= ((j * parameters.CollisionNormal)) / b2.Mass; } A.PointMassData = b1; B.PointMassData = b2; }
public void ResolveCollision(CollisionParameters parameters) { IPhysicalObject A = parameters.A; IPhysicalObject B = parameters.B; //if (parameters.CollisionNormal * parameters.RelativeVelocity < 0) // return; if (A.Type == ObjectType.Static && B.Type == ObjectType.Static) return; if (A.Type == ObjectType.Static && B.Type == ObjectType.PointMass) { ResolveStaticToPointMass(parameters); return; } if (B.Type == ObjectType.Static && A.Type == ObjectType.PointMass) { parameters.A = B; parameters.B = A; parameters.CollisionNormal = -parameters.CollisionNormal; parameters.RelativeAcceleration = -parameters.RelativeAcceleration; parameters.RelativeVelocity = -parameters.RelativeVelocity; ResolveStaticToPointMass(parameters); return; } if (A.Type == ObjectType.Static && B.Type == ObjectType.RigidBody) { ResolveStaticToRigidBody(parameters); return; } if (B.Type == ObjectType.Static && A.Type == ObjectType.RigidBody) { parameters.A = B; parameters.B = A; parameters.CollisionNormal = -parameters.CollisionNormal; parameters.RelativeAcceleration = -parameters.RelativeAcceleration; parameters.RelativeVelocity = -parameters.RelativeVelocity; ResolveStaticToRigidBody(parameters); return; } if (A.Type == ObjectType.PointMass && B.Type == ObjectType.RigidBody) { ResolvePointMassToRigidBody(parameters); return; } if (B.Type == ObjectType.PointMass && A.Type == ObjectType.RigidBody) { parameters.A = B; parameters.B = A; parameters.CollisionNormal = -parameters.CollisionNormal; parameters.RelativeAcceleration = -parameters.RelativeAcceleration; parameters.RelativeVelocity = -parameters.RelativeVelocity; ResolvePointMassToRigidBody(parameters); return; } if (A.Type == ObjectType.PointMass && B.Type == ObjectType.PointMass) { ResolvePointMassToPointMass(parameters); return; } if (A.Type == ObjectType.RigidBody && B.Type == ObjectType.RigidBody) { ResolveRigidBodyToRigidBody(parameters); return; } //float cr = A.CoefficientOfRestitution * B.CoefficientOfRestitution; //float cf = A.FrictionCoefficient * B.FrictionCoefficient; ////in case of still-moving collision we assume that B is still //if (A.Type == ObjectType.Static) //{ // CollisionParameters p=parameters; // p.A = parameters.B; // p.B = parameters.A; // p.CollisionNormal = -p.CollisionNormal; // p.RelativeAcceleration = -p.RelativeAcceleration; // p.RelativeVelocity = -p.RelativeVelocity; // //ResolveCollision(p); // //return; //} //MyVector r1,r2; //float j,Vrt; //if (B.Type == ObjectType.RigidBody) //{ // //moving-moving collision // r1 = parameters.CollisionPoint - A.Position; // r2 = parameters.CollisionPoint - B.Position; // RigidBodyData b1 = A.RigidBodyData; // RigidBodyData b2 = B.RigidBodyData; // j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / // ((1 / b1.Mass + 1 / b2.Mass) + // (parameters.CollisionNormal * (((r1 ^ parameters.CollisionNormal) * b1.InertiaInverseGlobal) ^ r1)) + // (parameters.CollisionNormal * (((r2 ^ parameters.CollisionNormal) * b2.InertiaInverseGlobal) ^ r2))); // Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; // if (Vrt != 0) // { // MyVector frictionImpulse; // cf *= Vrt / parameters.RelativeVelocity.Length; // b1.Velocity += ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b1.Mass; // b1.AngularVelocity += ((r1 ^ ((j * parameters.CollisionNormal) + // ((cf * j) * parameters.CollisionTangent))) * b1.InertiaInverseGlobal).Rotate(~b1.Orientation); // b2.Velocity -= ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b2.Mass; // b2.AngularVelocity -= ((r2 ^ ((j * parameters.CollisionNormal) + // ((cf * j) * parameters.CollisionTangent))) * b2.InertiaInverseGlobal).Rotate(~b2.Orientation); // } // else // { // b1.Velocity += (j * parameters.CollisionNormal) / b1.Mass; // b1.AngularVelocity += ((r1 ^ (j * parameters.CollisionNormal))* // b1.InertiaInverseGlobal).Rotate(~b1.Orientation); // b2.Velocity -= ((j * parameters.CollisionNormal)) / b2.Mass; // b2.AngularVelocity -= ((r2 ^ (j * parameters.CollisionNormal)) * // b2.InertiaInverseGlobal).Rotate(~b2.Orientation); // } // A.RigidBodyData = b1; // B.RigidBodyData = b2; //} //else //{ // //moving-still collision // r1 = parameters.CollisionPoint - A.Position; // RigidBodyData b1 = A.RigidBodyData; // j = (-(1f + cr) * (parameters.RelativeVelocity * parameters.CollisionNormal)) / // ((1 / b1.Mass) + // (parameters.CollisionNormal * (((r1 ^ parameters.CollisionNormal) * b1.InertiaInverseGlobal) ^ r1))); // Vrt = parameters.RelativeVelocity * parameters.CollisionTangent; // if (Vrt != 0) // { // cf *= Vrt / parameters.RelativeVelocity.Length; // b1.Velocity += ((j * parameters.CollisionNormal) + ((cf * j) * parameters.CollisionTangent)) / b1.Mass; // b1.AngularVelocity += ((r1 ^ ((j * parameters.CollisionNormal) + // ((cf * j) * parameters.CollisionTangent))) * b1.InertiaInverseGlobal).Rotate(~b1.Orientation); // } // else // { // b1.Velocity += (j * parameters.CollisionNormal) / b1.Mass; // b1.AngularVelocity += ((r1 ^ ((j * parameters.CollisionNormal))) * // b1.InertiaInverseGlobal).Rotate(~b1.Orientation); // } // A.RigidBodyData = b1; //} }