PhysX+OGRE: how to simulate smoothly?

xius

08-05-2009 15:08:08

Hi, more experienced colleagues!
Every frame I'm updating position and orientation of every mesh in my scene. And here comes a problem:

bool frameStarted(const FrameEvent& evt) {
...
updateAllPhysics(evt.timeSinceLastFrame);
return true;
}


Everything had moved extremely slow (fps: 1500-2000). So, I just multiplied evt.timeSinceLastFrame by 10. :) It was a prototype, stinky code is allowed, isn't?
Then I added fluid. With some hundreds particles, fps drops to 20. (yes, this is not fluid problem, it's all about that multiplying) It wasn't even rendered yet. :/ Experimenting with PhysX demos, I was able to create and render (point sprites only) about 15000 particles with 100+ fps...
I've read couple of threads here but still don't understand how to make it run smoothly with OGRE. I know evt.sinceLastFrame is an average value. I've look at Ogre::Timer class and tried to use it... No progress.

How to glue OGRE and PhysX timing together and get decent results?

betajaen

08-05-2009 15:21:57

Usually, it's best to update parts of the Scene that have been moved (see Active Transform Notification). Then implement batching in Ogre to reduce the number of writing and reading to the graphics card (this is more important than the number of triangles - and will be the major cause in frame drop). Then implement interpolation to smooth out the positions per frame.

xius

09-05-2009 11:51:05

Let's see whether I understand it correctly:
My main problem is working with meshes/objects in a clumsy way. It's ok while I have just a few of them, but when I add fluid with thousands of sprites it's quite obvious. So that my "evt.timeSinceLastFrame*10.0f" is perfectly acceptable interpolation while it gives smooth results.
Right?

betajaen

09-05-2009 12:07:17

Yes, It is a little clumsy. But like I said batching them together would increase your FPS. You may be able to work with the Ogre Particle or Billboard system to render your particles; rather than using the scene-node/entity approach. As for Entities using the same mesh. This is more of an Ogre question, and I really don't know any of those batching techniques. Perhaps the Wiki can help.

That isn't interpolation, it's just speeding up time. Interpolation is where you calculate the position of an object between frames. As computer clocks aren't entirely accurate, and you have a multi-tasking OS. You can't assume that the time-step will be the same as the previous one (it may be a few milli-seconds off). Errors are bound to creep in and cause slight errors that are noticeable (jittering). I wouldn't worry about that now. "Jittering" is only really noticed with the wheel system, and extremely fast moving objects, which I don't think your using.

Also; Use ActiveTransformNotification. PhysX will give you a list per frame of the NxActors that have moved. Reducing the redundant updates of static actors, particles and other objects that are sleeping.

xius

09-05-2009 14:14:33

Yes, since yesterday I'm using ActiveTransformNotification. 8) Very nice improvement, thanks for mention it. For fluid is used MovableObject. (about batching techniques, I've found quite enough info about it, so thanks again!)

Main loop:
- frame starts
- Ogre::Timer returns ms since last frame and passes it to Scene->simulate()
- OGRE moves with objects which have moved (yay for ActiveTransformNotification)
- repeat

I have only one cube in the scene and it moves quite slow. Everything is slow. FPS is high. :) I can't really see why... Isn't there a simple solution how could it be fixed? (move faster without loss of precision/performance) Physics is ok. No strange behaviour even with 100 cubes.
What about passed time x10 and timeStep 10 times bigger? Sorry, if I'm still missing your point. I really appreciate your effort.

Also, you're right, no wheels and extremely fast moving objects. :)

betajaen

09-05-2009 14:31:35

Remember when you pass on a time value into PhysX. It is measured in seconds. So if the time passed in Ogre, was 0.01667 s then you modify it to 0.1667 s, then time is passing ten times as faster than usual.

As for your slow cubes; that seems a little strange. Does it seem to be slow when the cube is falling?



Also; For the sake of many of us. Do you fancy showing us your MovableObject/Fluid code? ;)

xius

09-05-2009 16:45:18

Exactly. But what if timeStep is set to 1.0f/10.0f? It would make things right or worse?

Falling, interacting, rolling... Gravitation is set to (0, -9.8, 0).

You and many others would be really disappointed. :) Right now it's just many points in space without any cool code or look... My latest searching+reading here implies that some subclass of SimpleRenderable would better fit my needs.
This project is something I have to create in order to finish my bachelor thesis. When it comes to point to be something more than just bunch of experiments, I have no problem with showing my solution. (actually, I'll be glad if it would be considered useful)

betajaen

09-05-2009 17:42:39

Then each step is 0.1 of a second. I would go at a fixed 1.0f/60.0f which is considered standard, besides Ogre works at 1/60.0f in vertical sync mode. So it pairs up well.

Anything you got it fine, I remember having some major troubles with trying to render fluid. Perhaps it will help me when I implement it into Bloody Mess.

AnTeevY

09-09-2009 10:40:33

I would go at a fixed 1.0f/60.0f which is considered standard, besides Ogre works at 1/60.0f in vertical sync mode. So it pairs up well.
That's what I'm doing with ThriceBall, but what if the FPS drop below 60? Then everything gets slooow. But passing the time since the last frame to NxOgre is somehow laggy. Is there a better way to do this?

betajaen

09-09-2009 10:59:20

Sadly no. The accumulator in Bleeding/Mess is based of that article was linked in your ThriceBall thread. One of the known problems is that the simulation tends to break apart under 60 fps.

Personally, I would just render as fast as possible, and just let the accumulator spread out the physics across the second.

[Edit]

Actually, there is one thing you could try. In NxOgreScene.cpp find the line;

scene_description.timeStepMethod = NX_TIMESTEP_VARIABLE; // temp.

and change to

scene_description.timeStepMethod = NX_TIMESTEP_FIXED; // temp.

I would also advice you to upgrade to the Git version. There have been some changes and fixes since 1.5.5 that may help.

AnTeevY

09-09-2009 15:51:12

Okay, updated to the Git version. What exactly should the time step method thing change? I couldn't notice any differences.

..., and just let the accumulator spread out the physics across the second.
What do you mean by that?

betajaen

09-09-2009 16:01:18

No differences? Then my idea didn't work.

There isn't anything else you can do with it. If the FPS drops below 60 then it's going to be out, hence the "lag". If the FPS is over 60, then it ignores the additional frames. - As it should be.

It's been the same code since Bleeding, which Luis worked on it for his ThunderWheels game. It's been perfectly fine so far, and I don't understand why your having some problems with it.

AnTeevY

09-09-2009 17:54:27

I've no problems with that as the game would run with ~250FPS on my (not very good) PC. But those with old PCs may have slow physics if their FPS drop below 60. But if that's not to fix, I'm okay with it. But wouldn't there be problems with games that have higher graphics requirements?