Пример #1
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = ContactFlags.Enabled;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            NodeA.Contact = null;
            NodeA.Prev    = null;
            NodeA.Next    = null;
            NodeA.Other   = null;

            NodeB.Contact = null;
            NodeB.Prev    = null;
            NodeB.Next    = null;
            NodeB.Other   = null;

            TOICount = 0;

            //FPE: We only set the friction and restitution if we are not destroying the contact
            if (FixtureA != null && FixtureB != null)
            {
                Friction    = Settings.MixFriction(FixtureA.Friction, FixtureB.Friction);
                Restitution = Settings.MixRestitution(FixtureA.Restitution, FixtureB.Restitution);
            }

            TangentSpeed = 0;
        }
Пример #2
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = ContactFlags.Enabled;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev    = null;
            NodeA.Next    = null;
            NodeA.Other   = null;

            NodeB.Contact = null;
            NodeB.Prev    = null;
            NodeB.Next    = null;
            NodeB.Other   = null;

            TOICount = 0;
        }
Пример #3
0
        protected Contact(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            m_flags = ContactFlags.e_enabledFlag;

            m_fixtureA = fA;
            m_fixtureB = fB;

            m_indexA = indexA;
            m_indexB = indexB;

            m_manifold = new Manifold();
            m_manifold.points.Clear();

            m_nodeA.contact = null;
            m_nodeA.other   = null;

            m_nodeB.contact = null;
            m_nodeB.other   = null;

            m_toiCount = 0;

            m_friction    = MixFriction(m_fixtureA.m_friction, m_fixtureB.m_friction);
            m_restitution = MixRestitution(m_fixtureA.m_restitution, m_fixtureB.m_restitution);

            m_tangentSpeed = 0.0f;
        }
Пример #4
0
        /// <summary>
        /// initialization for pooling
        /// </summary>
        public virtual void Init(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = 0;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev    = null;
            NodeA.Next    = null;
            NodeA.Other   = null;

            NodeB.Contact = null;
            NodeB.Prev    = null;
            NodeB.Next    = null;
            NodeB.Other   = null;

            ToiCount    = 0;
            Friction    = MixFriction(fA.Friction, fB.Friction);
            Restitution = MixRestitution(fA.Restitution, fB.Restitution);

            TangentSpeed = 0;
        }
Пример #5
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            this.Flags = ContactFlags.Enabled;

            this.FixtureA = fA;
            this.FixtureB = fB;

            this.ChildIndexA = indexA;
            this.ChildIndexB = indexB;

            this.Manifold.PointCount = 0;

            this.NodeA.Contact = null;
            this.NodeA.Prev    = null;
            this.NodeA.Next    = null;
            this.NodeA.Other   = null;

            this.NodeB.Contact = null;
            this.NodeB.Prev    = null;
            this.NodeB.Next    = null;
            this.NodeB.Other   = null;

            this.TOICount = 0;
        }
Пример #6
0
 /// <summary>
 /// Enable this contact.
 /// </summary>
 public void Enable()
 {
     Flags |= ContactFlags.Enabled;
 }
