public static void Test() { //const int bodyCount = 8; //SimulationSetup.BuildStackOfBodiesOnGround(bodyCount, false, true, out var bodies, out var solver, out var graph, out var bodyHandles, out var constraintHandles); SimulationSetup.BuildLattice( new RegularGridWithKinematicBaseBuilder(new Vector3(1), new Vector3()), new ContactManifoldConstraintBuilder(), 32, 32, 32, out var simulation, out var bodyHandles, out var constraintHandles); SimulationScrambling.ScrambleBodies(simulation); SimulationScrambling.ScrambleConstraints(simulation.Solver); SimulationScrambling.ScrambleBodyConstraintLists(simulation); SimulationScrambling.AddRemoveChurn <Contact4>(simulation, 100000, bodyHandles, constraintHandles); var threadDispatcher = new SimpleThreadDispatcher(8); //var threadDispatcher = new NotQuiteAThreadDispatcher(8); simulation.ConstraintLayoutOptimizer.OptimizationFraction = 0.01f; int constraintOptimizationIterations = 8192; simulation.ConstraintLayoutOptimizer.Update(simulation.BufferPool, threadDispatcher);//prejit var timer = Stopwatch.StartNew(); for (int i = 0; i < constraintOptimizationIterations; ++i) { simulation.ConstraintLayoutOptimizer.Update(simulation.BufferPool, threadDispatcher); } timer.Stop(); Console.WriteLine($"Finished constraint optimizations, time (ms): {timer.Elapsed.TotalMilliseconds}" + $", per iteration (us): {timer.Elapsed.TotalSeconds * 1e6 / constraintOptimizationIterations}"); //threadDispatcher.Dispose(); simulation.BufferPool.Clear(); }
public static SimulationTimeSamples Solve <TBodyBuilder, TConstraintBuilder, TConstraint>(TBodyBuilder bodyBuilder, TConstraintBuilder constraintBuilder, int width, int height, int length, int frameCount, int threadCount, IThreadDispatcher initializationThreadPool, IThreadDispatcher threadDispatcher) where TBodyBuilder : IBodyBuilder where TConstraintBuilder : IConstraintBuilder where TConstraint : IConstraintDescription <TConstraint> { //const int bodyCount = 8; //SimulationSetup.BuildStackOfBodiesOnGround(bodyCount, false, true, out var bodies, out var solver, out var graph, out var bodyHandles, out var constraintHandles); GC.Collect(3, GCCollectionMode.Forced, true); SimulationSetup.BuildLattice( bodyBuilder, constraintBuilder, width, height, length, out var simulation, out var bodyHandles, out var constraintHandles); SimulationScrambling.ScrambleBodies(simulation); SimulationScrambling.ScrambleConstraints(simulation.Solver); SimulationScrambling.ScrambleBodyConstraintLists(simulation); SimulationScrambling.AddRemoveChurn <TConstraint>(simulation, bodyHandles.Length * 2, bodyHandles, constraintHandles); const int batchCompressionIterations = 1000; simulation.SolverBatchCompressor.TargetCandidateFraction = .005f; simulation.SolverBatchCompressor.MaximumCompressionFraction = 0.0005f; for (int i = 0; i < batchCompressionIterations; ++i) { simulation.SolverBatchCompressor.Compress(simulation.BufferPool, initializationThreadPool); } //Attempt cache optimization. int bodyOptimizationIterations = bodyHandles.Length / 4; simulation.BodyLayoutOptimizer.OptimizationFraction = 0.005f; for (int i = 0; i < bodyOptimizationIterations; ++i) { simulation.BodyLayoutOptimizer.IncrementalOptimize(simulation.BufferPool, initializationThreadPool); } simulation.ConstraintLayoutOptimizer.OptimizationFraction = 0.044f; int constraintOptimizationIterations = 1024; for (int i = 0; i < constraintOptimizationIterations; ++i) { simulation.ConstraintLayoutOptimizer.Update(simulation.BufferPool, initializationThreadPool); } var simulationTimeSamples = new SimulationTimeSamples(frameCount); const float dt = 1 / 60f; const int iterationCount = 8; simulation.Solver.IterationCount = iterationCount; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { CacheBlaster.Blast(); simulation.Timestep(dt, threadDispatcher); simulationTimeSamples.RecordFrame(simulation); } simulation.Dispose(); simulation.BufferPool.Clear(); return(simulationTimeSamples); }