different results on different PC's

yuriythebest

23-09-2008 22:49:32

right, an important lesson that I learnt from my previous experiments in ogre is to always test your app on different types of pc's as early as possible. This proved to be very wise in this case as the character speed and jumping ability is very different on the two that I tested:


Quad core + 8600Gts + 4gb ram
= character barely jumps, moves slowly

pentium 4 + 6600Gts + 1Gb ram = character runs fast and jumps high

I always assumed as long as I multiply all the speeds in frameStarted by evt.timeSinceLastFrame that I would get consistent results since when you create the mOgreNewtListener you input the ogreNewt frame rate- I was proved wrong.

my character callback:

void mainApp1App::ivanCallback (OgreNewt::Body* me)
{

//prevent falling asleep
me->unFreeze();

//control actual motion velocity based on keys pressed
if (isJumping){
me->setVelocity(Vector3(spd.x, spd.y, spd.z));
}else{
me->setVelocity(Vector3(spd.x, me->getVelocity().y, spd.z));
spd.y=0;
}

//add gravity
me->addForce(Vector3(0,-9.8,0));

//so the cube doesn't rotate
me->setOmega(Vector3(0,0,0));
//might be redundant- also to top rotation
me->getPositionOrientation(bodyPos, bodyOrient);
me->setPositionOrientation(bodyPos , bodyOrientOriginal );

}



and here is how I move the character (I've only included the code that moves him left for brevity:


// move ivan left
}else if(mKeyboard->isKeyDown(OIS::KC_M)){


spd=Vector3(ivanSpeed*evt.timeSinceLastFrame,spd.y*evt.timeSinceLastFrame,0);
charNode->setOrientation(Quaternion(0.707107,0,0.707107,0));


}



I use a Vector3 called spd which is then used by the callback

BardockSSJ

24-09-2008 10:34:06

not use! bad way :)

better is create somthing i name "acumulator" to update te game in constant frame rate. it works great on every computer!


global: float AcumulatedTime = 0.0;

in frameStarted ogre framelisterner event:
{
AcumulatedTime += evt.TimeSinceLastFrame;
while (AcumulatedTime > TIMESTEP (example 1/60)) {
UpdateGameLogick();
UpdateInput();
UpdatePhysic();
AcumulatedTime -= TIMESTEP;
};
};


And it is best i think solution to keep game indepent;

You should also no use Newton Frame Listener, just update world manualy and toggle debugger mesh too manually.

yuriythebest

25-09-2008 16:01:57

thank you BardockSSJ but when I try to implement your code the game freezes on the first frame like it doesn't update.

my code:

//at the top near the include files I've created these vars:
float AcumulatedTime = 0.0;
const float TIMESTEP= 1/60;


bool mainApp1App::frameStarted(const FrameEvent& evt)
{

AcumulatedTime += evt.timeSinceLastFrame;
while (AcumulatedTime > TIMESTEP) {

//my game code



AcumulatedTime -= TIMESTEP;
};



return BaseApplication::frameStarted(evt);

}




BardockSSJ

25-09-2008 17:06:35

You need call update on OgreNewt::World * in every frame

mWorld->update( TIME_STEP );

yuriythebest

15-11-2008 19:39:00

okey my code is now so:



float AcumulatedTime = 0.0;
const float TIMESTEP= 1/60;


.
.
.

bool ogreNewttest2App::frameStarted(const FrameEvent& evt){



mWorld->update( TIMESTEP );


AcumulatedTime += evt.timeSinceLastFrame;
while (AcumulatedTime > TIMESTEP ) {




//game code

AcumulatedTime -= TIMESTEP;
}


}


however my game still freezes- not just the ogreNewt stuff but also everything else- camera movement/debug UI/etc does not update.

also in "the game code" I put all my commands directly that do the game logic is that ok?

nullsquared

16-11-2008 19:37:33

1) it should be while (AccumulatedTime >= TIMESTEP)

2) keep game logic and what-not as you had it before (outside of that while-loop), only use the mWorld->update(TIMESTEP) code inside that loop

3) make sure your TIME_STEP = 1.0 / 60.0, not just 1 / 60, since that's integer division and will give you 0 (you want 1.0 / 60.0 = decimal)