Пример #7
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="contactManager">The contact manager.</param>
        internal void Update(ContactManager contactManager)
        {
            Manifold oldManifold = Manifold;

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensor = FixtureA.IsSensor || FixtureB.IsSensor;

            Body bodyA = FixtureA.Body;
            Body bodyB = FixtureB.Body;

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = AABB.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, ref bodyA.Xf, ref bodyB.Xf);

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

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

                    for (int j = 0; j < oldManifold.PointCount; ++j)
                    {
                        ManifoldPoint 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)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false)
            {
                if (touching)
                {

            #if true
                    bool enabledA, enabledB;

                    // Report the collision to both participants. Track which ones returned true so we can
                    // later call OnSeparation if the contact is disabled for a different reason.
                    if (FixtureA.OnCollision != null)
                        enabledA = FixtureA.OnCollision(FixtureA, FixtureB, this);
                    else
                        enabledA = true;

                    // Reverse the order of the reported fixtures. The first fixture is always the one that the
                    // user subscribed to.
                    if (FixtureB.OnCollision != null)
                        enabledB = FixtureB.OnCollision(FixtureB, FixtureA, this);
                    else
                        enabledB = true;

                    Enabled = enabledA && enabledB;

                    // BeginContact can also return false and disable the contact
                    if (enabledA && enabledB && contactManager.BeginContact != null)
                    {
                        Enabled = contactManager.BeginContact(this);
                    }

                    // If the user disabled the contact (needed to exclude it in TOI solver) at any point by
                    // any of the callbacks, we need to mark it as not touching and call any separation
                    // callbacks for fixtures that didn't explicitly disable the collision.
                    if (!Enabled)
                    {
                        Flags &= ~ContactFlags.Touching;
                    }

            #else
                    //Report the collision to both participants:
                    if (FixtureA.OnCollision != null)
                        Enabled = FixtureA.OnCollision(FixtureA, FixtureB, this);

                    //Reverse the order of the reported fixtures. The first fixture is always the one that the
                    //user subscribed to.
                    if (FixtureB.OnCollision != null)
                        Enabled = FixtureB.OnCollision(FixtureB, FixtureA, this);

                    //BeginContact can also return false and disable the contact
                    if (contactManager.BeginContact != null)
                        Enabled = contactManager.BeginContact(this);

                    //if the user disabled the contact (needed to exclude it in TOI solver), we also need to mark
                    //it as not touching.
                    if (Enabled == false)
                        Flags &= ~ContactFlags.Touching;
            #endif
                }
            }
            else
            {
                if (touching == false)
                {
                    //Report the separation to both participants:
                    if (FixtureA != null && FixtureA.OnSeparation != null)
                        FixtureA.OnSeparation(FixtureA, FixtureB);

                    //Reverse the order of the reported fixtures. The first fixture is always the one that the
                    //user subscribed to.
                    if (FixtureB != null && FixtureB.OnSeparation != null)
                        FixtureB.OnSeparation(FixtureB, FixtureA);

                    if (contactManager.EndContact != null)
                        contactManager.EndContact(this);
                }
            }

            if (sensor)
                return;

            if (contactManager.PreSolve != null)
                contactManager.PreSolve(this, ref oldManifold);
        }
Пример #8
0
 /// <summary>
 /// Enable this contact.
 /// </summary>
 public void Enable()
 {
     Flags |= ContactFlags.Enabled;
 }
Пример #9
0
 void SetFlag(ContactFlags flag, bool value)
 {
     Flags = value ? (Flags | flag) : (Flags & ~flag);
 }
