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.
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.
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.
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.)
Well his code is wrong too then.
exactly
what exactly is wrong about it?
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
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...
I don't predict the future. I take the latency of one simulation step (or less) and it works great.