/// <summary> /// Clears the contacts associated with this pair handler. /// </summary> public override void ClearContacts() { if (previousContactCount > 0) { //Just exited collision. //Remove the solver item. if (Parent != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableRemoved(ContactConstraint); } if (!suppressEvents) { var a = CollidableA; var b = CollidableB; a.EventTriggerer.OnCollisionEnded(b, this); b.EventTriggerer.OnCollisionEnded(a, this); } } ContactManifold.ClearContacts(); base.ClearContacts(); }
void IPairHandlerParent.RemoveSolverUpdateable(SolverUpdateable removedItem) { manifoldConstraintGroup.Remove(removedItem); //If this is the last child solver item, we need to remove ourselves from our parent too. if (manifoldConstraintGroup.SolverUpdateables.Count == 0) { if (Parent != null) { Parent.RemoveSolverUpdateable(manifoldConstraintGroup); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableRemoved(manifoldConstraintGroup); } } }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { //Deal with the remaining contacts. for (int i = ContactManifold.contacts.count - 1; i >= 0; i--) { OnContactRemoved(ContactManifold.contacts[i]); } //If the constraint is still in the solver, then request to have it removed. if (ContactConstraint.solver != null) { ContactConstraint.pair = null; //Setting the pair to null tells the constraint that it's going to be orphaned. It will be cleaned up on removal. if (Parent != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableRemoved(ContactConstraint); } } else { ContactConstraint.CleanUpReferences();//The constraint isn't in the solver, so we can safely clean it up directly. //Even though it's not in the solver, we still may need to notify the parent to remove it. if (Parent != null && ContactConstraint.SolverGroup != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } } ContactConstraint.CleanUp(); base.CleanUp(); ContactManifold.CleanUp(); //Child cleanup is responsible for cleaning up direct references to the involved collidables. }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { //Deal with the remaining contacts. for (int i = ContactManifold.contacts.Count - 1; i >= 0; i--) { OnContactRemoved(ContactManifold.contacts[i]); } //If the constraint is still in the solver, then request to have it removed. if (ContactConstraint.solver != null) { if (Parent != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableRemoved(ContactConstraint); } } else { //Even though it's not in the solver, we still may need to notify the parent to remove it. if (Parent != null && ContactConstraint.SolverGroup != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } } //Contact constraint cleanup changes the involved entities, which is acceptable because it's no longer in the solver. ContactConstraint.CleanUp(); base.CleanUp(); ContactManifold.CleanUp(); //Child cleanup is responsible for cleaning up direct references to the involved collidables. }
///<summary> /// Updates the pair handler. ///</summary> ///<param name="dt">Timestep duration.</param> public override void UpdateCollision(float dt) { //Cache some properties. var a = CollidableA; var b = CollidableB; var triggerA = a.EventTriggerer; var triggerB = b.EventTriggerer; if (!suppressEvents) { triggerA.OnPairUpdated(b, this); triggerB.OnPairUpdated(a, this); } ContactManifold.Update(dt); if (ContactManifold.contacts.count > 0) { if (!suppressEvents) { triggerA.OnPairTouching(b, this); triggerB.OnPairTouching(a, this); } if (previousContactCount == 0) { //New collision. //Add a solver item. if (Parent != null) { Parent.AddSolverUpdateable(ContactConstraint); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableAdded(ContactConstraint); } //And notify the pair members. if (!suppressEvents) { triggerA.OnInitialCollisionDetected(b, this); triggerB.OnInitialCollisionDetected(a, this); } } } else if (previousContactCount > 0) { //Just exited collision. //Remove the solver item. if (Parent != null) { Parent.RemoveSolverUpdateable(ContactConstraint); } else if (NarrowPhase != null) { NarrowPhase.NotifyUpdateableRemoved(ContactConstraint); } if (!suppressEvents) { triggerA.OnCollisionEnded(b, this); triggerB.OnCollisionEnded(a, this); } } previousContactCount = ContactManifold.contacts.count; }