Пример #10
0
		// Update the contact manifold and touching status.
		// Note: do not assume the fixture AABBs are overlapping or are valid.
		internal void Update(ContactListener listener){
			Manifold oldManifold = m_manifold;

			// Re-enable this contact.
			m_flags |= ContactFlags.e_enabledFlag;

			bool touching = false;
			bool wasTouching = (m_flags & ContactFlags.e_touchingFlag) == ContactFlags.e_touchingFlag;

			bool sensorA = m_fixtureA.IsSensor;
			bool sensorB = m_fixtureB.IsSensor;
			bool sensor = sensorA || sensorB;

			Body bodyA = m_fixtureA.GetBody();
			Body bodyB = m_fixtureB.GetBody();
			Transform xfA = bodyA.GetTransform();
			Transform xfB = bodyB.GetTransform();

			// Is this contact a sensor?
			if (sensor)
			{
			    Shape shapeA = m_fixtureA.GetShape();
			    Shape shapeB = m_fixtureB.GetShape();
			    touching = Collision.TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB);

			    // Sensors don't generate manifolds.
				m_manifold.points.Clear();
			}
			else
			{
			    Evaluate(out m_manifold, xfA, xfB);
			    touching = m_manifold.points.Count() > 0;

			    // Match old contact ids to new contact ids and copy the
			    // stored impulses to warm start the solver.
			    for (int i = 0; i < m_manifold.points.Count(); ++i)
			    {
					ManifoldPoint mp2 = m_manifold.points[i];
					mp2.normalImpulse = 0.0f;
					mp2.tangentImpulse = 0.0f;
					ContactID id2 = mp2.id;

					for (int j = 0; j < oldManifold.points.Count(); ++j) {
						ManifoldPoint mp1 = oldManifold.points[j];

						if (mp1.id.key == id2.key) {
							mp2.normalImpulse = mp1.normalImpulse;
							mp2.tangentImpulse = mp1.tangentImpulse;
							break;
						}
					}
			    }

			    if (touching != wasTouching)
			    {
			        bodyA.SetAwake(true);
			        bodyB.SetAwake(true);
			    }
			}

			if (touching)
			{
			    m_flags |= ContactFlags.e_touchingFlag;
			}
			else
			{
				m_flags &= ~ContactFlags.e_touchingFlag;
			}

			if (wasTouching == false && touching == true && listener != null)
			{
			    listener.BeginContact(this);
			}

			if (wasTouching == true && touching == false && listener != null)
			{
			    listener.EndContact(this);
			}

			if (sensor == false && touching && listener != null)
			{
			    listener.PreSolve(this, oldManifold);
			}
		}
Пример #11
0
		protected Contact(Fixture fA, int indexA, Fixture fB, int indexB) {
			m_flags = ContactFlags.e_enabledFlag;

			m_fixtureA = fA;
			m_fixtureB = fB;

			m_indexA = indexA;
			m_indexB = indexB;

			m_manifold = new Manifold();
			m_manifold.points.Clear();

			m_nodeA.contact = null;
			m_nodeA.other = null;

			m_nodeB.contact = null;
			m_nodeB.other = null;

			m_toiCount = 0;

			m_friction = MixFriction(m_fixtureA.m_friction, m_fixtureB.m_friction);
			m_restitution = MixRestitution(m_fixtureA.m_restitution, m_fixtureB.m_restitution);

			m_tangentSpeed = 0.0f;
		}
Пример #12
0
		public abstract void Evaluate(out Manifold manifold, Transform xfA, Transform xfB); //manifold was pointer

		

		/// Flag this contact for filtering. Filtering will occur the next time step.
		internal void FlagForFiltering(){
			m_flags |= ContactFlags.e_filterFlag;
		}
