Performance re: Ribbon Trail -> Physics Step

cradle

19-04-2007 13:35:23

Hello all, a small query regarding ribbon trails, time steps, and bad performance.

Usually, if you have a ribbon trail, you attach it to a node, and call the node's updatePosition once per frame and that updates the ribbon trail. However, if your display is decoupled from the time between frames, and is instead coupled to the physics engine, you need the trail to be updated each physics step (using the step size) instead of each frame update (using time between frames) as using the frame time results in trails with incorrect lengths. I solved this problem with the following: (pseudo-code-ified)

postStep():
trail._timeUpdate(stepSize)
node.setPosition(body.getPosition())
trail.nodeUpdated(node)


So, my problem? This is giving me a massive performance hit! Using just eyeballing, having more than 30 or so ribbon trails reduces the framerate to below 1 fps, and using profiling I can identify that (during ribbon trail intensive scenes) the postStep method is second only to 'go()' in terms of time spent in the method.

This can be contrasted to the following:
frameEnded():
node.setPosition(body.getPosition())


Which when used results in playable framerates with over 70 ribbon trails, and the frameEnded method not showing up in the top 30 methods in profiling (albeit with the trails being completely the wrong length).

Is there a simple solution to this? Have I missed some ribbon-trail magic that would do this for me faster? Any ideas on how to make it faster?

- Glenn

bharling

19-04-2007 17:50:15

I dunno a great deal about this (am just starting the physics thing myself), but shouldn't your ogre node be already attached to the physics body? I dont think you have to update the node position every frame, I thought the physics took care of that for you, and consequently anything attached to the node should update too, without intervention. This is with Newton however, maybe your using something else

body.attachToNode( node )

Note: I'm probably 100% wrong about this, sorry couldn't be more help.

cradle

20-04-2007 01:54:48

I think that would work if I was using an Ogre-ised physics library that understood the notion of Nodes (OgreNewt or OgreOde). I am, however, using PyOde (to keep a cleaner MVC-esque design) which has no understanding of the rendering engine, and instead I have the controller (Python Object) setting the views position (Ogre Node/Entity) based on data from the model (Ode Body).

I've been very tempted multiple times to switch to OgreOde; but am a huge fan of the fact that my dedicated server has only PyOde, and not OgreOde (and therefor Ogre) as a pre-requisite. I've even thought so-far as to contemplate making equivalent OgreOde and PyOde implementations, but have concluded that there is too much margin for error inherent in that.

I'm not even completely sure as to why it runs so slow; is it simply the overhead of calling that many methods in Python so many times? Or are the actual methods slow (which seems odd, as you would assume they would have to be called internally for even the automatic updating mechanism).

- Glenn

andy

21-04-2007 07:22:25

I'm guessing that if you comment out
trail.nodeUpdated(node)
then your performance would be good again ?? (and it might even work as you expect)..

A challenge could be if your physics stepping is much faster than your framerate you are needlessly calling an update on the nodes (which does quite a lot of work in updateTrail..)

I'm guessing that you really only need the trail to be updated each frame refresh and that this is done automatically for you anyway..

Just a thought
Cheers
Andy

Biggles

24-04-2007 17:22:40

if the trails are simply graphical flourishes you could maybe update them less often than the rest of the physics? Either in a frameListener as you had before, or maybe once every x number of physics steps. If you then stagger them, so that the same number of trails are updated each time, it could work rather nicely. Ie, trails [0..(n/x)-1] on the first step, then [(n/x)..(2n/x)-1] on the next, right up to ... [((x-1)n/x)...n-1] before starting again from the beginning on the n+1'th step...

cradle

04-05-2007 15:44:33

Unfortunately commenting out
trail.nodeUpdated(node)
resulted in the trails being horrible the wrong length again. In fact, they have extremely interesting behaviour, in that they render correctly for a short distance from the lead node, and then just leave a long straight line that seams to ignore updates for about 10 times the length the trail is meant to be (maximum!).

So, I've comprimised and implemented this solution. Count the number of steps since the last render. Set the time to be stepTime * numSteps. Update the trail. Update the nodes. Reset the numSteps.

It works really well - most of the time. When the game lags for, say, more than 10 physics steps, the trail still renders too long a length, but fixes itself very very quickly (and I presume that calling nodeUpdated is still affecting my framerates, but it fixes my length-of-trail bug).

I'm very interested in your solution Biggles, but I unfortunately don't understand it :S

I'd post more, and ask more questions, but I've decided to post a public Alpha of my game, and for that I'll create another thread! Scary times... :S