Closed felix-ri closed 2 years ago
Also I didn't quite get the VelocityIterationCount.
I could reproduce this with a modified version of the Colosseum Demo, in which I put our cubestacks: old - new
In the newer version of the demo, the provided SolveDescription
only allows the solver to use 1 velocity iteration. In the older version, it uses the default of 8. If the velocity iteration count is increased in the SolveDescription
to 8 to match the old version, it works as expected.
For reference, 2.3's Solver.IterationCount
and 2.4's Solver.VelocityIterationCount
are the same thing. I just renamed it since IterationCount
alone could be a bit ambiguous with SubstepCount
. VelocityIterationCount
refers to the number of velocity solving passes constraints undergo in a single (sub)step. Each velocity solve brings body velocities closer to obeying all their connected velocity constraints.
As far as I understood, the substepcount is simply how many solver/velocityIntegration pairs are executed for every CollisionDetection step.
That's correct; it executes multiple solves and integration steps. The integration steps also include position integration, though.
(because the solver is somehow cheaper than CollisionDetection and can get away with older contact points)
The savings is in 1) not having to re-run collision detection every substep, 2) a tighter bundling of execution that avoids thread sync points, and 3) more efficient memory access patterns.
Why would you split up the velocity integration in smaller parts, if the forces don't change inbetween?
They do change.
See the substepping documentation for more information: https://github.com/bepu/bepuphysics2/blob/master/Documentation/Substepping.md
We also had simulated surface velocities by modifying the angular and linear velocity before the solver ran and restoring the normal ones afterwards (before the position integrator) How can this be done now, since integration and solving is now tied together and I can't find a callback inbeen them?
If you are using only one substep, the execution flow is extremely similar to 2.3's PositionLastTimestepper
. The frame goes like this (check https://github.com/bepu/bepuphysics2/blob/master/BepuPhysics/DefaultTimestepper.cs for details):
The DefaultTimestepper
doesn't expose a callback between 5 and 6 since they're both within the Simulation.Solve
call, but you could create a custom ITimestepper
that does or hook the Solver.SubstepEnded
event (see below).
Also, rather than resetting the velocity before the position integration, you could simply reset the position afterwards. Whichever's simpler and works for what you need.
If you are using more than one substep, things get a little trickier. The second substep and beyond will do position integration for the previous substep at the start of the current substep, and the Solver
exposes a SubstepStarted
and SubstepEnded
event. So the call to Simulation.Solve
for 3 substeps could conceptually look like:
SubstepStarted(0)
SubstepEnded(0)
SubstepStarted(1)
SubstepEnded(1)
SubstepStarted(2)
SubstepEnded(2)
By hooking the SubstepEnded
event, you could reset velocities. Note that, when the timestep is given an IThreadDispatcher
, the SubstepStarted
/SubstepEnded
events are called from thread 0 in the IThreadDispatcher
. Using that same IThreadDispatcher
instance from within those events would require that the IThreadDispatcher
implementation is reentrant, which the built in ThreadDispatcher
is not.
Thanks. We are only using one substep, so the first suggestion worked.
For reference, 2.3's Solver.IterationCount and 2.4's Solver.VelocityIterationCount are the same thing
Ahh, now I understand.
Cubestack Stability Deterioration