Пример #13
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="contactManager">The contact manager.</param>
        internal void Update(FSContactManager contactManager)
        {
            Manifold oldManifold = Manifold;

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensor = FixtureA.IsSensor || FixtureB.IsSensor;

            FSBody bodyA = FixtureA.Body;
            FSBody bodyB = FixtureB.Body;

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = AABB.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, ref bodyA.Xf, ref bodyB.Xf);

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

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

                    for (int j = 0; j < oldManifold.PointCount; ++j)
                    {
                        ManifoldPoint 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)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false)
            {
                if (touching)
                {
#if true
                    bool enabledA, enabledB;

                    // Report the collision to both participants. Track which ones returned true so we can
                    // later call OnSeparation if the contact is disabled for a different reason.
                    if (FixtureA.OnCollision != null)
                    {
                        enabledA = FixtureA.OnCollision(FixtureA, FixtureB, this);
                    }
                    else
                    {
                        enabledA = true;
                    }

                    // Reverse the order of the reported fixtures. The first fixture is always the one that the
                    // user subscribed to.
                    if (FixtureB.OnCollision != null)
                    {
                        enabledB = FixtureB.OnCollision(FixtureB, FixtureA, this);
                    }
                    else
                    {
                        enabledB = true;
                    }

                    Enabled = enabledA && enabledB;

                    // BeginContact can also return false and disable the contact
                    if (enabledA && enabledB && contactManager.BeginContact != null)
                    {
                        Enabled = contactManager.BeginContact(this);
                    }

                    // If the user disabled the contact (needed to exclude it in TOI solver) at any point by
                    // any of the callbacks, we need to mark it as not touching and call any separation
                    // callbacks for fixtures that didn't explicitly disable the collision.
                    if (!Enabled)
                    {
                        Flags &= ~ContactFlags.Touching;
                    }
#else
                    //Report the collision to both participants:
                    if (FixtureA.OnCollision != null)
                    {
                        Enabled = FixtureA.OnCollision(FixtureA, FixtureB, this);
                    }

                    //Reverse the order of the reported fixtures. The first fixture is always the one that the
                    //user subscribed to.
                    if (FixtureB.OnCollision != null)
                    {
                        Enabled = FixtureB.OnCollision(FixtureB, FixtureA, this);
                    }

                    //BeginContact can also return false and disable the contact
                    if (contactManager.BeginContact != null)
                    {
                        Enabled = contactManager.BeginContact(this);
                    }

                    //if the user disabled the contact (needed to exclude it in TOI solver), we also need to mark
                    //it as not touching.
                    if (Enabled == false)
                    {
                        Flags &= ~ContactFlags.Touching;
                    }
#endif
                }
            }
            else
            {
                if (touching == false)
                {
                    //Report the separation to both participants:
                    if (FixtureA != null && FixtureA.OnSeparation != null)
                    {
                        FixtureA.OnSeparation(FixtureA, FixtureB);
                    }

                    //Reverse the order of the reported fixtures. The first fixture is always the one that the
                    //user subscribed to.
                    if (FixtureB != null && FixtureB.OnSeparation != null)
                    {
                        FixtureB.OnSeparation(FixtureB, FixtureA);
                    }

                    if (contactManager.EndContact != null)
                    {
                        contactManager.EndContact(this);
                    }
                }
            }

            if (sensor)
            {
                return;
            }

            if (contactManager.PreSolve != null)
            {
                contactManager.PreSolve(this, ref oldManifold);
            }
        }
Пример #14
0
        // Update the contact manifold and touching status.
        // Note: do not assume the fixture AABBs are overlapping or are valid.
        internal void Update(ContactListener listener)
        {
            Manifold oldManifold = m_manifold;

            // Re-enable this contact.
            m_flags |= ContactFlags.e_enabledFlag;

            bool touching    = false;
            bool wasTouching = (m_flags & ContactFlags.e_touchingFlag) == ContactFlags.e_touchingFlag;

            bool sensorA = m_fixtureA.IsSensor;
            bool sensorB = m_fixtureB.IsSensor;
            bool sensor  = sensorA || sensorB;

            Body      bodyA = m_fixtureA.GetBody();
            Body      bodyB = m_fixtureB.GetBody();
            Transform xfA   = bodyA.GetTransform();
            Transform xfB   = bodyB.GetTransform();

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = m_fixtureA.GetShape();
                Shape shapeB = m_fixtureB.GetShape();
                touching = Collision.TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB);

                // Sensors don't generate manifolds.
                m_manifold.points.Clear();
            }
            else
            {
                Evaluate(out m_manifold, xfA, xfB);
                touching = m_manifold.points.Count() > 0;

                // Match old contact ids to new contact ids and copy the
                // stored impulses to warm start the solver.
                for (int i = 0; i < m_manifold.points.Count(); ++i)
                {
                    ManifoldPoint mp2 = m_manifold.points[i];
                    mp2.normalImpulse  = 0.0f;
                    mp2.tangentImpulse = 0.0f;
                    ContactID id2 = mp2.id;

                    for (int j = 0; j < oldManifold.points.Count(); ++j)
                    {
                        ManifoldPoint mp1 = oldManifold.points[j];

                        if (mp1.id.key == id2.key)
                        {
                            mp2.normalImpulse  = mp1.normalImpulse;
                            mp2.tangentImpulse = mp1.tangentImpulse;
                            break;
                        }
                    }
                }

                if (touching != wasTouching)
                {
                    bodyA.SetAwake(true);
                    bodyB.SetAwake(true);
                }
            }

            if (touching)
            {
                m_flags |= ContactFlags.e_touchingFlag;
            }
            else
            {
                m_flags &= ~ContactFlags.e_touchingFlag;
            }

            if (wasTouching == false && touching == true && listener != null)
            {
                listener.BeginContact(this);
            }

            if (wasTouching == true && touching == false && listener != null)
            {
                listener.EndContact(this);
            }

            if (sensor == false && touching && listener != null)
            {
                listener.PreSolve(this, oldManifold);
            }
        }
