public static void ResolveCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info,
     T2DCollisionMaterial material, bool handleBoth)
 {
     theirObject.Physics.Velocity = Vector2.Zero;
     ourObject.Physics.Velocity = Vector2.Zero;
     ourObject.MarkForDelete = true;
 }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            TrapComponent trapComponent = trapObject.Components.FindComponent<TrapComponent>();

            trapComponent.Activate();

            ourObject.CollisionsEnabled = false;
            ourObject.MarkForDelete = true;
        }
        public static void EtherealCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info,
            T2DCollisionMaterial material, bool handleBoth)
        {
            // Start player's flashing animation to indicate she was hit.
            PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>();

            if (actor != null && !actor.IsInvincible)
                actor.ApplyDamageEffects();
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();

            if (actor == null)
                return;

            actor.Kill(Owner as T2DSceneObject);
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();

            if (actor == null)
                return;

            if (_confirmDamage(ourObject, theirObject, actor))
                actor.TakeDamage(_damage, ourObject);
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            PlayerActorComponent player = theirObject.Components.FindComponent<PlayerActorComponent>();

            if (player == null)
                return;
            else
                player.SwitchToFallDeath();

            base._onEnter(ourObject, theirObject, info);
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            BairneActorComponent actor = theirObject.Components.FindComponent<BairneActorComponent>();

            if (actor != null)
            {
                actor.OnLeft = onLeft;
                actor.ReachedBound = true;
                actor.HorizontalStop();
            }
            else
                ;//log error
        }
        /// <summary>
        /// The routine run when the player collides with the object.
        /// </summary>
        /// <param name="ourObject">The trigger object.</param>
        /// <param name="theirObject">The player that collided with the trigger.</param>
        /// <param name="info">Some sort of info...</param>
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            if (!flipped)
            {
                switchedOn = !switchedOn;

                if (behaviors != null)
                    foreach (ISwitchBehavior behavior in behaviors)
                        behavior.Execute(ourObject, switchedOn);

                flipped = true;
            }
        }
        ///<summary>
        ///Callback for when the microbe collides with another object.
        ///</summary>
        ///<param name="ourObject">The microbe.</param>
        ///<param name="theirObject">The other object.</param>
        ///<param name="info">Information about the collision point.</param>
        ///<param name="resolve">Not used.</param>
        ///<param name="physicsMaterial">
        ///The physics properties of the objects.
        ///</param>
        public void OnCollision(
           T2DSceneObject ourObject,
           T2DSceneObject theirObject,
           T2DCollisionInfo info,
           ref T2DResolveCollisionDelegate resolve,
           ref T2DCollisionMaterial physicsMaterial)
        {
            if (!ourObject.MarkForDelete &&
               theirObject.TestObjectType(_collidesWith))
            {
                //handle microbe collision with another microbe
                if (theirObject.TestObjectType(
                   TorqueObjectDatabase.Instance.GetObjectType("microbe")))
                {
                    T2DPhysicsComponent.BounceCollision.Invoke(
                       ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.ClampCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.KillCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.RigidCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.StickyCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);
                }
                else if (theirObject.TestObjectType(
                   TorqueObjectDatabase.Instance.GetObjectType("projectile")))
                {
                    //T2DPhysicsComponent.BounceCollision.Invoke(
                    //  ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.ClampCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    T2DPhysicsComponent.KillCollision.Invoke(
                     ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.RigidCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.StickyCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);
                }
                //TODO: add handling for other object types
            }
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the melee scene object and enemies
        /// </summary>
        /// <param name="myObject">The melee scene object mounted on the player</param>
        /// <param name="theirObject">The enemy scene object</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage;

            if (theirObject.TestObjectType(PlatformerData.PlayerObjectType))
            {
                PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null)
                    actor.TakeDamage(damage, myObject, true, true);
            }

            myObject.MarkForDelete = true;
        }
        public static void ProjCollision(T2DSceneObject projectile, T2DSceneObject targetObject,
            T2DCollisionInfo into, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial material)
        {
            int damage = projectile.Components.FindComponent<ProjectileComponent>().Damage;

            if (targetObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                PlayerActorComponent actor = targetObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null)
                    actor.TakeDamage(damage, projectile, true, true);
            }

            projectile.CollisionsEnabled = false;
            projectile.MarkForDelete = true;
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the kushling and the player
        /// </summary>
        /// <param name="myObject">The kushling</param>
        /// <param name="theirObject">The collided object.</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void KushCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            int damage = myObject.Components.FindComponent<KushlingActorComponent>().Damage;

            if (theirObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null && !actor.IsInvincible)
                    actor.TakeDamage(damage, myObject, true, true);
            }

            else if (theirObject.TestObjectType(PlatformerData.EnemyObjectType))
            {
                resolve = T2DPhysicsComponent.ClampCollision;
            }

            else
                resolve = null;
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            base._onEnter(ourObject, theirObject, info);

            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();

            if (actor == null || ourObject == null)
                return;

            if (_confirmPickup(ourObject, theirObject, actor))
            {
                ourObject.Visible = false;
                ourObject.CollisionsEnabled = false;

                if (actor.Controller != null)
                    (actor.Controller as ActorController).ActorCollectedItem(actor, this);

                if (ourObject.IsRegistered)
                    TorqueObjectDatabase.Instance.Unregister(ourObject);

                ourObject = null;
            }
        }
 protected static void _resolveBounce(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
 {
     if (ourObject.Physics != null)
     {
         // are we already bouncing away?
         float dot = Vector2.Dot(ourObject.Physics.Velocity, info.Normal);
         if (dot < 0.0f)
             ourObject.Physics.Velocity = ourObject.Physics.Velocity - (1.0f + physicsMaterial.Restitution) * dot * info.Normal;
     }
     if (handleBoth && theirObject.Physics != null)
     {
         // are they already bouncing away?
         float dot = Vector2.Dot(theirObject.Physics.Velocity, -info.Normal);
         if (dot < 0.0f)
             theirObject.Physics.Velocity = theirObject.Physics.Velocity + (1.0f + physicsMaterial.Restitution) * dot * info.Normal;
     }
 }
Example #15
0
        ///<summary>
        ///Callback for when the tank collides with another object.
        ///</summary>
        ///<param name="ourObject">The tank.</param>
        ///<param name="theirObject">The other object.</param>
        ///<param name="info">Information about the collision point.</param>
        ///<param name="resolve">Not used.</param>
        ///<param name="physicsMaterial">
        ///The physics properties of the objects.
        ///</param>
        public void OnCollision(
            T2DSceneObject ourObject,
            T2DSceneObject theirObject,
            T2DCollisionInfo info,
            ref T2DResolveCollisionDelegate resolve,
            ref T2DCollisionMaterial physicsMaterial)
        {
            if (ourObject.MarkForDelete ||
                !theirObject.TestObjectType(_collidesWith))
                return;

            //Set up gamepad vibration if this is a player object
            //also set up maxVelocity
            GamepadVibrationComponent vib =
                ourObject.Components.FindComponent<GamepadVibrationComponent>();
            TankMovementComponent mac =
                ourObject.Components.FindComponent<TankMovementComponent>();

            float maxSpeed = 0.1f; //avoid possible divide by zero below
            if (null != mac)
            {
                maxSpeed = mac.MaxForwardSpeed;
            }

            //Calculate Impact Velocity.
            Vector2 deltaImpactVelocity =
                _CalculateImpactVelocity(ourObject, theirObject, info);
            float impact = deltaImpactVelocity.Length();
            float vibration =
                MathHelper.Clamp((impact / (maxSpeed * 2.0f)), 0.0f, 1.0f);

            //Perform sound (on all objects) and vibration (players only)
            if (vibration < 0.3)
            {
                //High speed vibration for the small collisions
                if (vib != null)
                {
                    vib.SetHighSpeedVibration(0.2f, (vibration / 0.3f) * 0.8f);
                }

                if (vibration >= 0.1 &&
                    TorqueEngineComponent.Instance.TorqueTime >=
                    _nextSoftSoundPlayTime)
                {
                    Program.SoundBank.PlayCue("softCollision");
                    _nextSoftSoundPlayTime =
                        TorqueEngineComponent.Instance.TorqueTime +
                        SOUND_TIME_STEP +
                        TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE);
                }
            }
            else
            {
                //Low speed vibration for the big collisions
                if (vib != null)
                {
                    vib.SetLowSpeedVibration(
                        0.2f,
                        ((vibration - 0.3f) / 0.7f) * 0.9f + 0.1f);
                }

                if (TorqueEngineComponent.Instance.TorqueTime >=
                    _nextHardSoundPlayTime)
                {
                    Program.SoundBank.PlayCue("hardCollision");
                    _nextHardSoundPlayTime =
                        TorqueEngineComponent.Instance.TorqueTime +
                        SOUND_TIME_STEP +
                        TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE);
                }
            }
        }
