I have a question. Let's take a billiard cue and cue ball. When the cue is moving fast, cue go through the ball without a BEPU engine noticed. Finally the cue stuck in the ball and this leads to funny animations and physics behavior. Space.Update() method is called in Game.Update() method. So this is something about 60 times per second. I was thinking about it and I got idea... What if I make some pre-calculation in another thread in backround with smaller time step (ex. Space.Update(1) ), then store positions for each update and when pre-calculation finished - > run Game.Draw() mehod with my stored data? What do you think about it?
THX for your replies and suggestions. Cheers
Resolution of simulation
Re: Resolution of simulation
Increasing the frequency of updates does indeed help stabilize the simulation and avoid missed collisions. I'll talk about that first, though there are a couple of other easy options to improving simulation quality at the bottom.
However, updating the engine asynchronously is usually harder from a development perspective than running it sequentially with the rest of your program. If possible, it's a good idea to keep it in the more intuitive sequential flow.
Fortunately, you do not need to put the engine on a separate thread to update it faster. By default, the Space.TimeStepSettings.TimeStepDuration is 1/60f. Each parameterless Space.Update() performs a single time step of length Space.TimeStepSettings.TimeStepDuration. So if your game updates at 1/60f, one Space.Update() per frame is about right.
You can change the Space.TimeStepSettings.TimeStepDuration to something smaller, like 1/120f or 1/180f, and then update the engine more frequently. For a time step duration of 1/180f and a game update rate of 60hz, calling Space.Update() three times would cover the same amount of time as a single 1/60f update, matching the game update rate.
You can also pass the elapsed game time into the Space.Update(dt) method. This version of the update method uses internal time stepping. That means that the time you pass into the engine is accumulated and a number of time steps of Space.TimeStepSettings.TimeStepDuration are executed to get as close to 0 as possible. Instead of having to explicitly call Space.Update(), calling it once with the elapsed time will take however many steps are necessary to keep up with the game.
Internal time stepping does introduce a complication, however. As the remaining time each frame is some amount between 0 and Space.TimeStepSettings.TimeStepDuration, there may be a slightly jittery appearance to the simulation. This is addressed by making use of the interpolation buffers available in the Space. More information is available in the asychronous update documentation linked above. Note that you do not need to use an asynchronous update to make use of internal time stepping or interpolation.
Note that Space.Update(dt) takes the elapsed frame time, which for most games, hovers around 1/60f. Using Space.Update(1) as in your example would force it to simulate a full 'time unit' (generally seconds), forcing 60 time steps in one frame under the default settings.
There are other things you can do to help with stability. First, make sure your simulation is within a fairly regular scale. The engine likes things in the range of 0.5 to 10 units. This applies to individual triangles in a mesh and individual bodies. You can go outside of this range safely, but staying within it has pretty strong guarantees of stability. Some collision pairs have greater robustness and can deal with much larger ranges without issue (like sphere-sphere, box-box, sphere-triangle, etc.), but it's best to stay in the universally comfortable range.
Second, for missed collisions, you can enable continuous collision detection. Set the entity's PositionUpdateMode to Continuous. Its motion will be swept through space to detect collisions between frames. This is generally much cheaper than increasing the simulation update rate.
However, updating the engine asynchronously is usually harder from a development perspective than running it sequentially with the rest of your program. If possible, it's a good idea to keep it in the more intuitive sequential flow.
Fortunately, you do not need to put the engine on a separate thread to update it faster. By default, the Space.TimeStepSettings.TimeStepDuration is 1/60f. Each parameterless Space.Update() performs a single time step of length Space.TimeStepSettings.TimeStepDuration. So if your game updates at 1/60f, one Space.Update() per frame is about right.
You can change the Space.TimeStepSettings.TimeStepDuration to something smaller, like 1/120f or 1/180f, and then update the engine more frequently. For a time step duration of 1/180f and a game update rate of 60hz, calling Space.Update() three times would cover the same amount of time as a single 1/60f update, matching the game update rate.
You can also pass the elapsed game time into the Space.Update(dt) method. This version of the update method uses internal time stepping. That means that the time you pass into the engine is accumulated and a number of time steps of Space.TimeStepSettings.TimeStepDuration are executed to get as close to 0 as possible. Instead of having to explicitly call Space.Update(), calling it once with the elapsed time will take however many steps are necessary to keep up with the game.
Internal time stepping does introduce a complication, however. As the remaining time each frame is some amount between 0 and Space.TimeStepSettings.TimeStepDuration, there may be a slightly jittery appearance to the simulation. This is addressed by making use of the interpolation buffers available in the Space. More information is available in the asychronous update documentation linked above. Note that you do not need to use an asynchronous update to make use of internal time stepping or interpolation.
Note that Space.Update(dt) takes the elapsed frame time, which for most games, hovers around 1/60f. Using Space.Update(1) as in your example would force it to simulate a full 'time unit' (generally seconds), forcing 60 time steps in one frame under the default settings.
There are other things you can do to help with stability. First, make sure your simulation is within a fairly regular scale. The engine likes things in the range of 0.5 to 10 units. This applies to individual triangles in a mesh and individual bodies. You can go outside of this range safely, but staying within it has pretty strong guarantees of stability. Some collision pairs have greater robustness and can deal with much larger ranges without issue (like sphere-sphere, box-box, sphere-triangle, etc.), but it's best to stay in the universally comfortable range.
Second, for missed collisions, you can enable continuous collision detection. Set the entity's PositionUpdateMode to Continuous. Its motion will be swept through space to detect collisions between frames. This is generally much cheaper than increasing the simulation update rate.
-
- Posts: 5
- Joined: Mon Dec 05, 2011 7:34 pm
Re: Resolution of simulation
Thank you very much for your comprehensive answer
Active support convicting me that BEPU was the right choice
I am going to check it out... 