Пример #15
0
 /// <summary>
 /// Enable/disable this contact. This can be used inside the pre-solve
 /// contact listener. The contact is only disabled for the current
 /// time step (or sub-step in continuous collisions).
 /// </summary>
 /// <param name="flag"></param>
 public void SetEnabled(bool flag)
 {
     if (flag)
     {
         _flags |= ContactFlags.Enabled;
     }
     else
     {
         _flags &= ~ContactFlags.Enabled;
     }
 }
Пример #16
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = ContactFlags.Enabled;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev = null;
            NodeA.Next = null;
            NodeA.Other = null;

            NodeB.Contact = null;
            NodeB.Prev = null;
            NodeB.Next = null;
            NodeB.Other = null;

            TOICount = 0;
        }
Пример #17
0
        internal void Reset(Fixture fA, Fixture fB)
        {
            _flags = ContactFlags.Enabled;

            _fixtureA = fA;
            _fixtureB = fB;

            _manifold._pointCount = 0;

            _prev = null;
            _next = null;

            _nodeA.Contact = null;
            _nodeA.Prev = null;
            _nodeA.Next = null;
            _nodeA.Other = null;

            _nodeB.Contact = null;
            _nodeB.Prev = null;
            _nodeB.Next = null;
            _nodeB.Other = null;

            _toiCount = 0;
        }
Пример #18
0
        public void Update(IContactListener listener)
        {
            oldManifold.Set(Manifold);

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensorA = FixtureA.Sensor;
            bool sensorB = FixtureB.Sensor;
            bool sensor  = sensorA || sensorB;

            Body      bodyA = FixtureA.Body;
            Body      bodyB = FixtureB.Body;
            Transform xfA   = bodyA.GetTransform();
            Transform xfB   = bodyB.GetTransform();

            // log.debug("TransformA: "+xfA);
            // log.debug("TransformB: "+xfB);

            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = Pool.GetCollision().TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, xfA, xfB);

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

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

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

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

                if (touching != wasTouching)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (listener == null)
            {
                return;
            }

            if (!wasTouching && touching)
            {
                listener.BeginContact(this);
            }

            if (wasTouching && !touching)
            {
                listener.EndContact(this);
            }

            if (!sensor && touching)
            {
                listener.PreSolve(this, oldManifold);
            }
        }
