Advertisement

smoothing out mesh movment

Started by March 20, 2006 05:16 PM
4 comments, last by hplus0603 18 years, 11 months ago
I am creating a client/server 3D app, using a udp connection to send cord's that all works fine but whats happening is when you see another client there movment is just a touch jumpy, and I cant seem to figure out the right direction to handle this, It seems like I have all the info needed to handle it just not sure how, my idea was to take the velocity and direction and try to anticipate where the other client will end up. does anyone have any ideas or have had a problem like this before? thanks
Moved to multiplayer and network programming

Just a guess...

What frequency/interval does your network data appear at? If it's not the same as the rendering frame rate then you might want to look into some simple extrapolation of movement (note: not interpolation!) If you store the last 3-4 known positions you should be able to extrapolate with some degree of accuracy where the object will be for the next message. Any frames that you render after the last message but before the next one should move along this guesstimated line. Depending on the latency it could look much worse, but if you're describing it as "a touch jumpy" then it shouldn't hurt.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Advertisement
i couldnt read this post without questioning something from "jollyjeffers" reply.

in multiplayer games, i should refresh the network data by the interval of the rendering? if u render 60 fps i should send and recieve 60 times as well? i didnt go into networking much, thats new to me. it sounds logical now.

i guess thats the same as online games, right?
Typically the network update is much lower frequency than the rendering update, meaning that extrapolation of velocities must be done on the clients.

Winterdyne Solutions Ltd is recruiting - this thread for details!
This is what Im atemting to do but having a problem figureing out the right way to do it my velocity is stored in a vector3 so I was using Vector3.LengthSq()
so each packet contains
1. the clients camera point
2. the clients lookat
3. the Vector3.LenghtSq()

im sure I hve all the info I need to caculate this right just not sure how to do it
For EVERY ENTITY in your simulation, you probably want to store the last known position and velocity, and the last calculated target position and velocity. This includes player, opponent, camera, etc. The cool thing about that is that you can just decide to evaluate the scene at "time X" and out comes the position/orientation of each object.

So, each object reference has the following data:
class InterpolatedEntity {  float timeOfTarget;  Vector3 targetPosition;  Vector3 velocity;  Quaternion targetOrientation;  Quaternion angularVelocity;};

When you render, you do something like:
void InterpolatedEntity::renderSceneAtTime( float now ) {  #define INTERPOLATION_LAG 50 // tune as necessary  float renderAtTime = now - INTERPOLATION_LAG;  Vector3 renderPos = targetPosition + velocity * (renderAtTime - timeOfTarget);  Quaternion renderOri = targetOrientation + angularVelocity * (renderAtTime - timeOfTarget);  renderMeshAtPosOri( myMesh, renderPos, renderOri );}

This assumes certain implementations of "+" and "*" for the quaternion class, of course; it would work almost as well with another representation, such as Euler angles or a simple "heading" orientation.

When you receive a new update for an object, you run code similar to:
void InterpolatedEntity::receiveUpdate( Update const & update ) {  float oldTime = timeOfTarget;  #define LATENCY_COMP 100 // tune as necessary  timeOfTarget = update.forTime + LATENCY_COMP;  Vector3 oldPosition = targetPosition;  targetPosition = update.position + update.velocity * LATENCY_COMP;  velocity = (targetPosition - oldPosition) / (timeOfTarget - oldTime);  Quaternion oldOrientation = targetOrientation;  targetOrientation = update.orientation + update.angularVelocity * LATENCY_COMP;  angularVelocity = (targetOrientation - oldOrientation) / (timeOfTarget - oldTime);}

Again, watch out for quaternion operations -- it talks about actual rotations, not the xyzw values themselves (so multiplying by 0 would give the identity rotation).
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement