Frame Rate Independence

abaraba
Posts: 56
Joined: Thu Jun 19, 2008 7:54 am

Re: Frame Rate Independence

Post by abaraba »

I used the term "newbies" to refer to simple apps..
you are right, sorry...
i did exaggerate there a bit because i was struggling to prove my point otherwise ..i felt it was worth it
BTW, in the end, it looks like Bullet works exactly as i expected, and the only problem seems to have been communication
yes, terminology.. but, thats where my question only begins really..

>>"The (dt,0) way works correctly."

you on to it,
(dt,0) does work (as i expect at least) and we needed to establish that, so we all exactly know what *visually* we are talking about and can move on ..compare that with *interpolation*, that is (dt, n>1)

you can try (dt, 10or50or100..), overload your scene and tell us what happens and what did you expect to happen, if you will?

[when i do that i notice everything slows down and i expect similar output as with (dt, 0)]

//---------------
terminology explained:
if you're reading this to get an answer to the original question "Frame Rate Independence",
and by now you only got even more confused..

note that there are
- simulation frames, simulation frame rate = simulation speed or rate of physics update
- animation frames, animation frame rate = animation speed or FPS

they go so closely together,
no wonder it confuses so many people... btw answer to my 1st Q. is NO... surprised, eh?

look,
"Frame Rate" in this conversation meant few things, depending on who was talking it could be:
1.) simulation speed
2.) animation speed
3.) deltaTime

when i say "Frame Rate" i mean "animation frame-rate", animation speed or FPS like most of us apparently, hence confusion

by "Frame Rate Independence" i meant:
animation speed may VARY, but Simulation_Flow can still appear CONSTANT in real time


to me, this is only independence that makes sense talking about,
im really failing to see of what importance or relevance is any other independence and how was it not obvious what is common expectation, common terminology and what would be likely error


thanks for sharing
Last edited by abaraba on Thu Aug 28, 2008 3:39 pm, edited 3 times in total.
stenyak
Posts: 29
Joined: Fri Aug 12, 2005 4:59 pm

Re: Frame Rate Independence

Post by stenyak »

I still haven't coded the synchronization routines for inter-engine (physics<->graphics<->input<->etc....) communication, so i'm running headless simulations.

These are the results of my simple test. There are 4 independent physics engines running at the same time, at 300, 100, 60 and 10Hz respectively. I run them for 4 seconds, one second at a time, and these are the results of the helloworld body height as it falls from its initial position of 50 units up in the air:

<< Finished 300 steps at 300 Hz. Final position: 44.95
<< Finished 100 steps at 100 Hz. Final position: 44.85
<< Finished 60 steps at 60 Hz. Final position: 44.75
<< Finished 30 steps at 30 Hz. Final position: 44.5

<< Finished 300 steps at 300 Hz. Final position: 29.8999
<< Finished 100 steps at 100 Hz. Final position: 29.7
<< Finished 60 steps at 60 Hz. Final position: 29.5
<< Finished 30 steps at 30 Hz. Final position: 29

<< Finished 300 steps at 300 Hz. Final position: 4.84998
<< Finished 100 steps at 100 Hz. Final position: 4.54993
<< Finished 60 steps at 60 Hz. Final position: 4.25001
<< Finished 30 steps at 30 Hz. Final position: 3.49999

<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999991
<< Finished 60 steps at 60 Hz. Final position: 0.99899
<< Finished 30 steps at 30 Hz. Final position: 0.995528

I may do some "substepping" tests later (i won't be using them in my project anyway so it's very low prio...)
abaraba
Posts: 56
Joined: Thu Jun 19, 2008 7:54 am

Re: Frame Rate Independence

Post by abaraba »

its good to have someone to talk to about this... cheers!

i still have no idea if iam reporting a bug or my stupidity here..

anyway,
ok, that looks all good to me.. not really testing the case in question?