Пример #19
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="listener"></param>
        internal void Update(IContactListener listener)
        {
            Manifold oldManifold = _manifold;

            // Re-enable this contact.
            _flags |= ContactFlags.Enabled;

            bool touching = false;
            bool wasTouching = (_flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensorA = _fixtureA.IsSensor();
            bool sensorB = _fixtureB.IsSensor();
            bool sensor = sensorA || sensorB;

            Body bodyA = _fixtureA.GetBody();
            Body bodyB = _fixtureB.GetBody();
            Transform xfA; bodyA.GetTransform(out xfA);
            Transform xfB; bodyB.GetTransform(out xfB);

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = _fixtureA.GetShape();
                Shape shapeB = _fixtureB.GetShape();
                touching = AABB.TestOverlap(shapeA, shapeB, ref xfA, ref xfB);

                // Sensors don't generate manifolds.
                _manifold._pointCount = 0;
            }
            else
            {
                Evaluate(ref _manifold, ref xfA, ref xfB);
                touching = _manifold._pointCount > 0;

                // Match old contact ids to new contact ids and copy the
                // stored impulses to warm start the solver.
                for (int i = 0; i < _manifold._pointCount; ++i)
                {
                    ManifoldPoint mp2 = _manifold._points[i];
                    mp2.NormalImpulse = 0.0f;
                    mp2.TangentImpulse = 0.0f;
                    ContactID id2 = mp2.Id;

                    for (int j = 0; j < oldManifold._pointCount; ++j)
                    {
                        ManifoldPoint 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)
                {
                    bodyA.SetAwake(true);
                    bodyB.SetAwake(true);
                }
            }

            if (touching)
            {
                _flags |= ContactFlags.Touching;
            }
            else
            {
                _flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false && touching == true)
            {
                listener.BeginContact(this);
            }

            if (wasTouching == true && touching == false)
            {
                listener.EndContact(this);
            }

            if (sensor == false)
            {
                listener.PreSolve(this, ref oldManifold);
            }
        }
Пример #20
0
 /// <summary>
 /// Disable this contact.
 /// </summary>
 public void Disable()
 {
     Flags &= ~ContactFlags.Enabled;
 }
Пример #21
0
 void SetFlag(ContactFlags flag, bool value)
 {
     Flags = value ? (Flags | flag) : (Flags & ~flag);
 }
Пример #22
0
 /// <summary>
 /// Flag this contact for filtering. Filtering will occur the next time step.
 /// </summary>
 public void FlagForFiltering()
 {
     Flags |= ContactFlags.Filter;
 }
Пример #23
0
        /// <summary>
        /// initialization for pooling
        /// </summary>
        public virtual void Init(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = 0;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev = null;
            NodeA.Next = null;
            NodeA.Other = null;

            NodeB.Contact = null;
            NodeB.Prev = null;
            NodeB.Next = null;
            NodeB.Other = null;

            ToiCount = 0;
            Friction = MixFriction(fA.Friction, fB.Friction);
            Restitution = MixRestitution(fA.Restitution, fB.Restitution);

            TangentSpeed = 0;
        }
Пример #24
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = ContactFlags.Enabled;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            NodeA.Contact = null;
            NodeA.Prev = null;
            NodeA.Next = null;
            NodeA.Other = null;

            NodeB.Contact = null;
            NodeB.Prev = null;
            NodeB.Next = null;
            NodeB.Other = null;

            TOICount = 0;

            //FPE: We only set the friction and restitution if we are not destroying the contact
            if (FixtureA != null && FixtureB != null)
            {
                Friction = Settings.MixFriction(FixtureA.Friction, FixtureB.Friction);
                Restitution = Settings.MixRestitution(FixtureA.Restitution, FixtureB.Restitution);
            }

            TangentSpeed = 0;
        }
Пример #25
0
        public void Update(IContactListener listener)
        {
            oldManifold.Set(Manifold);

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensorA = FixtureA.Sensor;
            bool sensorB = FixtureB.Sensor;
            bool sensor = sensorA || sensorB;

            Body bodyA = FixtureA.Body;
            Body bodyB = FixtureB.Body;
            Transform xfA = bodyA.GetTransform();
            Transform xfB = bodyB.GetTransform();
            // log.debug("TransformA: "+xfA);
            // log.debug("TransformB: "+xfB);

            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = Pool.GetCollision().TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, xfA, xfB);

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

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

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

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

                if (touching != wasTouching)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (listener == null)
            {
                return;
            }

            if (!wasTouching && touching)
            {
                listener.BeginContact(this);
            }

            if (wasTouching && !touching)
            {
                listener.EndContact(this);
            }

            if (!sensor && touching)
            {
                listener.PreSolve(this, oldManifold);
            }
        }
Пример #26
0
 /// <summary>
 /// Disable this contact.
 /// </summary>
 public void Disable()
 {
     Flags &= ~ContactFlags.Enabled;
 }
