Exemplo n.º 1
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="wake">Whether we should wake the bodies due to touching changing.</param>
        /// <returns>What current status of the contact is (e.g. start touching, end touching, etc.)</returns>
        internal ContactStatus Update(IPhysicsManager physicsManager, out bool wake)
        {
            PhysicsComponent bodyA = FixtureA !.Body;
            PhysicsComponent bodyB = FixtureB !.Body;

            var oldManifold = Manifold;

            // Re-enable this contact.
            Enabled = true;

            bool touching;
            var  wasTouching = IsTouching;

            wake = false;
            var sensor = !(FixtureA.Hard && FixtureB.Hard);

            var bodyATransform = physicsManager.GetTransform(bodyA);
            var bodyBTransform = physicsManager.GetTransform(bodyB);

            // Is this contact a sensor?
            if (sensor)
            {
                IPhysShape shapeA = FixtureA.Shape;
                IPhysShape shapeB = FixtureB.Shape;
                touching = _manifoldManager.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, bodyATransform, bodyBTransform);

                // Sensors don't generate manifolds.
                Manifold.PointCount = 0;
            }
            else
            {
                Evaluate(ref Manifold, bodyATransform, bodyBTransform);
                touching = Manifold.PointCount > 0;

                // Match old contact ids to new contact ids and copy the
                // stored impulses to warm start the solver.
                for (var i = 0; i < Manifold.PointCount; ++i)
                {
                    var mp2 = Manifold.Points[i];
                    mp2.NormalImpulse  = 0.0f;
                    mp2.TangentImpulse = 0.0f;
                    var id2 = mp2.Id;

                    for (var j = 0; j < oldManifold.PointCount; ++j)
                    {
                        var mp1 = oldManifold.Points[j];

                        if (mp1.Id.Key == id2.Key)
                        {
                            mp2.NormalImpulse  = mp1.NormalImpulse;
                            mp2.TangentImpulse = mp1.TangentImpulse;
                            break;
                        }
                    }

                    Manifold.Points[i] = mp2;
                }

                if (touching != wasTouching)
                {
                    wake = true;
                }
            }

            IsTouching = touching;
            var status = ContactStatus.NoContact;

            if (!wasTouching)
            {
                if (touching)
                {
                    status = ContactStatus.StartTouching;
                }
            }
            else
            {
                if (!touching)
                {
                    status = ContactStatus.EndTouching;
                }
            }

#if DEBUG
            if (!sensor)
            {
                _debugPhysics.HandlePreSolve(this, oldManifold);
            }
#endif

            return(status);
        }