void ServerWrite(VRage.Library.Collections.BitStream stream, ulong clientId) { ClientData clientData = m_serverClientData[clientId]; m_clientUpdateFlag[clientId] = false; stream.WriteUInt32(clientData.TimeStamp); MyTransformD serverData = new MyTransformD(Entity.WorldMatrix); //rotation is calculated same way for both Quaternion serverRotation = serverData.Rotation; serverRotation.Normalize(); clientData.Transform.Rotation.Normalize(); MyTimeStampValues delta = new MyTimeStampValues(); serverRotation = Quaternion.Inverse(serverRotation); Quaternion.Multiply(ref clientData.Transform.Rotation, ref serverRotation, out delta.Transform.Rotation); bool apply = false; double eps = 0.001; if (Math.Abs(Quaternion.Dot(clientData.Transform.Rotation, serverData.Rotation)) < 1 - eps) { apply = true; } bool isValidPosition = true; bool correctServerposition = false; CalculatePositionDifference(clientId, out isValidPosition, out correctServerposition, out delta.Transform.Position); bool sendUpdate = !isValidPosition; if (correctServerposition) { apply = true; } if (apply) { MatrixD matrix = Entity.WorldMatrix; MatrixD correctionMatrix = MatrixD.Multiply(matrix.GetOrientation(), delta.Transform.TransformMatrix); correctionMatrix.Translation += Entity.WorldMatrix.Translation; Entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true); MyEntityPhysicsStateGroup support = MySupportHelper.FindPhysics(Entity); if(support != null && support.MoveHandler != null) { support.MoveHandler(ref matrix, ref correctionMatrix); } } stream.Write(Entity.Physics != null ? Entity.Physics.LinearVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero); stream.Write(Entity.Physics != null ? Entity.Physics.AngularVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero); stream.WriteBool(sendUpdate); if (sendUpdate) { serverData = new MyTransformD(Entity.WorldMatrix); stream.Write(serverData.Position); stream.WriteQuaternion(serverData.Rotation); CustomServerWrite(m_serverClientData[clientId].TimeStamp, clientId, stream); } }