Client Side Prediction for a Look Vector

So I am making a first person networked shooter. I am working on client-side prediction where I am predicting player position and look vectors client-side based on input messages received from the server. Right now I am only worried about the look vectors though. I am receiving the correct look vector from the server about 20 times per second and I am checking that against the look vector that I have client side. I want to interpolate the clients look vector towards the correct one that is server side over a period of time. Therefore no matter how far you are away from the servers look vector you will interpolate to it over the same amount of time. Ex. if you were 10 degrees off it would take the same amount of time as if you were 2 degrees off to be correctly lined up with the server copy. My code looks something like this but the problem is that the amount that you are changing the clients copy gets infinitesimally small so you will actually never reach the servers copy. This is because I am always calculating the difference and only moving by a percentage of that every frame. Does anyone have any suggestions on how to interpolate towards the servers copy correctly?

if(rotationDiffY > ClientSideAttributes::minRotation)
{

if(serverRotY > clientRotY)
{
playerObjects[i]->collisionObject->rotation.y += (rotationDiffY * deltaTime);
}
else
{
playerObjects[i]->collisionObject->rotation.y -= (rotationDiffY deltaTime);
}

}

• Well, why you just don't set some threshold (absolute or percentage) after which you just set client to same value as server? – Petr Abdulin Oct 24 '12 at 4:19
• Because the rendering is using the clients look vector for rendering the first person. If you are snapping to the servers value after you are said percentage away then it looks really bad. The camera is snapping all over the place making it look really choppy. – Mike Sawayda Oct 24 '12 at 14:13

You could try using a lerp (linear interpolation) function using the current client rotation and the last rotation received from the server. Because you always want to use the same time period to update the rotation you could reset a variable each time the server receives a message and increment it by delta time each frame. For example, if you want the rotation to be corrected over 0.5 seconds, each time you receive a message from the server reset the timer to 0.0 and increment it up to 0.5.

template<typename T>
T lerp(T a, T b, T t)
{
return a + (b-a) * t;
}

// Trim the t value to between 0.0 and 1.0
float t = timeSinceServerMessage / ROTATION_CORRECTION_TIME;

// Interpolate between the current rotation and the server rotation based on t
float newRotation = lerp<float>(currentClientRotation, serverRotation, t);


More information available here - Wikipedia: Linear Interpolation