Tile Racer NxOgre0.4.RC3 Patch

LAva

24-01-2008 15:12:30

We use the old NxOgre 0.4 RC3, which was published under the LGPL license, in our Tile Racer game.
During the development I made some changes to the original code, which I now publish in this post.

The NxOgre 0.4 RC3 is really old. Betajaen doesn't support it any more and he encourages people to use the newer version of the lib!

A few changes I made:
- Linux compatible (removed some features in order to use it with the first PhysX Linux version)
- added access to all static or dynamic bodies.
- added interpolation between calculation steps
- added a Ogre::SceneNode update after the position and orientation was set (to update all children as well)
- pass contact pair information to the contact reptorter

Patch: http://tileracer.model-view.com/download/NxOgre.0.4.RC3_TileRacer_patch
Tile Racer: http://tileracer.model-view.com

betajaen

24-01-2008 15:58:39

As nearly all of us 0.9 now, and I discourage other people to use anything else. It is much appreciated.

luis

24-01-2008 16:18:46

Thankyou LAva !
I'll check it ASAP, is it the complete 0.4rc3 plus changes or only a patch ?
I dont know if there is still a 0.4rc3 zip out there....

no, this link is broken:
http://get.nxogre.org/0.4.RC3/NxOgre.0.4.RC3.zip

I really want to see your patch & nxogre 0.4rc3 in order to see how to fix the jittering in 0.9......

Betajaen, do you have a 0.4rc3 ? LAva ?

betajaen

24-01-2008 17:28:20

I don't have a copy anymore, and I've removed it from the NxOgre.org webserver. But you should be able to work out his interpolation code from the patch.

+void body::render(float alpha) {
+ if (alpha < 0) {
+ alpha=0;
+ } else if (alpha > 1) {
+ alpha=1;
+ }
+
+ Ogre::Vector3 renderPos = mPreviousPosition + (mDestPosition - mPreviousPosition) * alpha;
+ Ogre::Quaternion renderOri = Ogre::Quaternion::Slerp(alpha,mPreviousOrientation,mDestOrientation,true);
+
+ mNode->setPosition(renderPos);
+ mNode->setOrientation(renderOri);
+ mNode->_update(true,true);
}


It's like how we do it in Bleeding.

weak

24-01-2008 18:04:42


It's like how we do it in Bleeding.


which is still wrong ;)

btw, will that be fixed in the upcoming release?

betajaen

24-01-2008 18:34:48

Well his code is wrong too then.

LAva

24-01-2008 19:09:13

The whole physic jitter thing is really complex.
There is also the chance to screw it up outside the nxOgre lib.
(This happened in Tile Racer very often, but most of the time it had something to do with the 3rd person cam, which is kind of attached to the physic body of the car.)

weak

24-01-2008 19:10:34

Well his code is wrong too then.

exactly

LAva

24-01-2008 19:25:47

what exactly is wrong about it?

luis

24-01-2008 19:33:43

I tried TileRacer with variable frame rate and at differents FPS and it work PERFECT i didnt notice any jittering.

The math in the interpolation code is OK in nxogre 0.9, the problem is in the moment at lastpose gets saved. It should be saved only when a simulation step is made (and it isn't the case in current version).

I reproduced the jittering in ageia's demo and inplemented Gaffer method there and it fixed the jittering, but doing it in nxogre doesn't work.

Obviously i'm doing something wrong so i hope this patch will give me an answer. In my opinion, the jittering is a very serious bug in the wrapper, and going to variable time step has other problems (even worse) so it needs to be fixed if you want to have a good vehicle simulation.

This is the code i'm using now:

bool AccumulatorSceneController::Simulate(NxReal deltaTime) {
mDeltaTime = mTimer.getMicroseconds()*1.0e-6;
if( mDeltaTime > 0.2 ) // 5hz
{
mTimer.reset();
mDeltaTime = 0.2;
}
mAccumulator += mDeltaTime;
mSimulated = false;
while( mAccumulator >= mDt ) {
mScene->getSceneRenderer()->saveLastPoseSources();
mSimulated = true;
mNxScene->simulate( mDt );
mNxScene->flushStream();
mNxScene->fetchResults(NX_RIGID_BODY_FINISHED, true);
mAccumulator -= mDt;
}
mAlpha = mAccumulator / mDt;
mTimer.reset();
//Ogre::Root *root = Ogre::Root::getSingletonPtr();
//unsigned long frame = root->getCurrentFrameNumber();
//_cprintf( "AccumSnController mAlpha: %.4f FN: %d mSimulated: %d\n", mAlpha, frame, (int)mSimulated );
return true;
}


void Body::__renderSelf() {
switch (mInterpolation) {
case I_Absolute:
{
mDeltaPose = getGlobalPose();
mRenderable->setPose(mDeltaPose);
mLastPose = mDeltaPose;
}
break;

case I_Linear:
{
Pose blended_pose = NxInterpolate(mLastPose, getGlobalPose(), mOwner->getLastAlphaValue());
mRenderable->setPose(blended_pose);
static_cast<NxOgre::OgreNodeRenderable *>( mRenderable )->getNode()->_update( true, true );
}
break;


I have pending to change the wheels code to be relative to the chassis's scenenode (instead of beeing relative to its physics representation).

But still with that code i'm having small jitterings in the body itself :(

weak

24-01-2008 20:19:18

what exactly is wrong about it?

actually i didn't look at your implementation at all, but if it's the same as in bleeding it can't work correctly.
as already discussed in another thread you can't predict the future. using the last two frames to interpolate the next position can't work for obvious reasons (eg. an obstacle between the last and the interpolated position). although it may seem right for most situations it simply can't handle all situations properly.
you have to introduce a latency of one simulation step and interpolate between the last and the current position. but maybe you're already doing it that way...

LAva

24-01-2008 20:23:50

I don't predict the future. I take the latency of one simulation step (or less) and it works great.