Bonjour,
Dans l’algorithme qui suit (en C#) je calcule une spline cubique afin de déterminer la position d'un objet au cours du temps en fonction de 4 vecteurs. Ces vecteurs sont calculés sur un serveur qui envoi le résultat au client.
Tout fonctionne a merveille sauf quand l'objet se déplace sur une ligne. Dans ce cas là le serveur n'envoi plus les nouvelles positions puisse que le chemin est une droite a vitesse constante. Mais du coup l'objet ralentit.
Code PHP:
// List of vectors used to calculate curve
private List<Vector3> m_Positions = new List<Vector3>() { Vector3.zero, Vector3.zero, Vector3.zero };
public List<Vector3> Positions
{
get
{
return m_Positions;
}
set
{
m_Positions = value;
}
}
// Times when a new vector is received. Each one is the time for the above corresponding vector.
private List<float> m_LocalTime = new List<float>() { 0.0f, 0.0f, 0.0f, 0.0f };
public List<float> LocalTime
{
get
{
return m_LocalTime;
}
set
{
m_LocalTime = value;
}
}
// Curve constants
float[,] P = new float[3,4]{
{ 0.0f, 0.0f, 0.0f, 0.0f }, // X
{ 0.0f, 0.0f, 0.0f, 0.0f }, // Y
{ 0.0f, 0.0f, 0.0f, 0.0f } // Z
};
// Calculating new curve constants every times a new position is recieved
public void SetPolynomial(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3)
{
for (int i = 0; i < 3; i++)
{
P[i, 0] = v3[i] - 3.0f * v2[i] + 3.0f * v1[i] - v0[i]; // a
P[i, 1] = 3.0f * v2[i] - 6.0f * v1[i] + 3.0f * v0[i]; // b
P[i, 2] = 3.0f * v1[i] - 3.0f * v0[i]; // c
P[i, 3] = v0[i]; // d
}
}
// get one position's float (x, y or z)
private float GetPosition(float time, int axis)
{
return
P[axis, 0] * Mathf.Pow(time, 3)
+ P[axis, 1] * Mathf.Pow(time, 2)
+ P[axis, 2] * time
+ P[axis, 3];
}
// get position vector
public Vector3 GetPosition(float delaTime)
{
Vector3 position = new Vector3();
position.x = GetPosition(delaTime, 0);
position.y = GetPosition(delaTime, 1);
position.z = GetPosition(delaTime, 2);
return position;
}
// get position vector with time set to current delta time from first vector
public Vector3 GetPosition()
{
float delaTime = Time.time - LocalTime[0];
return GetPosition(delaTime);
}
// add a new position and recalculate the spline
public void Add(Vector3 position)
{
float
time = Time.time,
deltaTime = time - LocalTime[1];
SetPolynomial(Positions[0], Positions[1], Positions[2], position);
Positions.RemoveAt(0);
Positions.Add(position);
LocalTime.RemoveAt(0);
LocalTime.Add(time);
return;
}
// Apply position in Update
transform.localPosition = Path.GetPosition();
Code PHP:
// Server update. Only send updates when velocity changes
public void FixedUpdate()
{
if (uLink.Network.isServer)
{
LastUpdate++;
if (LastUpdate >= Path.UpdateRate) // don't send all the time, save bandwidth
{
// Only send required data
bool
accelerate = rigidbody.velocity != CurrentSpeed,
rotate = rigidbody.angularVelocity != AngularVelocity;
if (accelerate && rotate)
NetworkView.RPC("ServerSendPhysics", uLink.RPCMode.Others, transform.localPosition, transform.localRotation);
else if (accelerate)
NetworkView.RPC("ServerSendPosition", uLink.RPCMode.Others, transform.localPosition);
else if (rotate)
{
if (Pawn.Controller.PlayerInput.MouseDelta != Vector2.zero)
NetworkView.RPC("ServerSendRotation", uLink.RPCMode.Others, transform.localRotation);
else NetworkView.RPC("ServerStopRotation", uLink.RPCMode.Others, transform.localRotation);
}
LastUpdate = 0;
CurrentSpeed = rigidbody.velocity;
AngularVelocity = rigidbody.angularVelocity;
}
}
-----