Example #1
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 10, 40);
            camera.Yaw      = 0;
            camera.Pitch    = 0;
            //Note the higher stiffness on contacts for this demo. That's not ideal for general stability at the demo timestep duration default of 60hz, but
            //this demo doesn't have any significant solver complexity and we want to see the CCD in action more clearly- which means more rigid contact.
            //Having objects bounce a bunch on impact makes it harder to see.
            //Also note that the PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep
            //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper.
            //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection.
            Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks()
            {
                ContactSpringiness = new SpringSettings(120, 1)
            }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper());

            var shape = new Box(1, 1, 1);

            shape.ComputeInertia(1, out var inertia);
            var shapeIndex = Simulation.Shapes.Add(shape);

            for (int i = 0; i < 10; ++i)
            {
                for (int j = 0; j < 10; ++j)
                {
                    //These two falling dynamics have pretty small speculative margins. The second one uses continuous collision detection sweeps to generate speculative contacts.
                    Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(-4 - 2 * j, 100 + (i + j) * 2, i * 2), new BodyVelocity {
                        Linear = new Vector3(0, -150, 0)
                    }, inertia,
                                                                        new CollidableDescription(shapeIndex, 0.01f), new BodyActivityDescription(0.01f)));
                    //The minimum progression duration parameter at 1e-3 means the CCD sweep won't miss any collisions that last at least 1e-3 units of time- so, if time is measured in seconds,
                    //then this will capture any collision that an update rate of 1000hz would.
                    //Note also that the sweep convergence threshold is actually pretty loose at 100hz. Despite that, it can still lead to reasonably good speculative contacts with solid impact behavior.
                    //That's because the sweep does not directly generate contacts- it generates a time of impact estimate, and then the discrete contact generation
                    //runs to create the actual contact manifold. That provides high quality contact positions and speculative depths.
                    //If the ground that these boxes were smashing into was something like a mesh- which is infinitely thin- you may want to increase the sweep accuracy.
                    Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(4 + 2 * j, 100 + (i + j) * 2, i * 2), new BodyVelocity {
                        Linear = new Vector3(0, -150, 0)
                    }, inertia,
                                                                        new CollidableDescription(shapeIndex, 0.01f, ContinuousDetectionSettings.Continuous(1e-3f, 1e-2f)), new BodyActivityDescription(0.01f)));
                }
            }
            rolloverInfo = new RolloverInfo();
            rolloverInfo.Add(new Vector3(-12, 2, 0), "Discrete");
            rolloverInfo.Add(new Vector3(12, 2, 0), "Continuous");

            //Build a couple of spinners to ram into each other to showcase angular CCD. Note that the spin speeds are slightly different- that helps avoid
            //synchronization that makes the blades frequently miss each other, which sorta ruins a CCD demo.
            spinnerMotorA = BuildSpinner(new Vector3(-5, 10, -5), 53);
            spinnerMotorB = BuildSpinner(new Vector3(5, 10, -5), 59);
            rolloverInfo.Add(new Vector3(0, 12, -5), "High angular velocity continuous detection");

            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(300, 10, 300)), 0.1f)));
        }
Example #2
0
 /// <summary>
 /// Tries to extract contact prestep, impulse, and body reference data from the given handle. If it's not a contact constraint, returns false.
 /// </summary>
 /// <typeparam name="TExtractor">Type of the extractor used to collect contact data from the solver.</typeparam>
 /// <param name="constraintHandle">Constraint to try to extract data from.</param>
 /// <param name="extractor">Extractor used to collect contact data from the solver.</param>
 /// <returns>True if the constraint was a contact type, false otherwise.</returns>
 public bool TryExtractSolverContactData <TExtractor>(ConstraintHandle constraintHandle, ref TExtractor extractor) where TExtractor : struct, ISolverContactDataExtractor
 {
     ref var constraintLocation = ref Solver.HandleToConstraint[constraintHandle.Value];
Example #3
0
 /// <summary>
 /// Allocates a slot in the batch.
 /// </summary>
 /// <param name="typeBatch">Type batch to allocate in.</param>
 /// <param name="handle">Handle of the constraint to allocate. Establishes a link from the allocated constraint to its handle.</param>
 /// <param name="bodyIndices">Pointer to a list of body indices (not handles!) with count equal to the type batch's expected number of involved bodies.</param>
 /// <param name="pool">Allocation provider to use if the type batch has to be resized.</param>
 /// <returns>Index of the slot in the batch.</returns>
 public unsafe abstract int Allocate(ref TypeBatch typeBatch, ConstraintHandle handle, int *bodyIndices, BufferPool pool);