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; }
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; }
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; }
/// <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; }
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; }
/// <summary> /// Enable this contact. /// </summary> public void Enable() { Flags |= ContactFlags.Enabled; }
/// <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); }
void SetFlag(ContactFlags flag, bool value) { Flags = value ? (Flags | flag) : (Flags & ~flag); }
// 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); } }
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; }
/// <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); } }
// 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); } }
/// <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; } }
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; }
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); } }
/// <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); } }
/// <summary> /// Disable this contact. /// </summary> public void Disable() { Flags &= ~ContactFlags.Enabled; }
/// <summary> /// Flag this contact for filtering. Filtering will occur the next time step. /// </summary> public void FlagForFiltering() { Flags |= ContactFlags.Filter; }
/// <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); }
/// <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); } }
/// <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); } }
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; }