public unsafe IslandScaffoldConstraintBatch(Solver solver, BufferPool pool, int batchIndex) { pool.TakeAtLeast(solver.TypeProcessors.Length, out TypeIdToIndex); Unsafe.InitBlockUnaligned(TypeIdToIndex.Memory, 0xFF, (uint)(TypeIdToIndex.Length * sizeof(int))); TypeBatches = new QuickList <IslandScaffoldTypeBatch>(solver.TypeProcessors.Length, pool); ReferencedBodyIndices = batchIndex < solver.FallbackBatchThreshold ? new IndexSet(pool, solver.bodies.ActiveSet.Count) : default; }
public unsafe IslandScaffoldConstraintBatch(Solver solver, BufferPool pool) { pool.SpecializeFor<int>().Take(solver.TypeProcessors.Length, out TypeIdToIndex); Unsafe.InitBlockUnaligned(TypeIdToIndex.Memory, 0xFF, (uint)(TypeIdToIndex.Length * sizeof(int))); QuickList<IslandScaffoldTypeBatch, Buffer<IslandScaffoldTypeBatch>>.Create(pool.SpecializeFor<IslandScaffoldTypeBatch>(), solver.TypeProcessors.Length, out TypeBatches); ReferencedBodyIndices = new IndexSet(pool, solver.bodies.ActiveSet.Count); }
/// <summary> /// Awakens a list of set indices. /// </summary> /// <param name="setIndices">List of set indices to wake up.</param> /// <param name="threadDispatcher">Thread dispatcher to use when waking the bodies. Pass null to run on a single thread.</param> public void AwakenSets(ref QuickList <int, Buffer <int> > setIndices, IThreadDispatcher threadDispatcher = null) { QuickList <int, Buffer <int> > .Create(pool.SpecializeFor <int>(), setIndices.Count, out var uniqueSetIndices); var uniqueSet = new IndexSet(pool, bodies.Sets.Length); AccumulateUniqueIndices(ref setIndices, ref uniqueSet, ref uniqueSetIndices); uniqueSet.Dispose(pool); //Note that we use the same codepath as multithreading, we just don't use a multithreaded dispatch to execute jobs. //TODO: It would probably be a good idea to add a little heuristic to avoid doing multithreaded dispatches if there are only like 5 total bodies. //Shouldn't matter too much- the threaded variant should only really be used when doing big batched changes, so having a fixed constant cost isn't that bad. int threadCount = threadDispatcher == null ? 1 : threadDispatcher.ThreadCount; //Note that direct wakes always reset activity states. I suspect this is sufficiently universal that no one will ever want the alternative, //even though the narrowphase does avoid resetting activity states for the sake of faster resleeping when possible. var(phaseOneJobCount, phaseTwoJobCount) = PrepareJobs(ref uniqueSetIndices, true, threadCount); if (threadCount > 1) { this.jobIndex = -1; this.jobCount = phaseOneJobCount; threadDispatcher.DispatchWorkers(phaseOneWorkerDelegate); } else { for (int i = 0; i < phaseOneJobCount; ++i) { ExecutePhaseOneJob(i); } } if (threadCount > 1) { this.jobIndex = -1; this.jobCount = phaseTwoJobCount; threadDispatcher.DispatchWorkers(phaseTwoWorkerDelegate); } else { for (int i = 0; i < phaseTwoJobCount; ++i) { ExecutePhaseTwoJob(i); } } DisposeForCompletedAwakenings(ref uniqueSetIndices); uniqueSetIndices.Dispose(pool.SpecializeFor <int>()); }