Character is moving more slowly as framerate increases

Night Elf

19-09-2007 15:14:24

My character is moving more slowly when FPS are high. It seems it works fine if FPS < 60 or so.

This is the move() function in my CharacterMovementVectorController:
void CharacterMovementController::move(NxVec3& out, NxVec3& moveVector, NxQuat& direction, NxVec3& g, float t, NxOgre::Character*)
{
moveVector.normalize();
out = ((direction.rot(moveVector) * _speed) + g) * t;
}

What can I do about this?

Night Elf

20-09-2007 23:14:12

Any ideas about this? Maybe NxOgre/PhysX fixed at 60 FPS?

betajaen

21-09-2007 09:54:45

It's one of those really complicated things here. But it should be the reverse shouldn't? If your getting 999 FPS, then CharacterMovementVectorController should be hit 999 times in that second? Causing the character to move 999 times?

The easiest and laziest is to turn VSync on, the more complicated example is write some code to limit the amount of time the character can move in the second, but it also limits the graphics and physics.

It's quite similar to the FixedSceneIterator. You count up the time for each call of the function say 60 times; Over that time, you quickly exit without moving. If it's not allow some movement based of 1/60th of a second.

Something like this in C++/Pseudocode:


int lastFrame = 0;

void movementFunction() {

if (Ogre::getThisFrame != lastFrame && counter > 60) {
counter = 0;
}

if (counter > 60)
return;

counter++;
lastFrame = Ogre::getThisFrame();

moveVector.normalize();
out = ((direction.rot(moveVector) * _speed) + g) * 1.0f/60f;
}


I think my code is wrong, but I think you get the picture. Make the Character run at 60 Hertz and the rest at the scene as you will.

ebol

21-09-2007 11:47:34

Maybe its just me, but unless I haven't spotted this behavior in my application, which I doubt, my characters move at constant speed regardless of fps - with Vsync turned off but using variable scene controller.

Which scene controller are you using Night Elf?

Night Elf

21-09-2007 12:00:56

I'm using the fixed scene controller and I guess I've figured out what's wrong: NxOgre is updating the simulation at a fixed step, but passing the current frame interval to the simulate() functions.

Digging a bit inside NxOgre, I found this code that I think proves what I'm saying:

bool FixedSceneController::Simulate(NxReal deltaTime) {

mTiming_CurrentStep += deltaTime;

if (mTiming_CurrentStep < mTiming_MaxStep) {
mRenderFrame = false;
return false;
}

mNxScene->simulate(mTiming_MaxStep - (mTiming_MaxStep - mTiming_CurrentStep));

...etc...


The last line in the snippet calculates the interval as: mTiming_MaxStep - (mTiming_MaxStep - mTiming_CurrentStep), which in fact is nothing else but mTiming_CurrentStep. I'm guessing you wanted a different formula there, betajaen? That one doesn't make much sense to me...

betajaen

21-09-2007 12:07:41

Actually it's correct. The Timer method that Ogre and NxOgre uses is quite inaccurate, there's also a chance that there is a delay between each frame, which increases the deltaTime. So that function catches up the simulation in the next second.

You could write your own SceneController, that injects 1.0f/60.0f into PhysX no matter the frame rate though.

Night Elf

21-09-2007 12:14:53

I was just wondering why you'd use mTiming_MaxStep - (mTiming_MaxStep - mTiming_CurrentStep)) instead of just mTiming_CurrentStep. Weren't you intending something different in that expression?

betajaen

21-09-2007 12:58:44

I expect so. I was probably tired when I wrote that, like now when I can't read it. ;)