void ClientRead(VRage.Library.Collections.BitStream stream) { uint timeStamp = stream.ReadUInt32(); m_lastRecievedTimeStamp = timeStamp; Vector3 serverLinearVelocity = stream.ReadVector3(); Vector3 serverAngularVelocity = stream.ReadVector3(); MyTimeStampValues?clientData = m_timestamp.GetTransform(timeStamp); if (clientData.HasValue) { Vector3D linearDelta = serverLinearVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.LinearVelocity; Entity.Physics.LinearVelocity += Vector3D.Round(linearDelta, 2); Vector3D angularDelta = serverAngularVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.AngularVelocity; Entity.Physics.AngularVelocity += Vector3D.Round(angularDelta, 2); m_timestamp.UpdateDeltaVelocities(timeStamp, ref linearDelta, ref angularDelta); } bool isUpdate = stream.ReadBool(); if (isUpdate) { MyTransformD serverTransform = new MyTransformD(); serverTransform.Position = stream.ReadVector3D(); serverTransform.Rotation = stream.ReadQuaternion(); serverTransform.Rotation = Quaternion.Identity; CustomClientRead(timeStamp, ref serverTransform, stream); } }
protected override void CustomClientRead(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation, VRage.Library.Collections.BitStream stream) { bool hasSupport = stream.ReadBool(); if (hasSupport) { long entityId = stream.ReadInt64(); Vector3D serverDelta = stream.ReadVector3D(); Vector3D serverSupportPos = stream.ReadVector3D(); if (!MyEntities.EntityExists(entityId)) { return; } MyEntity support = MyEntities.GetEntityById(entityId); MyTimeStampValues?clientTransform = m_timestamp.GetTransform(timeStamp); Vector3D clientDelta = Vector3.Zero; Vector3D clientVelocity = Vector3D.Zero; Quaternion rotationComp = Quaternion.Identity; if (clientTransform != null) { if (m_supportTimeStamp == null) { return; } MyTimeStampValues?supportTransform = m_supportTimeStamp.GetTransform(timeStamp); Vector3D supportPosition = support.PositionComp.WorldMatrix.Translation; if (supportTransform.HasValue) { supportPosition = supportTransform.Value.Transform.Position; if (supportTransform.Value.EntityId != entityId) { supportPosition = serverSupportPos; return; } } clientDelta = supportPosition - clientTransform.Value.Transform.Position; clientVelocity = clientTransform.Value.LinearVelocity; rotationComp = Quaternion.Inverse(clientTransform.Value.Transform.Rotation); } else { m_character.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true); return; } MyTimeStampValues delta = new MyTimeStampValues(); Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref rotationComp, out delta.Transform.Rotation); delta.Transform.Position = clientDelta - serverDelta; delta.LinearVelocity = serverPositionAndOrientation.LinearVelocity - clientVelocity; double deltaL = delta.Transform.Position.Length(); //if difference is more than if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio)) { delta.Transform.Position = delta.Transform.Position * 0.2; delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f); } Quaternion normalized = delta.Transform.Rotation; normalized.Normalize(); delta.Transform.Rotation = normalized; normalized = serverPositionAndOrientation.Transform.Rotation; normalized.Normalize(); serverPositionAndOrientation.Transform.Rotation = normalized; Quaternion clientNormalized = clientTransform.Value.Transform.Rotation; clientNormalized.Normalize(); double eps = 0.001; if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, clientNormalized)) < 1 - eps && m_character.IsDead == false) { Quaternion currentOrientation = Quaternion.CreateFromForwardUp(m_character.WorldMatrix.Forward, m_character.WorldMatrix.Up); Quaternion.Multiply(ref delta.Transform.Rotation, ref currentOrientation, out currentOrientation); MatrixD matrix = MatrixD.CreateFromQuaternion(currentOrientation); MatrixD currentMatrix = m_character.PositionComp.WorldMatrix; currentMatrix.Translation = Vector3D.Zero; if (currentMatrix.EqualsFast(ref matrix) == false) { if (m_character.Physics.CharacterProxy != null) { m_character.Physics.CharacterProxy.Forward = matrix.Forward; m_character.Physics.CharacterProxy.Up = matrix.Up; } } } if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio)) { m_character.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position); m_character.Physics.LinearVelocity = serverPositionAndOrientation.LinearVelocity; m_timestamp.OverwriteServerPosition(timeStamp, ref serverPositionAndOrientation); return; } else if (deltaL > 5.0f * MyTimestampHelper.POSITION_TOLERANCE) { m_character.CacheMoveDelta(ref delta.Transform.Position); } m_character.Physics.LinearVelocity += delta.LinearVelocity; m_timestamp.UpdateDeltaPosition(timeStamp, ref delta); } else { base.CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream); } }
protected override void CustomClientRead(uint timeStamp, ref MyTransformD serverPositionAndOrientation, VRage.Library.Collections.BitStream stream) { bool hasSupport = stream.ReadBool(); if (hasSupport) { long entityId = stream.ReadInt64(); Vector3D serverSupportPos = stream.ReadVector3D(); if (!MyEntities.EntityExists(entityId)) { return; } MyEntity support = MyEntities.GetEntityById(entityId); MyTimeStampValues?clientTransform = m_timestamp.GetTransform(timeStamp); Vector3D clientPosition = Vector3D.Zero; Vector3D clientSupportPosition = Vector3D.Zero; Quaternion rotationComp = Quaternion.Identity; if (clientTransform != null) { if (m_supportTimeStamp == null) { return; } MyTimeStampValues?supportTransform = m_supportTimeStamp.GetTransform(timeStamp); Vector3D supportPosition = support.PositionComp.WorldMatrix.Translation; if (supportTransform.HasValue) { supportPosition = supportTransform.Value.Transform.Position; if (supportTransform.Value.EntityId != entityId) { return; } } clientPosition = clientTransform.Value.Transform.Position; clientSupportPosition = supportPosition; rotationComp = Quaternion.Inverse(clientTransform.Value.Transform.Rotation); } else { m_character.PositionComp.SetWorldMatrix(serverPositionAndOrientation.TransformMatrix, null, true); return; } MyTransformD delta = new MyTransformD(); delta.Rotation = Quaternion.Identity; Vector3D characterDelta = serverPositionAndOrientation.Position - clientPosition; Vector3D supportDelta = serverSupportPos - clientSupportPosition; delta.Position = characterDelta - supportDelta; m_character.CacheMoveDelta(ref delta.Position); m_timestamp.UpdateDeltaPosition(timeStamp, ref delta); } else { base.CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream); } }