Пример #27
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="contactManager">The contact manager.</param>
        internal void Update(ContactManager contactManager)
        {
            if (FixtureA == null || FixtureB == null)
            {
                return;
            }

            Body bodyA = FixtureA.Body;
            Body bodyB = FixtureB.Body;

            Manifold oldManifold = Manifold;

            // Re-enable this contact.
            _flags |= ContactFlags.EnabledFlag;

            bool touching;
            bool wasTouching = IsTouching;

            bool sensor = FixtureA.IsSensor || FixtureB.IsSensor;

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = Narrowphase.Collision.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, ref bodyA._xf, ref bodyB._xf);

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

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

                    for (int j = 0; j < oldManifold.PointCount; ++j)
                    {
                        ManifoldPoint 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)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                _flags |= ContactFlags.TouchingFlag;
            }
            else
            {
                _flags &= ~ContactFlags.TouchingFlag;
            }

            if (wasTouching == false && touching)
            {
                FixtureA.OnCollision?.Invoke(FixtureA, FixtureB, this);
                FixtureB.OnCollision?.Invoke(FixtureB, FixtureA, this);
                contactManager.BeginContact?.Invoke(this);

                // Velcro: If the user disabled the contact (needed to exclude it in TOI solver) at any point by
                // any of the callbacks, we need to mark it as not touching and call any separation
                // callbacks for fixtures that didn't explicitly disable the collision.
                if (!Enabled)
                {
                    touching = false;
                }
            }

            if (wasTouching == true && touching == false)
            {
                FixtureA?.OnSeparation?.Invoke(FixtureA, FixtureB, this);
                FixtureB?.OnSeparation?.Invoke(FixtureB, FixtureA, this);
                contactManager.EndContact?.Invoke(this);
            }

            if (sensor)
            {
                return;
            }

            contactManager.PreSolve?.Invoke(this, ref oldManifold);
        }
Пример #28
0
 /// <summary>
 /// Flag this contact for filtering. Filtering will occur the next time step.
 /// </summary>
 public void FlagForFiltering()
 {
     Flags |= ContactFlags.Filter;
 }
Пример #29
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="contactManager">The contact manager.</param>
        internal void Update(ContactManager contactManager)
        {
            Manifold oldManifold = Manifold;

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensorA = FixtureA.IsSensor;
            bool sensorB = FixtureB.IsSensor;
            bool sensor = sensorA || sensorB;

            Body bodyA = FixtureA.Body;
            Body bodyB = FixtureB.Body;
            Transform xfA;
            bodyA.GetTransform(out xfA);
            Transform xfB;
            bodyB.GetTransform(out xfB);

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = AABB.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, ref xfA, ref xfB);

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

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

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

                        if (mp1.Id.Key == id2.Key)
                        {
                            mp2.NormalImpulse = mp1.NormalImpulse;
                            mp2.TangentImpulse = mp1.TangentImpulse;
                            found = true;
                            break;
                        }
                    }
                    if (found == false)
                    {
                        mp2.NormalImpulse = 0.0f;
                        mp2.TangentImpulse = 0.0f;
                    }

                    Manifold.Points[i] = mp2;
                }

                if (touching != wasTouching)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false && touching)
            {
                // Report the collision to both participants:
                if (FixtureA.OnCollision != null)
                    Enabled = FixtureA.OnCollision(FixtureA, FixtureB, this);

                // Reverse the order of the reported fixtures. The first fixture is always the one that the
                // user subscribed to.
                if (FixtureB.OnCollision != null)
                    Enabled = FixtureB.OnCollision(FixtureB, FixtureA, this);

                // if the user disabled the contact (needed to exclude it in TOI solver), we also need to mark
                // it as not touching.
                if (Enabled == false)
                    Flags &= ~ContactFlags.Touching;

                if (contactManager.BeginContact != null)
                    contactManager.BeginContact(this);
            }

            if (wasTouching && touching == false)
            {
                // Report the separation to both participants:
                if (FixtureA.OnSeparation != null)
                    FixtureA.OnSeparation(FixtureA, FixtureB);

                // Reverse the order of the reported fixtures. The first fixture is always the one that the
                // user subscribed to.
                if (FixtureB.OnSeparation != null)
                    FixtureB.OnSeparation(FixtureB, FixtureA);

                if (contactManager.EndContact != null)
                    contactManager.EndContact(this);
            }

            if (sensor == false)
            {
                if (contactManager.PreSolve != null)
                    contactManager.PreSolve(this, ref oldManifold);
            }
        }