- because you still use (dt, 0)?
- you have plenty of time left to sleep() after each simulation and animation frame even with 1/300 step or not?
- do you know how dt vary or perhaps is steady... with scenes of different complexity and/or moving camera dt should change more and make measurements that much more interesting...

what units you use? size? gravity? damping_or_whatever_else?


i wonder what kind of effect could have *video driver* setting that would lock FPS to Vsync , you know that option:
1.) let application decide
2.) always
3.) never


thanks,
friendly zebra
Last edited by abaraba on Thu Aug 28, 2008 3:30 pm, edited 1 time in total.
stenyak
Posts: 29
Joined: Fri Aug 12, 2005 4:59 pm

Re: Frame Rate Independence

Post by stenyak »

I'm now using this exact piece of code. substepping turns substeps ON/OFF, and substeps is the max number of substeps to compute. I believe the 2 systems are equivalente, but please point out if you find any bug.

IMPORTANT: i'm not reading the world state when X steps pass, but when X seconds pass. That is, i use a timer between pause and pause. Therefore, it's not guaranteed that 300 steps will be computed during one second at 300Hz. However, this happens almost always with the first case, and almost never in the rest of cases (which is why it's taking me so long to edit the results in the post, because i have to make several runs before i get a consistent one...).

Code: Select all

            const bool substepping = true;
            const int substeps = 100;
            if (substepping)
            {
                int countInc = dynamicsWorld->stepSimulation(dt.total_microseconds()/1000000.,substeps,1./getFrequency());
                count += countInc;
                lasttime += period * countInc;
            }
            else
            {
                while (dt > halfperiod) //TODO: merge this loop with the parent, so that the thread can be pauses if physics get under realtime.
                {
                    ++count;
                    dynamicsWorld->stepSimulation(1./getFrequency(),0);
                    dt -= period;
                    lasttime += period;
                }
            }
And the positions are retrieved with this code:

Code: Select all

    btTransform trans;
    fallRigidBody->getMotionState()->getWorldTransform(trans);
    std::cout<<"<< Finished "<<count<<" steps at "<<getFrequency()<< " Hz. Final position: "<< trans.getOrigin().getY() << std::endl;
These are the results:
no substepping wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.95
<< Finished 100 steps at 100 Hz. Final position: 44.85
<< Finished 60 steps at 60 Hz. Final position: 44.75
<< Finished 30 steps at 30 Hz. Final position: 44.5
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.8999
<< Finished 100 steps at 100 Hz. Final position: 29.7
<< Finished 60 steps at 60 Hz. Final position: 29.5
<< Finished 30 steps at 30 Hz. Final position: 29
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.84998
<< Finished 100 steps at 100 Hz. Final position: 4.54993
<< Finished 60 steps at 60 Hz. Final position: 4.25001
<< Finished 30 steps at 30 Hz. Final position: 3.49999
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999991
<< Finished 60 steps at 60 Hz. Final position: 0.99899
<< Finished 30 steps at 30 Hz. Final position: 0.995528
max 10000 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9581
<< Finished 100 steps at 100 Hz. Final position: 44.9038
<< Finished 60 steps at 60 Hz. Final position: 44.764
<< Finished 30 steps at 30 Hz. Final position: 44.7664
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.9785
<< Finished 100 steps at 100 Hz. Final position: 29.7678
<< Finished 60 steps at 60 Hz. Final position: 29.6784
<< Finished 30 steps at 30 Hz. Final position: 29.167
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.86899
<< Finished 100 steps at 100 Hz. Final position: 4.67576
<< Finished 60 steps at 60 Hz. Final position: 4.5475
<< Finished 30 steps at 30 Hz. Final position: 4.16572
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999989
<< Finished 60 steps at 60 Hz. Final position: 0.998869
<< Finished 30 steps at 30 Hz. Final position: 0.994024
max 100 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9819
<< Finished 100 steps at 100 Hz. Final position: 44.888
<< Finished 60 steps at 60 Hz. Final position: 44.7536
<< Finished 30 steps at 30 Hz. Final position: 44.6459
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.9117
<< Finished 100 steps at 100 Hz. Final position: 29.7587
<< Finished 60 steps at 60 Hz. Final position: 29.5242
<< Finished 30 steps at 30 Hz. Final position: 29.0363
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.91648
<< Finished 100 steps at 100 Hz. Final position: 4.685
<< Finished 60 steps at 60 Hz. Final position: 4.3828
<< Finished 30 steps at 30 Hz. Final position: 3.71284
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999991
<< Finished 60 steps at 60 Hz. Final position: 0.998838
<< Finished 30 steps at 30 Hz. Final position: 0.994509
max 25 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9613
<< Finished 100 steps at 100 Hz. Final position: 44.8854
<< Finished 60 steps at 60 Hz. Final position: 44.8123
<< Finished 30 steps at 30 Hz. Final position: 44.8477
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.9041
<< Finished 100 steps at 100 Hz. Final position: 29.8604
<< Finished 60 steps at 60 Hz. Final position: 29.6729
<< Finished 30 steps at 30 Hz. Final position: 29.4106
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.90391
<< Finished 100 steps at 100 Hz. Final position: 4.77254
<< Finished 60 steps at 60 Hz. Final position: 4.70113
<< Finished 30 steps at 30 Hz. Final position: 4.07179
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999987
<< Finished 60 steps at 60 Hz. Final position: 0.998893
<< Finished 30 steps at 30 Hz. Final position: 0.99417
max 15 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9813
<< Finished 100 steps at 100 Hz. Final position: 44.9197
<< Finished 60 steps at 60 Hz. Final position: 44.8079
<< Finished 30 steps at 30 Hz. Final position: 44.8892
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.9637
<< Finished 100 steps at 100 Hz. Final position: 29.8348
<< Finished 60 steps at 60 Hz. Final position: 29.6534
<< Finished 30 steps at 30 Hz. Final position: 29.5013
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.94549
<< Finished 100 steps at 100 Hz. Final position: 4.67464
<< Finished 60 steps at 60 Hz. Final position: 4.69588
<< Finished 30 steps at 30 Hz. Final position: 3.64771
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999988
<< Finished 60 steps at 60 Hz. Final position: 0.998703
<< Finished 30 steps at 30 Hz. Final position: 0.994792
max 10 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9695
<< Finished 100 steps at 100 Hz. Final position: 44.882
<< Finished 60 steps at 60 Hz. Final position: 44.9373
<< Finished 30 steps at 30 Hz. Final position: 44.6227
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.935
<< Finished 100 steps at 100 Hz. Final position: 29.771
<< Finished 60 steps at 60 Hz. Final position: 29.7721
<< Finished 30 steps at 30 Hz. Final position: 29.4246
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.9052
<< Finished 100 steps at 100 Hz. Final position: 4.65617
<< Finished 60 steps at 60 Hz. Final position: 4.62355
<< Finished 30 steps at 30 Hz. Final position: 3.9646
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999989
<< Finished 60 steps at 60 Hz. Final position: 0.998956
<< Finished 30 steps at 30 Hz. Final position: 0.993704
max 5 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 44.9803
<< Finished 100 steps at 100 Hz. Final position: 44.9109
<< Finished 60 steps at 60 Hz. Final position: 44.903
<< Finished 30 steps at 30 Hz. Final position: 44.7792
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 29.9535
<< Finished 100 steps at 100 Hz. Final position: 29.8034
<< Finished 60 steps at 60 Hz. Final position: 29.5829
<< Finished 30 steps at 30 Hz. Final position: 29.6838
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 4.94099
<< Finished 100 steps at 100 Hz. Final position: 4.66523
<< Finished 60 steps at 60 Hz. Final position: 4.44343
<< Finished 30 steps at 30 Hz. Final position: 3.5473
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999988
<< Finished 60 steps at 60 Hz. Final position: 0.998958
<< Finished 30 steps at 30 Hz. Final position: 0.995482
max 3 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 45.0394
<< Finished 100 steps at 100 Hz. Final position: 44.9692
<< Finished 60 steps at 60 Hz. Final position: 44.847
<< Finished 30 steps at 30 Hz. Final position: 44.69
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 30.0643
<< Finished 100 steps at 100 Hz. Final position: 29.8278
<< Finished 60 steps at 60 Hz. Final position: 29.803
<< Finished 30 steps at 30 Hz. Final position: 29.5404
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 5.09172
<< Finished 100 steps at 100 Hz. Final position: 4.77863
<< Finished 60 steps at 60 Hz. Final position: 4.62727
<< Finished 30 steps at 30 Hz. Final position: 4.36807
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999987
<< Finished 60 steps at 60 Hz. Final position: 0.998888
<< Finished 30 steps at 30 Hz. Final position: 0.9952
max 2 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 45.093
<< Finished 100 steps at 100 Hz. Final position: 44.8818
<< Finished 60 steps at 60 Hz. Final position: 44.7908
<< Finished 30 steps at 30 Hz. Final position: 44.6122
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 30.2181
<< Finished 100 steps at 100 Hz. Final position: 29.8874
<< Finished 60 steps at 60 Hz. Final position: 29.7461
<< Finished 30 steps at 30 Hz. Final position: 29.326
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 5.27164
<< Finished 100 steps at 100 Hz. Final position: 4.5986
<< Finished 60 steps at 60 Hz. Final position: 4.50991
<< Finished 30 steps at 30 Hz. Final position: 4.06084
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 1
<< Finished 100 steps at 100 Hz. Final position: 0.999988
<< Finished 60 steps at 60 Hz. Final position: 0.998936
<< Finished 30 steps at 30 Hz. Final position: 0.993844
max 1 substeps wrote: (1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 46.076
<< Finished 100 steps at 100 Hz. Final position: 45.4047
<< Finished 60 steps at 60 Hz. Final position: 45.3614
<< Finished 30 steps at 30 Hz. Final position: 45.1331
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 33.9136
<< Finished 100 steps at 100 Hz. Final position: 32.0674
<< Finished 60 steps at 60 Hz. Final position: 32.4089
<< Finished 30 steps at 30 Hz. Final position: 33.4197
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 14.5084
<< Finished 100 steps at 100 Hz. Final position: 9.30374
<< Finished 60 steps at 60 Hz. Final position: 11.221
<< Finished 30 steps at 30 Hz. Final position: 11.7972
(1.0 seconds elapsed)
<< Finished 300 steps at 300 Hz. Final position: 0.999509
<< Finished 100 steps at 100 Hz. Final position: 0.9975
<< Finished 60 steps at 60 Hz. Final position: 1.49259
<< Finished 30 steps at 30 Hz. Final position: 1.04568
max 0 substeps wrote: (1.0 seconds elapsed)
<< Finished 493 steps at 300 Hz. Final position: -138199
<< Finished 187 steps at 100 Hz. Final position: -33714.1
<< Finished 116 steps at 60 Hz. Final position: -14794.6
<< Finished 60 steps at 30 Hz. Final position: -4528.75
(1.0 seconds elapsed)
<< Finished 431 steps at 300 Hz. Final position: -1.10227e+11
<< Finished 173 steps at 100 Hz. Final position: -2.15859e+10
<< Finished 112 steps at 60 Hz. Final position: -3.48767e+10
<< Finished 59 steps at 30 Hz. Final position: -6.02033e+09
(1.0 seconds elapsed)
<< Finished 362 steps at 300 Hz. Final position: -4.54513e+16
<< Finished 166 steps at 100 Hz. Final position: -1.23049e+16
<< Finished 107 steps at 60 Hz. Final position: -7.15754e+16
<< Finished 57 steps at 30 Hz. Final position: -7.48711e+15
(1.0 seconds elapsed)
<< Finished 331 steps at 300 Hz. Final position: -3.21032e+22
<< Finished 158 steps at 100 Hz. Final position: -2.85914e+22
<< Finished 103 steps at 60 Hz. Final position: -1.29481e+23
<< Finished 55 steps at 30 Hz. Final position: -5.61669e+21
Conclussions:
Obviously, bullet is inconsistent in its behaviour when maxSubsteps==0, no matter if you specify the substep timestep or not. IMHO this should be changed, since it is not intuitive. Passing maxSubsteps=0 should result in an exception being thrown, or something similar. Well, even better would be to simply return 0 as number of steps computed... but then the user has to check for this value (which he already should be doing anyway, except that in the helloworld demo this is not done, which could clearly be one of the reasons why people can't achieve framerate independence if they base their code off the helloworld source.... haven't checked the rest of bullet demos, but i hope they don't repeat the same mistake!!)

We can see that the results differ depending on the maxSubsteps used.

In my tests, i've checked that using substepping, the number of steps per seconds almost always vary (sometimes 300, sometimes 299, sometimes 301, or 304, etc.). This should correct overtime, giving a correct average number of steps per second, and shows that the behaviour is very accurate, but not precise (see wikipedia on how these 2 terms differ xD). However, without substepping, the results are almost always 300 steps (as it should). This means that:
- Using both substepping and no-substepping gives perfect accuracy.
- Using substepping does not give perfect precission.
^----- all of this, i'm talking about simulated time vs. wall time. not about the accuracy/precission of the simulation itself.

Also, it must be noted that, in all cases, statemotions have been used. This means that, if the docs are correct, the interpolation could account for the differences between different maxSubsteps (with substepping enabled). Since i'm tired of testing, i won't try the same batch of tests without them. It's enough to know that, if using statemotions AND not using substepping you always get the same results (so no interpolation going on).

The rest of conclusions (why there are differences in the position of the body) are up to the reader, because i've had enough of these tests and can't think clearly enough to extract more conclussions out of the data anymore :wink:
Last edited by stenyak on Thu Aug 28, 2008 4:06 pm, edited 5 times in total.
abaraba
Posts: 56
Joined: Thu Jun 19, 2008 7:54 am

Re: Frame Rate Independence

Post by abaraba »

thanks..

ok,
i see all that.. something... numbers... submarines... rainbows

it all looks fine,
except that little bit there which is horribly wrong, so maybe some problem in the test?


your comment is most valuable to me... i dont absorb numbers well and im not really sure whats happening there with all these threads and sleep() stuff.. how many processors/cores, what hardware is that?


appreciated


[edit:]
man, that was super-quick, how wonderful ..anything i can do for you?

crunching..........
Passing maxSubsteps=0 should result in an exception being thrown, or something similar.
ok, you lost me there...



//--------------------
To Whom it may concern...

CcdPhysicsDemo has this bit of code:

Code: Select all

      //during idle mode, just run 1 simulation step maximum
      int maxSimSubSteps = m_idle ? 1 : 1;
      if (m_idle)
         dt = 1.0/420.f;

      int numSimSteps = 0;
      numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
a) all that change to this:

Code: Select all

 m_dynamicsWorld->stepSimulation(dt, 0);
b) then to this:

Code: Select all

   m_dynamicsWorld->stepSimulation(dt, 10or50or100..); 
then try to overload the scene eg. resize to full-screen, add more objects, add empty loop to eat your time randomly or whatever ..and then compare a) and b) ...visual observation would suffice
Last edited by abaraba on Thu Aug 28, 2008 4:30 pm, edited 2 times in total.
stenyak
Posts: 29
Joined: Fri Aug 12, 2005 4:59 pm

