how to use SmoothMovers?

it just happend that i am in need of some smoothing :slight_smile:
i want to smooth and predict the positoins of my mmorpg players and i think it’s possible using the smoothmover stuff.
unfortunately the manual and the API docs didnt really helped me getting those things to work.

can anyone who knows about it write a small example which demonstrates how those smoothmover things have to be set up?
thx in advance

thomas e

anyone? i’m still stuck with it and all i managed was setting the prediction and smooth-modes. but how to actually smooth a nodes movement?? please help=)

In general, the SmoothMover stores a collection of position reports, each of which is associated with a particular time, given in seconds. Ideally, the position reports should be received for a time in the future, which can be achieved artificially by smoothMover.setDelay(), which effectively delays the apparent position of the remote client on the local client. If this is intolerable, then smoothMover.setPredictionMode() can be used to enable prediction, which works about as well as prediction ever does. :slight_smile:

As you receive each position report from a remote client, call smoothMover.setPos() and/or setHpr() to set the new position, or use the individual setX/setY/setZ etc. If you do not set one of the components, it remains the same as last time. You should also call setTimestamp(). When you have set all of the components for a position report that you intend to modify, call smoothMover.markPosition(), and then you can set the components for the next position report.

The SmoothMover can then interpolate a position between known position reports, according to the current time. To do this, each frame you should call smoothMover.computeSmoothPosition(), which computes the current position based on the current time (as reported by globalClock.getFrameTime(), unless you specify a particular time as a parameter to computeSmoothPosition()). Then you can call getSmoothPos() and/or getSmoothHpr() to get the computed position.

The nuts and bolts of actually synchronizing two or more clients to use a similar timestamp, and of communicating position reports between two or more clients at regular intervals, is left up to you. (Though the DistributedSmoothNode class does contain code to do this, but it requires using the larger ServerRepository/ClientRepository system, which may be a much bigger bite than you were interested in taking at this moment.)

David

thx a lot drwr … but i still have no clue how to really smooth a node’s movement. i tried a lot of things like
nodepath.SmoothMover.setPos()
nodepath.applySmoothPos()
SmoothMover.nodepath.etcetcetc…
…
and whatever not… i imported the smoothmover stuff but all i managed to do was:
SmoothMover.setPredictionMode(True)
SmoothMover.setSmoothMode(True)
and the rest… no clue how to use it.
at the moment i’m just repositioning my actors with the data comming from the server but it looks really ugly and i really wanna change it^^.
could you provide a minimal script which is able to smooth a position?

I’m a little swamped at the moment, but if you give me a few days I can try to throw something together. In the meantime, you may be missing a fundamental point: you need to create an instance of the SmoothMover class for each object whose position you want to smooth. In my code above, smoothMover.setPos() refers to a method on that instance, e.g.:

self.smoothMover = SmoothMover()
self.smoothMover.setPos(x, y, z)
self.smoothMover.setHpr(h, p, r)
self.smoothMover.setTimestamp(t)
self.smoothMover.markPosition()

David

hm… well i really missed this one. so this smoothmover stuff is more or less a completely node-path unrelated thing… like… a storage point for your position/rotation values where they get smoothed and predicted?
simmilar to
xyz = node.getPos()
and node.setPos(xyz)
with the only difference that it’s smoothed based on the current time?

Right. A SmoothMover is just a place to store a list of position reports, with an ability to compute a “current position” that moves smoothly between position reports according to the current time.

The idea is that you create a SmoothMover for each node that moves under remote control. Each time you get a position report from the remote client, you add it to the appropriate SmoothMover. To actually move the nodes, you must have a task running that updates each node with the current position as reported by its SmoothMover.

You can see some examples of this being done in the DistributedSmoothNode class. Even if you don’t use the infrastructure that DistributedSmoothNode requires (so you can’t use the class directly), you should be able to get an idea of what it is doing by looking at the code.

David

well i dont think i’ll use the distributed node thing.
knowing what exactly those smoothmovers are is already very helpfull. for now it should be enought to make them work in my case =).
guess i’ll write a basic tutorial on this since it’s very useful for network applications.
nother nice thing is that it uses tasks :slight_smile:. i do have a lot of playeres and it really would be painfull if they where all predicted even if they where just idling around ^^

well once more, thanks for your help :slight_smile:

well … i sort of managed to set up a smoothmover and i managed to get a few smoothed values from time to time… but i’ve some trouble with the timestamp thing. what sort of times does it want? the “ultimative pc time”, the time since application start? the time since the last position update? and the phonytimestamp… well always sets my values to the latest setPos i did (doesnt look like setDelay seems to have any effect)
any hints?

It wants values in the same range returned by globalClock.getFrameTime(), which is defined as seconds elapsed since some undefined epoch. (In practice, the “undefined epoch” is usually the start of the application, but you shouldn’t assume this will universally be true.)

So you will have to have some mechanism to synchronize clocks between clients, which is to say, you will have to exchange a timestamp between clients at startup, so that each client knows how much he should add to his clock time to get the same clock time on the other clients.

David

ok =) this time i made them work! ( thx god my application is not timing critical so i can use setPhonyTimestamp )

thx for all your help!

when i finished adding them i’ll write a section in the manual.