void AddNewNarrowPhaseObjects() { //Add new narrow phase objects. This will typically be a very tiny phase. NarrowPhasePair narrowPhaseObject; while (newNarrowPhasePairs.TryUnsafeDequeueFirst(out narrowPhaseObject)) { narrowPhasePairs.Add(narrowPhaseObject); //Because this occurs AFTER a stale update, and because a new narrow phase object will have NeedsUpdate = false, //set it to true here. //This ensures that the pair will be removed by the stale remover in the next frame should it be necessary to do so. //(If this wasn't set, it would only be removed 2 frames from now.) narrowPhaseObject.NeedsUpdate = true; OnCreatePair(narrowPhaseObject); } }
/// <summary> /// Initializes the pool with some resources. /// Throws away excess resources. /// </summary> /// <param name="initialResourceCount">Number of resources to include.</param> public override void Initialize(int initialResourceCount) { while (stack.Count > initialResourceCount) { T toRemove; stack.TryUnsafeDequeueFirst(out toRemove); } int length = stack.lastIndex - stack.firstIndex + 1; //lastIndex is inclusive, so add 1. if (InstanceInitializer != null) { for (int i = 0; i < length; i++) { InstanceInitializer(stack.array[(stack.firstIndex + i) % stack.array.Length]); } } while (stack.Count < initialResourceCount) { stack.UnsafeEnqueue(CreateNewResource()); } }
void FlushSplits() { //Only do a portion of the total splits. int maxAttempts = Math.Max(minimumSplitAttempts, (int)(splitAttempts.Count * maximumSplitAttemptsFraction)); int attempts = 0; SimulationIslandConnection attempt; while (attempts < maxAttempts && splitAttempts.TryUnsafeDequeueFirst(out attempt)) { if (attempt.SlatedForRemoval) //If it was re-added, don't split! { attempt.SlatedForRemoval = false; //Reset the removal state so that future adds will add back references, since we're about to remove them. attempt.RemoveReferencesFromConnectedMembers(); bool triedToSplit = false; for (int i = 0; i < attempt.entries.Count; i++) { for (int j = i + 1; j < attempt.entries.Count; j++) { triedToSplit |= TryToSplit(attempt.entries.Elements[i].Member, attempt.entries.Elements[j].Member); } } //Only count the split if it does any work. if (triedToSplit) { attempts++; } if (attempt.Owner == null) { //It's an orphan connection. No one owns it, and now that it's been dequeued from the deactivation manager, //it has no home at all. //Don't let it rot- return it to the pool! PhysicsResources.GiveBack(attempt); //This occurs when a constraint changes members. //Because connections need to be immutable for this scheme to work, //the old connection is orphaned and put into the deactivation manager's removal queue //while a new one from the pool takes its place. } } } }
protected virtual void DispatchEvents() { //Note: Deferred event creation should be performed sequentially with dispatching. //This means a event creation from this creator cannot occur ASYNCHRONOUSLY while DispatchEvents is running. //Note: If the deferred event handler is removed during the execution of the engine, the handler may be null. //In this situation, ignore the event. //This is not a particularly clean behavior, but it's better than just crashing. EventStoragePairCreated collisionPairCreated; while (eventStoragePairCreated.TryUnsafeDequeueFirst(out collisionPairCreated)) { if (InternalPairCreated != null) { InternalPairCreated(owner, collisionPairCreated.other, collisionPairCreated.pair); } } EventStoragePairRemoved collisionPairRemoved; while (eventStoragePairRemoved.TryUnsafeDequeueFirst(out collisionPairRemoved)) { if (InternalPairRemoved != null) { InternalPairRemoved(owner, collisionPairRemoved.other); } } EventStoragePairUpdated collisionPairUpdated; while (eventStoragePairUpdated.TryUnsafeDequeueFirst(out collisionPairUpdated)) { if (InternalPairUpdated != null) { InternalPairUpdated(owner, collisionPairUpdated.other, collisionPairUpdated.pair); } } }