Пример #30
0
        /// <summary>
        /// Update the contact manifold and touching status.
        /// Note: do not assume the fixture AABBs are overlapping or are valid.
        /// </summary>
        /// <param name="contactManager">The contact manager.</param>
        internal void Update(ContactManager contactManager)
        {
            Manifold oldManifold = Manifold;

            // Re-enable this contact.
            Flags |= ContactFlags.Enabled;

            bool touching;
            bool wasTouching = (Flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensor = FixtureA.IsSensor || FixtureB.IsSensor;

            Body bodyA = FixtureA.Body;
            Body bodyB = FixtureB.Body;

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = FixtureA.Shape;
                Shape shapeB = FixtureB.Shape;
                touching = AABB.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, ref bodyA.Xf, ref bodyB.Xf);

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

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

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

                        if (mp1.Id.Key == id2.Key)
                        {
                            mp2.NormalImpulse  = mp1.NormalImpulse;
                            mp2.TangentImpulse = mp1.TangentImpulse;
                            found = true;
                            break;
                        }
                    }
                    if (found == false)
                    {
                        mp2.NormalImpulse  = 0.0f;
                        mp2.TangentImpulse = 0.0f;
                    }

                    Manifold.Points[i] = mp2;
                }

                if (touching != wasTouching)
                {
                    bodyA.Awake = true;
                    bodyB.Awake = true;
                }
            }

            if (touching)
            {
                Flags |= ContactFlags.Touching;
            }
            else
            {
                Flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false && touching)
            {
                //Report the collision to both participants:
                if (FixtureA.OnCollision != null)
                {
                    Enabled = FixtureA.OnCollision(FixtureA, FixtureB, this);
                }

                //Reverse the order of the reported fixtures. The first fixture is always the one that the
                //user subscribed to.
                if (FixtureB.OnCollision != null)
                {
                    Enabled = FixtureB.OnCollision(FixtureB, FixtureA, this);
                }

                //BeginContact can also return false and disable the contact
                if (contactManager.BeginContact != null)
                {
                    Enabled = contactManager.BeginContact(this);
                }

                //if the user disabled the contact (needed to exclude it in TOI solver), we also need to mark
                //it as not touching.
                if (Enabled == false)
                {
                    Flags &= ~ContactFlags.Touching;
                }
            }

            if (wasTouching && touching == false)
            {
                //Report the separation to both participants:
                if (FixtureA.OnSeparation != null)
                {
                    FixtureA.OnSeparation(FixtureA, FixtureB);
                }

                //Reverse the order of the reported fixtures. The first fixture is always the one that the
                //user subscribed to.
                if (FixtureB.OnSeparation != null)
                {
                    FixtureB.OnSeparation(FixtureB, FixtureA);
                }

                if (contactManager.EndContact != null)
                {
                    contactManager.EndContact(this);
                }
            }

            if (sensor)
            {
                return;
            }

            if (contactManager.PreSolve != null)
            {
                contactManager.PreSolve(this, ref oldManifold);
            }
        }
Пример #31
0
        public abstract void Evaluate(out Manifold manifold, Transform xfA, Transform xfB);         //manifold was pointer



        /// Flag this contact for filtering. Filtering will occur the next time step.
        internal void FlagForFiltering()
        {
            m_flags |= ContactFlags.e_filterFlag;
        }