Re: Frame Rate Independence

Post by stenyak »

abaraba wrote:
Passing maxSubsteps=0 should result in an exception being thrown, or something similar.
ok, you lost me there...
Well, when using maxSubsteps, according to the general behaviour, you're telling Bullet to compute X seconds of simulation in no more than 0 steps.
That's like saying: "carry this big pile of boxes to the truck over there, but carry no more than zero boxes each time you go."
Which obvisouly doesn't make sense.
But bullet translates that into "carry this big pile of boxes to the truck over there, and do it in ONE go, carrying all the boxes at once."

Obviously, that's inconsistent behaviour. The user should check that he's asking impossible things. That's like trying to divide by zero, and expect the CPU to compute an addition instead of freaking out! Makes no sense.

Well, it's an acceptable behaviour, but a bit hackish, and very C-ish. If at least the special behaviour was used when the maxSubsteps was negative, leaving 0 for "no computation at all", or something.

Currently, after all these tests, i feel like that's the only thing in the API that should be changed (not to mention a good update to the docs in order to make it all more clear).
abaraba
Posts: 56
Joined: Thu Jun 19, 2008 7:54 am

Re: Frame Rate Independence

Post by abaraba »

i dont understand anything anymore...

are you not the same person whom Erwin wrote:
Again, if you want to manage time and substepping yourself, with similar behaviour to ODE, disable substepping, don't use/create motion states and use