Example #16
0
        /// <summary>
        /// Callback for when the projectile collides with another object.
        /// </summary>
        /// <param name="ourObject">The projectile.</param>
        /// <param name="theirObject">The other object.</param>
        /// <param name="info">Information about the collision point.</param>
        /// <param name="resolve">Not used.</param>
        /// <param name="physicsMaterial">The physics properties of the objects.</param>
        public void OnCollision(
            T2DSceneObject ourObject,
            T2DSceneObject theirObject,
            T2DCollisionInfo info,
            ref T2DResolveCollisionDelegate resolve,
            ref T2DCollisionMaterial physicsMaterial)
        {
            if (!ourObject.MarkForDelete &&
                theirObject.TestObjectType(_collidesWith))
            {
                // If we hit a player object then activate its game pad vibration
                T2DStaticSprite psprite = theirObject as T2DStaticSprite;
                if (psprite != null)
                {
                    GamepadVibrationComponent vib =
                        psprite.Components.FindComponent<GamepadVibrationComponent>();
                    if (vib != null)
                    {
                        vib.SetLowSpeedVibration(0.1f, 0.8f);
                    }
                }

                if (theirObject.TestObjectType(TorqueObjectDatabase.Instance.GetObjectType("tank")))
                {
                    Explode(info, true);
                }
                else
                {
                    Explode(info, false);
                }
            }
        }
