I am using the Bullet Physics engine in a 3D rendering engine I am building using Direct3D 10. The engine loads a character model when the program starts, and displays it on the screen with the physics activated the whole time. Then the user can load in and play a animation on that character at any time he/she chooses to do so. The FPS of the animation can be changed in the code, and must be set before the program launches. Right now I have the animation FPS set to 60fps, but the actual rendering fps of the GPU is normally around 2000fps when not playing an animation, and around 300fps when playing an animation.
I am fairly new to the Bullet API. How would I use the btDiscreteDynamicsWorld.stepSimulation() function to correctly continue the physics simulation without losing frames because of the changing global framerate?
How to use btdiscreteDynamicsWorld.stepSimulation()?
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
Framerate always changes (albeit not so abruptly). As long as you compute your time step correctly, it should keep going.
You are encouraged in implementing a framerate limiter. 125 fps are plenty.
You are encouraged in implementing a framerate limiter. 125 fps are plenty.
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
But what is the correct way to do this? Right now I call GetTickCount() at the start and end of each frame, compute the difference, then send this to my physics update function on the next frame as the delta time. In the update function, I calculate this as so:MaxDZ8 wrote:Framerate always changes (albeit not so abruptly). As long as you compute your time step correctly, it should keep going.
You are encouraged in implementing a framerate limiter. 125 fps are plenty.
Code: Select all
if (deltaTime == 0)
return;
sec = btScalar(deltaTime*0.001);/* convert frame to second */
float fps = 1.0f/sec;
_world->stepSimulation(sec, (int)fps, sec);
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
Last time I used GetTickCount it had a 20ms granularity. I'm not aware of how it works now on your system. That was insufficient to handle 300fps, let alone 1000. What's the granularity on your system?
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
Hmm, thanks for pointing that out. I didn't even bother trying to figure out the granularity because either way using GetTickCount() would be useless at this point because it lack accuracy. I switched over to timeGetTime(), but now the simulation of the ragdoll seems very slow. This is my main render function now:MaxDZ8 wrote:Last time I used GetTickCount it had a 20ms granularity. I'm not aware of how it works now on your system. That was insufficient to handle 300fps, let alone 1000. What's the granularity on your system?
Code: Select all
processWindowMsg();
if (timeGetTime()-frameEndTime < ((FPS_LIMIT)*0.001))
return;
frameStartTime = timeGetTime();
physics.update(frameTime);
cam->process(d3ddev);
d3ddev->ClearRenderTargetView(renderTargetView, D3DXVECTOR4(0, 0, 0, 1));
d3ddev->ClearDepthStencilView(DepthStencilView, D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL, 1.0f, 0);
view->SetMatrix((float*)&(cam->matView));
projection->SetMatrix((float*)&(cam->matProjection));
D3DXVECTOR3 c = D3DXVECTOR3(cam->getPos());
cameraPos->SetFloatVector((float*)&c);
ModelList::iterator it;
for (it=_mdlList.begin();it!=_mdlList.end();it++)
{
if ((*it).second[0].model.hasMotionStarted())
{
(*it).second[0].model.updateMotion();
}
if ((*it).second[0].visible)
{
renderingSkel->SetBool(false);
(*it).second[0].model.render();
}
frameEndTime = timeGetTime();
frameTime = frameEndTime-frameStartTime;
Code: Select all
if (deltaTime == 0)
return;
sec = btScalar(deltaTime*0.001);/* convert frame to second */
float fps = 1.0f/sec;
_world->stepSimulation(sec, (int)fps, sec);
I still have no idea about how to correctly use the stepSimulation function for a realistic ragdoll simulation though, and the Stepping The World wiki entry didn't seem to explain things to make it any easier to understand.
-
- Posts: 7
- Joined: Wed Jul 18, 2012 4:54 am
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
I think the comment about 'stepSimulation' did already well explain its use:
In your case, try this code:
Code: Select all
///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds.
///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'.
///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'.
///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant.
Code: Select all
if (deltaTime == 0)
return;
sec = btScalar(deltaTime*0.001);/* convert frame to second */
_world->stepSimulation(sec, 10);
-
- Posts: 7
- Joined: Wed Jul 18, 2012 4:54 am
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
In case you prefer a wiki page to the comments in code:
http://bulletphysics.org/mediawiki-1.5. ... _the_World
http://bulletphysics.org/mediawiki-1.5. ... _the_World
-
- Posts: 8
- Joined: Thu Nov 24, 2011 3:08 pm
Re: How to use btdiscreteDynamicsWorld.stepSimulation()?
You can use btClock, a class provided by Bullet, for microsecond accuracy.
The second argument to stepSimulation is the max number of simulation substeps; you probably shouldn't set it to anything else than 1 unless you have a good reason...
The second argument to stepSimulation is the max number of simulation substeps; you probably shouldn't set it to anything else than 1 unless you have a good reason...