Example #1
0
        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);
                }
            }
        }