[SOLVED] Forcing substeps

sabotage3d
Posts: 9
Joined: Tue Nov 11, 2014 1:52 pm

[SOLVED] Forcing substeps

Post by sabotage3d »

Hello,

I am trying to force the sub-steps in bullet but I am having some problems.
As I am working on mobile I am trying to reduce the number of sub-steps
If I set anything less than 10 my simulation slows down.
Is there a way to force the substeps to 1-2 without slowing down the simulation ?

Code: Select all

float timeStep = 1.0f / 60 ;
int maxSubSteps= 10;

World->stepSimulation(timeStep, maxSubSteps);
Thanks in advance,

Alex
Last edited by sabotage3d on Fri Nov 14, 2014 11:47 am, edited 1 time in total.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Forcing substeps

Post by drleviathan »

The declaration of stepSimulation() looks like this:

Code: Select all

virtual int     stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
Note that the last two arguments have default values of 1 and 1/60 respectively. What you're supposed to do is measure the first argument (timestep) rather than supply it as a constant 1/60 as your example code does, and then let Bullet take substeps as necessary.

That is, suppose your application was running at 29 fps such that timeStep was 1/29. If you call it like this:

Code: Select all

World->stepSimulation(timeStep, 10);
then Bullet would take two substeps (each at 1/60 second). It would only use the max 10 substeps if you supplied a stepTime of 1/6 second.

Hence, when you supply: stepTime = 1/60, maxSubSteps = 10, and the default fixedTimeStep = 1/60 then your simulation only takes one substep since that is how many substeps of 1/60 fit into a full step of 1/60. The reason your simulation would fall behind is not because of the value of maxSubSteps -- that is a red herring -- but because your application frame rate must be something less than 1/60 but you only supply 1/60 to the physics simulation.

The mystery is why you experience a change in behavior when modifying maxSubSteps -- it shouldn't affect anything since Bullet would only use one of them no matter what you set it to.

In short: measure stepTime and set maxSubSteps to 2.

Note that it is OK to supply a stepTime that is smaller than fixedTimeStep because btDiscreteDynamicsWorld will accumulate the timeStep over subsequent steps and then step forward when it can fit in a fixedTimeStep.
sabotage3d
Posts: 9
Joined: Tue Nov 11, 2014 1:52 pm

Re: Forcing substeps

Post by sabotage3d »

Thanks for the reply.

Can we ignore the FPS cap and just provide timestep and maxSubSteps ?
For real-time applications where the frame rate can drop what is the best option. Can we do something like this ?


For the currentFPS variable to feed it from the current FPS from the application.
And calculate timeSinceLastFrame as timestep ?

Code: Select all

int maxSubSteps = 1;

World->stepSimulation(timeSinceLastFrame, maxSubSteps , 1.0/currentFPS);
Actually I just tried that if the FPS drops everything will freeze with it.
I am not sure what would be the best solution.
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: Forcing substeps

Post by c6burns »

I don't see how passing a variable fixed timestep is going to help you. The "fixed" in fixedTimeStep is a hint. This should be constant.

How is this not a sufficient explanation? http://bulletphysics.org/mediawiki-1.5. ... _the_World

If you don't want your simulation to lose time, then set maxSubSteps to a number where: timeStep < maxSubSteps * fixedTimeStep

You don't "force" substeps, that doesn't make sense. Bullet will use substeps if timeStep > fixedTimeStep and it will use as many as it needs up to maxSubSteps.
sabotage3d
Posts: 9
Joined: Tue Nov 11, 2014 1:52 pm

Re: Forcing substeps

Post by sabotage3d »

I confused because I was running my tests on mobile simulator while on the device the behavior is correct. I am giving now a fixed timestep of 1.0/30.0 and 1 substep and it works quite well.