Exemple #1
0
        static void CreateAndRunSimulation(BufferPool bufferPool)
        {
            //TODO: As more features get added, you'll probably want to revisit this and lengthen the per-execution duration.
            var simulation = Simulation.Create(bufferPool, new TestCallbacks());
            var sphere     = new Sphere(0.5f);
            var shapeIndex = simulation.Shapes.Add(sphere);

            var       bodyBuilder       = new RegularGridWithKinematicBaseBuilder(new Vector3(1), new Vector3(), 1, shapeIndex);
            var       constraintBuilder = new BallSocketConstraintBuilder();
            const int width             = 3;
            const int height            = 3;
            const int length            = 3;

            SimulationSetup.BuildLattice(bodyBuilder, constraintBuilder, width, height, length, simulation, out var bodyHandles, out var constraintHandles);

            simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
            simulation.Bodies.ActiveSet.Velocities[width].Linear = new Vector3(0.1f, 0, 0.1f);

            for (int i = 0; i < 16; ++i)
            {
                simulation.Timestep(1 / 60f);
            }

            simulation.Dispose();
        }
Exemple #2
0
        public static RigidPose[] ExecuteSimulation(int frameCount, BufferPool bufferPool, IThreadDispatcher threadDispatcher)
        {
            var       simulation = Simulation.Create(bufferPool, new TestCallbacks());
            var       shape      = new Sphere(0.5f);
            var       shapeIndex = simulation.Shapes.Add(shape);
            const int width      = 8;
            const int height     = 8;
            const int length     = 8;

            SimulationSetup.BuildLattice(
                new RegularGridWithKinematicBaseBuilder(new Vector3(1.2f, 1.05f, 1.2f), new Vector3(1, 1, 1), 1f / (shape.Radius * shape.Radius * 2 / 3), shapeIndex),
                new ConstraintlessLatticeBuilder(),
                width, height, length, simulation, out var bodyHandles, out var constraintHandles);
            simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
            simulation.Deterministic          = true;

            //All bodies are definitely active, so we can pull directly from the active set.
            ref var velocity = ref simulation.Bodies.ActiveSet.Velocities[simulation.Bodies.HandleToLocation[bodyHandles[width]].Index];
        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();
        }
Exemple #4
0
        public static void Test()
        {
            const int width  = 32;
            const int height = 32;
            const int length = 32;

            SimulationSetup.BuildLattice(
                new RegularGridWithKinematicBaseBuilder(new Vector3(1), new Vector3()),
                new BallSocketConstraintBuilder(),
                width, height, length, out var simulation, out var bodyHandles, out var constraintHandles);

            var threadDispatcher = new SimpleThreadDispatcher(8);

            const float inverseDt      = 60f;
            const float dt             = 1 / inverseDt;
            const int   iterationCount = 8;
            const int   frameCount     = 128;

            simulation.Solver.IterationCount = iterationCount;

            simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);

            var samples = new SimulationTimeSamples(frameCount);

            for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex)
            {
                var energyBefore = TestHelpers.GetBodyEnergyHeuristic(simulation.Bodies);

                //simulation.Timestep(dt);
                simulation.Timestep(dt, threadDispatcher);

                samples.RecordFrame(simulation);

                var energyAfter      = TestHelpers.GetBodyEnergyHeuristic(simulation.Bodies);
                int sampledBodyIndex = width;
                var samplePose       = simulation.Bodies.ActiveSet.Poses[sampledBodyIndex];
                var sampleVelocity   = simulation.Bodies.ActiveSet.Velocities[sampledBodyIndex];
                //for (int i =0; i < simulation.Bodies.BodyCount; ++i)
                //{
                //    simulation.Bodies.GetPose(simulation.Bodies.IndexToHandle[i], out var pose);
                //    simulation.Bodies.GetVelocity(simulation.Bodies.IndexToHandle[i], out var velocity);
                //    Console.WriteLine($"Sample {i} position: {pose.Position}, velocity: {velocity.Linear}");
                //}
                Console.WriteLine($"Sample {sampledBodyIndex} position: {samplePose.Position}, velocity: {sampleVelocity.Linear}");

                Console.WriteLine($"Body energy {frameIndex}: {energyAfter}, delta: {energyAfter - energyBefore}");
            }

            var multiplier = 1e3 / frameCount;

            Console.WriteLine($"Simulation time (ms):       {multiplier * samples.Simulation.ComputeStats().Total}");
            Console.WriteLine($"Body opt time (ms):         {multiplier * samples.BodyOptimizer.ComputeStats().Total}");
            Console.WriteLine($"Constraint opt time (ms):   {multiplier * samples.ConstraintOptimizer.ComputeStats().Total}");
            Console.WriteLine($"Batch compress time (ms):   {multiplier * samples.BatchCompressor.ComputeStats().Total}");
            Console.WriteLine($"Pose integrate time (ms):   {multiplier * samples.PoseIntegrator.ComputeStats().Total}");
            Console.WriteLine($"Solve time (ms):            {multiplier * samples.Solver.ComputeStats().Total}");


            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);
        }
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(-20f, 13, -20f);
            camera.Yaw      = MathHelper.Pi * 3f / 4;
            camera.Pitch    = MathHelper.Pi * 0.1f;
            Simulation      = Simulation.Create(BufferPool, new TestCallbacks());

            var shape = new Sphere(0.5f);

            shape.ComputeInertia(1, out var sphereInertia);
            var       shapeIndex     = Simulation.Shapes.Add(shape);
            const int width          = 16;
            const int height         = 16;
            const int length         = 16;
            var       latticeSpacing = 1.1f;
            var       latticeOffset  = -0.5f * width * latticeSpacing;

            SimulationSetup.BuildLattice(
                new RegularGridBuilder(new Vector3(latticeSpacing, 1.1f, latticeSpacing), new Vector3(latticeOffset, 3, latticeOffset), sphereInertia, shapeIndex),
                new BallSocketConstraintBuilder(),
                width, height, length, Simulation, out var bodyHandles, out var constraintHandles);
            Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
            Simulation.Deterministic          = false;

            var         staticShape              = new Sphere(4);
            var         staticShapeIndex         = Simulation.Shapes.Add(staticShape);
            const int   staticGridWidthInSpheres = 100;
            const float staticSpacing            = 6;

            for (int i = 0; i < staticGridWidthInSpheres; ++i)
            {
                for (int j = 0; j < staticGridWidthInSpheres; ++j)
                {
                    var staticDescription = new StaticDescription
                    {
                        Collidable = new CollidableDescription
                        {
                            Continuity = new ContinuousDetectionSettings {
                                Mode = ContinuousDetectionMode.Discrete
                            },
                            Shape             = staticShapeIndex,
                            SpeculativeMargin = 0.1f
                        },
                        Pose = new RigidPose
                        {
                            Position = new Vector3(
                                -staticGridWidthInSpheres * staticSpacing * 0.5f + i * staticSpacing,
                                -4,
                                -staticGridWidthInSpheres * staticSpacing * 0.5f + j * staticSpacing),
                            Orientation = BepuUtilities.Quaternion.Identity
                        }
                    };
                    Simulation.Statics.Add(staticDescription);
                }
            }

            //ref var velocity = ref Simulation.Bodies.Velocities[Simulation.Bodies.HandleToIndex[bodyHandles[width]]];
            //velocity.Linear = new Vector3(0.1f, 0, 0.1f);
            //velocity.Angular = new Vector3();

            //Simulation.Solver.IterationCount = 100;
        }