Example #17
0
        /// <summary>
        /// Produces an explosion at the point of impact.
        /// </summary>
        /// <param name="info">Information about the collision point.</param>
        /// <param name="sparks">
        /// Should the explosion includes sparks (tank collision) or not 
        /// (barrier collision).
        /// </param>
        public void Explode(T2DCollisionInfo info, bool sparks)
        {
            if (sparks)
            {
                // Trigger the tank sparks
                T2DParticleEffect sparksEffect =
                    (TorqueObjectDatabase.Instance.FindObject<T2DParticleEffect>(
                        "SparkEffect")).Clone() as T2DParticleEffect;
                if (sparksEffect != null)
                {
                    sparksEffect.Position = info.Position;
                    sparksEffect.Rotation = T2DVectorUtil.AngleFromVector(info.Normal);
                    sparksEffect.Size = new Vector2(10.0f, 10.0f);
                    Owner.Manager.Register(sparksEffect);
                }

                MindcraftersComponentsLibrary.SoundBank.PlayCue("explodeTank");
            }
            else
            {
                // Trigger smoke
                T2DParticleEffect smokeEffect =
                    (TorqueObjectDatabase.Instance.FindObject<T2DParticleEffect>(
                        "SmokeEffect")).Clone() as T2DParticleEffect;
                if (smokeEffect != null)
                {
                    smokeEffect.Position = info.Position;

                    // For non-tank hit ie: barriers, we do a little
                    // calculation so that glancing blows look like they carry
                    // the momentum of the shell while more direct shots
                    // reflect back towards the direction the shell came from.
                    Vector2 I = SceneObject.Physics.Velocity;
                    I.Normalize();
                    Vector2 R =
                        I - (Vector2.Dot(2.0f * I, info.Normal) * info.Normal);
                    float dot = Vector2.Dot(info.Normal, -I);
                    smokeEffect.Rotation =
                        T2DVectorUtil.AngleFromVector(dot * -I + (1.0f - dot) * R);

                    smokeEffect.Size = new Vector2(10.0f, 10.0f);
                    Owner.Manager.Register(smokeEffect);
                }

                MindcraftersComponentsLibrary.SoundBank.PlayCue("explodeBarrier");
            }

            // Stop the projectile's playing sound on the parent object.
            // It is stored there to allow the sound to quickly fade rather
            // than just cut off when the projectile object is unregistered.
            MainGunComponent mgc =
                _parentObj.Components.FindComponent<MainGunComponent>();
            if (mgc != null)
            {
                mgc.StopProjectileSound(_projectileSoundRef);
            }

            // Clean up the projectile.
            if (DestroyOnCollision)
                Owner.MarkForDelete = true;
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the melee scene object and enemies
        /// </summary>
        /// <param name="myObject">The melee scene object mounted on the player</param>
        /// <param name="theirObject">The enemy scene object</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();
            int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage;

            // Deal damage to the enemy
            if(actor != null)
                actor.TakeDamage(damage, myObject, true, true);

            myObject.MarkForDelete = true;
        }
        public virtual void ResolveActorCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
        {
            // this is a custom collision response mode for actors
            // make sure this method is being used on an Actor
            if (!ourObject.TestObjectType(PlatformerData.ActorObjectType))
                return;

            // make sure it's the right actor
            ActorComponent actor = ourObject.Components.FindComponent<ActorComponent>();
            if (actor == null)
                return;

            // check for a physics component
            if (_actor.Physics == null)
                return;

            // get their object's velocity
            Vector2 theirVel = Vector2.Zero;

            if (theirObject.Physics != null)
                theirVel = theirObject.Physics.Velocity;

            // check if it's a ground surface
            bool groundSurface = info.Normal.Y <= _maxGroundNormalY;

            // get the actor's velocity modified velocity by the destination object's velocity
            Vector2 vel = _actor.Physics.Velocity - theirVel;

            //get the dot product
            float dot = Vector2.Dot(vel, info.Normal);

            // if we're currently on the ground, do magical stuff
            if (_onGround && !groundSurface)
            {
                // don't let the clamp push us off the ground or into the ground!
                // accomplish this by clamping the collision normal against the ground normal
                float groundDot = Vector2.Dot(info.Normal, _groundSurfaceNormal);

                // remove any portion of the ground surface normal from the collision normal
                info.Normal -= groundDot * _groundSurfaceNormal;

                // cancel move speed (this isn't a ground surface that we hit)
                _moveSpeed.X = 0;
            }

            // return if we're moving away from the surface
            if (dot >= 0.0f)
                return;

            // if object was not a ground surface...
            if (!groundSurface)
            {
                // notify the controller that we hit a wall
                if (Controller as ActorController != null)
                    (Controller as ActorController).ActorHitWall(this, info, dot);

                // forfeit all inherited velocity
                // (we ran into something, just get rid of it!)
                _inheritedVelocity = Vector2.Zero;
            }
            else
            {
                // if we actually overlapped with a platform, correct by a small amount (1/10 of a unit)
                // (the purpose of _groundYBuffer is to avoid constant collisions from scraping across the ground.
                // if we are colliding with the ground regularly, _groundYBuffer is too low. this error correction
                // is intended to solve potential problems when prolonged penetration occurs.)
                _platformError += info.Normal * 0.1f;
            }

            // clamp our actial velocity anyway
            _actor.Physics.Velocity -= dot * info.Normal;

            // if we're not on the ground, just dump our velocity into our move speed
            // and let the actor's physics clamp it
            if (!_onGround)
                _moveSpeed.X = _actor.Physics.Velocity.X;
        }
        protected static void _resolveRigid(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
        {
            Assert.Fatal(ourObject.Physics != null, "Cannot use rigid collision response without physics component");
            Assert.Fatal((theirObject != null && theirObject.Physics != null) || !handleBoth, "Cannot use rigid collision response without physics component");

            //------------------------------------------------------------------------------------------------------
            // Fetch information.
            //------------------------------------------------------------------------------------------------------

            // collision normal
            Vector2 normal = -info.Normal;

            // Positions
            Vector2 srcPosition = ourObject.Position;
            Vector2 dstPosition = theirObject != null ? theirObject.Position : Vector2.Zero;

            // Velocities
            Vector2 srcVelocity = ourObject.Physics.Velocity;
            Vector2 dstVelocity = Vector2.Zero;

            // Angular Velocities.
            float srcAngularVelocity = MathHelper.ToRadians(-ourObject.Physics.AngularVelocity);
            float dstAngularVelocity = 0.0f;

            // Friction/Restitution.
            float friction = physicsMaterial.Friction;
            float restitution = physicsMaterial.Restitution;

            // Inverse Masses.
            float srcInverseMass = ourObject.Physics.InverseMass;
            float dstInverseMass = 0.0f;

            // Inverse Inertial Moments.
            float srcInverseInertialMoment = ourObject.Physics.InverseRotationalInertia;
            float dstInverseInertialMoment = 0.0f;

            if (theirObject != null && theirObject.Physics != null)
            {
                dstVelocity = theirObject.Physics.Velocity;
                dstAngularVelocity = MathHelper.ToRadians(-theirObject.Physics.AngularVelocity);
                dstInverseMass = theirObject.Physics.InverseMass;
                dstInverseInertialMoment = theirObject.Physics.InverseRotationalInertia;
            }

            //------------------------------------------------------------------------------------------------------
            // Contact info.
            //------------------------------------------------------------------------------------------------------

            // Contact Velocity.
            Vector2 srcContactDelta = info.Position - srcPosition;
            Vector2 dstContactDelta = info.Position - dstPosition;
            Vector2 srcContactDeltaPerp = new Vector2(-srcContactDelta.Y, srcContactDelta.X);
            Vector2 dstContactDeltaPerp = new Vector2(-dstContactDelta.Y, dstContactDelta.X);
            Vector2 srcVP = srcVelocity - srcAngularVelocity * srcContactDeltaPerp;
            Vector2 dstVP = dstVelocity - dstAngularVelocity * dstContactDeltaPerp;

            //------------------------------------------------------------------------------------------------------
            // Calculate Impact Velocity.
            //------------------------------------------------------------------------------------------------------
            Vector2 deltaImpactVelocity = dstVP - srcVP;
            float deltaVelocityDot = Vector2.Dot(deltaImpactVelocity, normal);

            // Are we seperated?
            if (deltaVelocityDot > 0.0f)
                // Yes, so no interaction!
                return;

            // Normalise velocity.
            Vector2 Vn = deltaVelocityDot * normal;
            Vector2 Vt = deltaImpactVelocity - Vn;
            float vt = Vt.Length();
            Vector2 VtDir = Vt;
            if (vt > 0.0f)
                VtDir *= 1.0f / vt;

            //------------------------------------------------------------------------------------------------------
            // Calculate Impulse ( Dynamic-Friction and Restitution )
            //------------------------------------------------------------------------------------------------------

            // Break Impulse Function Down a little...
            float srcRN = Collision2D.PerpDot(srcContactDelta, normal);
            float dstRN = Collision2D.PerpDot(dstContactDelta, normal);
            float t0 = srcRN * srcRN * srcInverseInertialMoment;
            float t1 = dstRN * dstRN * dstInverseInertialMoment;
            float denom = srcInverseMass + dstInverseMass + t0 + t1;
            // handle two non-rotating, non-moving objects colliding (two platforms?)
            float jn = Math.Abs(denom) > Epsilon.Value ? deltaVelocityDot / denom : 0.0f;

            // Calculate Impulse (include restitution/dynamic friction).
            Vector2 impulseForce = ((-(1.0f + restitution) * jn) * normal) + ((friction * jn) * VtDir);

            //------------------------------------------------------------------------------------------------------
            // Changes in Momentum ( Linear and Angular ).
            //------------------------------------------------------------------------------------------------------

            // Calculate Linear Acceleration.
            Vector2 srcLinearDelta = -impulseForce * srcInverseMass;
            Vector2 dstLinearDelta = impulseForce * dstInverseMass;
            // Calculate Angular Acceleration.
            float srcAngularDelta = Collision2D.PerpDot(srcContactDelta, impulseForce) * srcInverseInertialMoment;
            float dstAngularDelta = -Collision2D.PerpDot(dstContactDelta, impulseForce) * dstInverseInertialMoment;

            //------------------------------------------------------------------------------------------------------
            // Finally, apply acceleration.
            //------------------------------------------------------------------------------------------------------

            ourObject.Physics.Velocity += srcLinearDelta;
            ourObject.Physics.AngularVelocity -= MathHelper.ToDegrees(srcAngularDelta);
            if (handleBoth)
            {
                theirObject.Physics.Velocity += dstLinearDelta;
                theirObject.Physics.AngularVelocity -= MathHelper.ToDegrees(dstAngularDelta);
            }
        }
        /// <summary>
        /// Derived classes should add collision points to 'list' using this method, which guarantees that duplicates are not added and that the list is proprly
        /// reset when earlier collisions are detected.
        /// </summary>
        protected void _AddCollisionPoint(ref float dt, float collisionTime, Vector2 pos, Vector2 norm, Vector2 penetration, T2DSceneObject obj, int matidx, List<T2DCollisionInfo> list)
        {
            float MIN_COINCIDENT_TIME = 0.0005f;
            if (collisionTime < 0.0f)
                collisionTime = 0.0f;
            if (collisionTime < dt + MIN_COINCIDENT_TIME)
            {
                if (collisionTime < dt - MIN_COINCIDENT_TIME)
                {
                    // prior collision, restart list and decrease dt
                    list.Clear();
                    dt = collisionTime;
                }

                // add collision to list
                T2DCollisionInfo info = new T2DCollisionInfo();
                info.Position = pos;
                info.Normal = norm;
                info.Penetration = penetration;
                info.SceneObject = obj;
                info.MaterialIndex = matidx;
                list.Add(info);

                // save some debug info
                _keepCollision = 1000; // 1000 frames
                _lastCollisionPoint = pos;
                _lastCollisionNormal = norm;
            }
        }
 /// <summary>
 /// Called from an actor possessed by this controller each time it collides with a wall or ceiling.
 /// (as defined on a per-actor basis by the ActorComponent's _maxSurfaceNormalY field).
 /// </summary>
 /// <param name="actor">The possessed ActorComponent that hit a wall.</param>
 /// <param name="info">The collision info for the collision that lead to this callback.</param>
 /// <param name="dot">Dot product of the velocity and the normal.</param>
 public virtual void ActorHitWall(ActorComponent actor, T2DCollisionInfo info, float dot)
 {
 }
 public void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
 {
     // call our local trigger OnEnter method
     _onEnter(ourObject, theirObject, info);
 }
 /// <summary>
 /// The _onEnter callback that's called whenever an obejct collides with this trigger.
 /// </summary>
 /// <param name="ourObject">The owner of this trigger component.</param>
 /// <param name="theirObject">The object that collided with this trigger.</param>
 /// <param name="info">The collision info generated for the collision.</param>
 protected virtual void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
 {
 }
        /// <summary>
        /// Performs a specialized collision check against the specified object using our ground check collision polyon.
        /// </summary>
        /// <param name="obj">The object to check collision against.</param>
        /// <returns>A list of collisions that occured with the object.</returns>
        private void _testGroundPolyMove(T2DSceneObject obj)
        {
            // clear the Actor's ground collision list for the new check
            _groundCollisionList.Clear();

            // grab their collision component
            T2DCollisionComponent theirCollider = obj.Collision;

            // if it doesnt have a collision component we don't care about it
            if (theirCollider == null)
                return;

            // always check based on a full tick
            float elapsed = 0.03f;

            // vars for moving poly - poly check
            float collisionTime = 0.0f;
            Vector2 collisionNormal = Vector2.Zero;
            Vector2 collisionPoint = Vector2.Zero;
            Vector2 collisionPenetration = Vector2.Zero;

            // use a position shifted up by the height of the ground check poly
            // (the poly itself is based below the actor, so this actually puts the bottom of it at the bottom of the actor's poly)
            Vector2 ourPos = new Vector2(_actor.Position.X, _actor.Position.Y - (_groundCheckYThreshold * 4));

            // use a velocity that will allow the poly to pass from it's current position
            // to a position exactly below where the actor's feet will be
            // (divide by threshold elapsed here to get the full distance in one tick)
            Vector2 ourVel = new Vector2(_actor.Physics.VelocityX, Math.Abs(_actor.Physics.VelocityY) + ((_groundCheckYThreshold * 4) / elapsed));

            // iterate the object's images
            for (int i = 0; i < obj.Collision.Images.Count; i++)
            {
                // grab this collision image
                T2DPolyImage theirImage = obj.Collision.Images[i] as T2DPolyImage;

                // if this isn't a poly image, skip it
                // (when new image types arise, add an if structure here)
                if (theirImage == null)
                    continue;

                // call the intersect function to do the math for us
                bool collisionTest = Collision2D.IntersectMovingPolyPoly(
                    elapsed, _GroundPolyImage.CollisionPoly, theirImage.CollisionPoly,
                    ourPos, theirImage.SceneObject.Position,
                    _GroundPolyImage.SceneObject.Rotation, theirImage.SceneObject.Rotation,
                    ourVel, Vector2.Zero,
                    ref collisionPoint, ref collisionNormal, ref collisionPenetration, ref collisionTime);

                // if the collision test came back positive...
                if (collisionTest)
                {
                    // skip platforms if the collision surface isn't facing 'upwards' at all
                    if (collisionNormal.Y >= 0)
                        continue;

                    // create a new collision info structure and add it to the list so we can return it
                    T2DCollisionInfo newInfo = new T2DCollisionInfo();
                    newInfo.Normal = collisionNormal;
                    newInfo.Penetration = collisionPenetration;
                    newInfo.Position = collisionPoint + (collisionPenetration / 2);
                    _groundCollisionList.Add(newInfo);
                }
            }
        }
 protected static void _resolveClamp(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
 {
     if (ourObject.Physics != null)
     {
         float dot = Vector2.Dot(ourObject.Physics.Velocity, info.Normal);
         if (dot < 0.0f)
             ourObject.Physics.Velocity = ourObject.Physics.Velocity - dot * info.Normal;
     }
     if (handleBoth && theirObject.Physics != null)
     {
         float dot = Vector2.Dot(theirObject.Physics.Velocity, -info.Normal);
         if (dot < 0.0f)
             theirObject.Physics.Velocity = theirObject.Physics.Velocity + dot * info.Normal;
     }
 }
 protected static void _resolveKill(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
 {
     ourObject.MarkForDelete = true;
     if (handleBoth)
         theirObject.MarkForDelete = true;
 }
        /// <summary>
        /// Resolve world limit collision.  Typically called by T2DPhysicsComponent.
        /// </summary>
        /// <param name="info">Current collision information.</param>
        public void ResolveWorldLimitCollision(T2DCollisionInfo info)
        {
            T2DResolveCollisionDelegate resolve = WorldLimitResolveCollision;
            T2DOnCollisionDelegate onCollision = OnWorldLimit;
            T2DCollisionMaterial physicsMaterial = T2DPhysicsComponent.DefaultCollisionMaterial;
            if (SceneObject.Collision != null && SceneObject.Collision.CollisionMaterial != null)
                physicsMaterial = SceneObject.Collision.CollisionMaterial;

            // on collision, on resolve...
            if (onCollision != null)
                onCollision(SceneObject, null, info, ref resolve, ref physicsMaterial);
            Assert.Fatal(physicsMaterial != null, "OnWorldLimitCollision nulled out physics material");
            if (resolve != null)
                resolve(SceneObject, null, ref info, physicsMaterial, false);
        }
 protected static void _resolveSticky(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
 {
     if (ourObject.Physics != null)
     {
         ourObject.Physics.Velocity = new Vector2(0, 0);
         ourObject.Physics.AngularVelocity = 0;
     }
     if (handleBoth && theirObject.Physics != null)
     {
         theirObject.Physics.Velocity = new Vector2(0, 0);
         theirObject.Physics.AngularVelocity = 0;
     }
 }
        public virtual void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            // call our custom collision resolve
            // (this is almost exactly the same as clamp, but takes *both* objects' velocity into account)
            if (theirObject.TestObjectType(PlatformerData.PlatformObjectType))
                resolve = ResolveActorCollision;
            else
                resolve = null;

            // if we hit a ladder, enable it
            if (theirObject.TestObjectType(PlatformerData.LadderObjectType))
            {
                // find the ladder component
                LadderComponent ladder = theirObject.Components.FindComponent<LadderComponent>();

                // enable it
                if (ladder != null)
                    ladder.Enabled = true;
            }
        }