How to use btdiscreteDynamicsWorld.stepSimulation()?

Post Reply
bearsomg
Posts: 5
Joined: Sat Jul 21, 2012 2:48 pm

How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by bearsomg »

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?
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by MaxDZ8 »

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.
bearsomg
Posts: 5
Joined: Sat Jul 21, 2012 2:48 pm

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by bearsomg »

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.
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:

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);
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by MaxDZ8 »

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?
bearsomg
Posts: 5
Joined: Sat Jul 21, 2012 2:48 pm

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by bearsomg »

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?
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:

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;
and the physics.update function:

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.
frank28_nfls
Posts: 7
Joined: Wed Jul 18, 2012 4:54 am

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by frank28_nfls »

I think the comment about 'stepSimulation' did already well explain its use:

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.
In your case, try this code:

Code: Select all

if (deltaTime == 0)
      return;

sec = btScalar(deltaTime*0.001);/* convert frame to second */

_world->stepSimulation(sec, 10);
frank28_nfls
Posts: 7
Joined: Wed Jul 18, 2012 4:54 am

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by frank28_nfls »

In case you prefer a wiki page to the comments in code:

http://bulletphysics.org/mediawiki-1.5. ... _the_World
trollington
Posts: 8
Joined: Thu Nov 24, 2011 3:08 pm

Re: How to use btdiscreteDynamicsWorld.stepSimulation()?

Post by trollington »

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...
Post Reply