stepSimulation(deltaTime,0);
and you said:
Yes, thanks a lot, it helped. I've been reading so many different ways to do the same thing, that i didn't know which one to choose. The (dt,0) way works correctly.

I've implemented the helloWorld in my ..
which basically means that you already used maxSubsteps=0 successfully - its a special case ..so, no.. it what they call variable time_flg_adfk .. i give up
stenyak
Posts: 29
Joined: Fri Aug 12, 2005 4:59 pm

Re: Frame Rate Independence

Post by stenyak »

abaraba wrote:which basically means that you already used maxSubsteps=0 successfully - its a special case ..so, no.. it what they call variable time_flg_adfk .. i give up
Forget my words and read the last code i posted.
I used maxSubsteps=0 succesfully, but i handle the time passed manually, making sure it's always constant. I never feed Bullet with deltatime. I mentioned "(dt,0)" because i use "certain number",0 and no other parameter, not because my difference of time to compute is what is usually called "deltatime" in this thread.

The mentioned code works properly; the first branch is what is suggested to be used by Bullet docs, while the second branch is the ODE way, which is equally good, but the docs don't recommend to use it because they assume you don't have the knowledge to use it properly.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Frame Rate Independence

Post by Erwin Coumans »

Thanks for everyones feedback, we will amend the API for Bullet 3.x to make it more consistent and clear. The original poster solved his problem by using seconds instead of milliseconds, and using a larger default maximum number of substeps. This thread is becoming repetitive and unproductive, so I'm going to lock it down and repeat one last time:

Bullet simulation internally only supports constant, fixed, non-varying time steps.

So user can choose to
(1) let Bullet automatic subdive the user-provided delta time into fixed/constant substeps (60 hertz by default), similar to Fix Your Timestep:

Code: Select all

//use default constant substep of 60 hertz
stepSimulation(deltaTime); 

//use a higher quality, smaller constant substep of 240 hertz
btScalar constantSubStep = 1./240.;
//clamping value to avoid simulation grinding down to a halt.
int maximumNumberOfSubsteps=10; 
stepSimulation(deltaTime, maximumNumberOfSubsteps, constantSubStep);
(2) disable Bullet's automatic subdivision of the time step and let the developer be responsible for passing in a fixed timestep, like Open Dynamics Engine:

Code: Select all

stepSimulation(deltaTime,0);
Both methods are good ways to simulate using a fixed, non-varying, time step.
Thanks,
Erwin

By the way, Havok and PhysX suffer similar problems and recommend similar solutions:
http://softwarecommunity.intel.com/isn/ ... 62914.aspx
See Timing in this link:
http://developer.nvidia.com/object/physx_tips.html