Bug with Fixed frame update

imtrobin

16-11-2007 03:53:26

I think there is a bug with fixed frame update.I turn on fixed frame update


mWorld = new NxOgre::World ("FrameListener: false");
mScene = mWorld->createScene ("myScene", mSceneMgr
,"gravity: 0 -9.8 0, floor: yes, time_step_method: fixed");


In FixedSceneController::Simulate, this line
mNxScene->simulate(mTiming_MaxStep - (mTiming_MaxStep - mTiming_CurrentStep));

is alway simulating a value lesser than 0 because the bracket evaluates to negative

If I understand what you are trying to do is to interpolate between the current and next frame, then you need an extra accumulator that should be something like

// stores accumulated time between each step, reset when step is updated
mAccumulated += deltaTime;
mNxScene->simulate(mTiming_CurrentStep + (AccumulateTime/mTiming_MaxStep));

betajaen

16-11-2007 10:33:02

Luis (or somebody) reminded me this earlier. I have a better SceneController now based of BloodyFantatic post in the Wheel thread, which uses an accumulator and some clever stuff with slerping.

It did require a huge change to how we render things though. ;)

imtrobin

16-11-2007 16:52:13

I was a little too rash to post. The code works, but I wasn't calling render to update. But the timestep is still not quite correct. Anyway, I will talk more with you about it offline.

http://www.gaffer.org/game-physics/fix-your-timestep/

betajaen

16-11-2007 17:52:55

That's the code/technique that BloodyFantatic mentioned.

Anyway, I've changed NxOgre so instead of each Actor takes care of rendering, a function of a class does it instead. Much like SceneController takes care of advancing a frame; SceneRenderer takes care of rendering the results of that frame.

It's totally inheritable and has some legacy support, it also allows full accumulator support with the new Accumulator Controller and the AccumulatorRenderer(Not written yet). But in practise works.

Oh, whilst coming up with the idea in front of Luis in MSN, he pointed out that you don't have to render if you don't want to, or even render to Ogre. Perhaps it could be a limited form of network support.

Anyway, I'll tell you more when this assignment for university is over.

BloodyFanatic

16-11-2007 21:39:14

great news, betajaen!
i'm really looking forward to the next version with the "smooth fixed timestep method" integrated. do you have any release date set? i mean, it's not urgent since what i do works, but i'd prefer "clean" code without my hacks ;)

betajaen

16-11-2007 21:41:59

Probably not for a few weeks.

Even if I released the new SceneRenderer code, people will complain that their triangle meshes and heightfields will crash and they can't use the Character Controller anymore.

[Edit]

This is the render function I was talking about. It fetches a "renderable" which contains a list of actors, characters, cloths, etc. that have either changed since last simulation, last render or everything (your choice).

The code can be quite simple like below, or rather complicated, or insane.

void GenericSceneRenderer::render() {

Renderable renderable = mScene->getRenderable(Scene::RT_TRANSFORM);

for (Actor* actor = renderable.actors.begin();actor = renderable.actors.next();) {

switch (actor->getType()) {

// Actors.
case NxHashes_Actor:
continue;
break;

// Bodys
case NxHashes_Body:
Body* body = static_cast<Body*>(actor);
body->getNode()->setPosition(body->getPosition());
body->getNode()->setOrientation(body->getOrientation());
break;

// Inherited Actors which aren't bodies.
default:
actor->renderSelf();
break;

}

//////////

actor->mVisualChange = false;

}

}



I should also point out; SceneRender::Render() is only called if you have a FrameListener attached to NxOgre.

Otherwise it's up to you if/when you want the Scene rendered regardless if it's been one frame or ten. Infact I'm pretty sure you could get away without using a SceneRenderer if you really wanted to.