void UpdateBroadPhaseOverlap(int i) { BroadPhaseOverlap overlap = broadPhaseOverlaps.Elements[i]; if (overlap.collisionRule < CollisionRule.NoNarrowPhasePair) { NarrowPhasePair pair; //see if the overlap is already present in the narrow phase. if (!overlapMapping.TryGetValue(overlap, out pair)) { //Create/enqueue based on collision table pair = NarrowPhaseHelper.GetPairHandler(ref overlap); if (pair != null) { pair.NarrowPhase = this; //Add the new object to the 'todo' list. //Technically, this doesn't need to be thread-safe when this is called from the sequential context. //It's just bunched together for maintainability despite the slight performance hit. newNarrowPhasePairs.Enqueue(pair); } } if (pair != null) { //Update the collision rule. pair.CollisionRule = overlap.collisionRule; if (pair.BroadPhaseOverlap.collisionRule < CollisionRule.NoNarrowPhaseUpdate) { pair.UpdateCollision(TimeStepSettings.TimeStepDuration); } pair.NeedsUpdate = false; } } }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { //Fire off some events if needed! Note the order; we should stop containing before we stop touching. if (Parent == null) { if (Containing) { DetectorVolume.StoppedContaining(this); } if (Touching) { DetectorVolume.StoppedTouching(this); } } Containing = false; Touching = false; WasContaining = false; WasTouching = false; DetectorVolume.pairs.Remove(Collidable.entity); broadPhaseOverlap = new BroadPhaseOverlap(); DetectorVolume = null; Parent = null; //Child cleanup is responsible for cleaning up direct references to the involved collidables. }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { //Child types remove contacts from the pair handler and call OnContactRemoved. //Child types manage the removal of the constraint from the space, if necessary. //If the contact manifold had any contacts in it on cleanup, then we still need to fire the 'ending' event. if (previousContactCount > 0 && !suppressEvents) { CollidableA.EventTriggerer.OnCollisionEnded(CollidableB, this); CollidableB.EventTriggerer.OnCollisionEnded(CollidableA, this); } //Remove this pair from each collidable. This can be done safely because the CleanUp is called sequentially. //However, only do it if we have been added to the collidables! This does not happen until this pair is added to the narrow phase. //For pairs which never get added to the broad phase, such as those in queries, we should not attempt to remove something that isn't there! if (listIndexA != -1) { CollidableA.RemovePair(this, ref listIndexA); CollidableB.RemovePair(this, ref listIndexB); } //Notify the colliders that the pair went away. if (!suppressEvents) { CollidableA.EventTriggerer.OnPairRemoved(CollidableB); CollidableB.EventTriggerer.OnPairRemoved(CollidableA); } broadPhaseOverlap = new BroadPhaseOverlap(); suppressEvents = false; timeOfImpact = 1; Parent = null; previousContactCount = 0; //Child cleanup is responsible for cleaning up direct references to the involved collidables. //Child cleanup is responsible for cleaning up contact manifolds. }
///<summary> /// Gets a narrow phase pair for a given broad phase overlap. ///</summary> ///<param name="pair">Overlap to use to create the pair.</param> ///<returns>A INarrowPhasePair for the overlap.</returns> public static NarrowPhasePair GetPairHandler(ref BroadPhaseOverlap pair) { NarrowPhasePairFactory factory; if (collisionManagers.TryGetValue(new TypePair(pair.entryA.GetType(), pair.entryB.GetType()), out factory)) { var toReturn = factory.GetNarrowPhasePair(); toReturn.BroadPhaseOverlap = pair; toReturn.Factory = factory; return(toReturn); } //Convex-convex collisions are a pretty significant chunk of all tests, so rather than defining them all, just have a fallback. var a = pair.entryA as ConvexCollidable; var b = pair.entryB as ConvexCollidable; if (a != null && b != null) { NarrowPhasePair toReturn = Factories.ConvexConvex.GetNarrowPhasePair(); toReturn.BroadPhaseOverlap = pair; toReturn.Factory = Factories.ConvexConvex; return(toReturn); } return(null); }
protected internal void AddOverlap(BroadPhaseOverlap overlap) { overlapAddLock.Enter(); overlaps.Add(overlap); overlapAddLock.Exit(); }
/// <summary> /// Gets a collidable pair handler for a pair of collidables. /// </summary> /// <param name="pair">Pair of collidables to use to create the pair handler.</param> /// <returns>CollidablePairHandler for the pair.</returns> public static CollidablePairHandler GetPairHandler(ref CollidablePair pair) { var overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB); return(GetPairHandler(ref overlap) as CollidablePairHandler); }
///<summary> /// Gets a narrow phase pair for a given pair of entries. ///</summary> ///<param name="entryA">First entry in the pair.</param> /// <param name="entryB">Second entry in the pair.</param> ///<returns>AINarrowPhasePair for the overlap.</returns> public static NarrowPhasePair GetPairHandler(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { var overlap = new BroadPhaseOverlap(entryA, entryB); return(GetPairHandler(ref overlap)); }