コード例 #1
0
 protected virtual void CustomClientRead(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation, VRage.Library.Collections.BitStream stream)
 {
     if (m_timestamp != null)
     {
         m_timestamp.ServerResponse(timeStamp, ref serverPositionAndOrientation);
     }
 }
コード例 #2
0
        public void Update(uint timeStamp)
        {
            if (m_timeStampData == null)
            {
                m_timeStampData = new SortedDictionary<uint, MyTimeStampValues>();
            }

            if(m_entity == null|| m_entity.Physics == null)
            {
                m_timeStampData.Remove(timeStamp);
                return;
            }
    
            var matrix = m_entity.WorldMatrix;

            m_timeStampData[timeStamp] = new MyTimeStampValues()
            {
                EntityId = m_entity.EntityId,
                Transform = new MyTransformD(matrix),
                LinearVelocity = m_entity.Physics.LinearVelocity,
                AngularVelocity = m_entity.Physics.AngularVelocity,
            };

            if (m_timeStampData.Count >= MAX_POSHISTORY)
            {
                m_timeStampData.Remove(m_timeStampData.First().Key);
            }

            m_currentTimestamp = timeStamp;
        }
コード例 #3
0
        public void Update(uint timeStamp)
        {
            if (m_entity == null || m_entity.Physics == null)
            {
                m_timeStampData.Remove(timeStamp);
                return;
            }

            var matrix = m_entity.WorldMatrix;

            m_timeStampData[timeStamp] = new MyTimeStampValues()
            {
                EntityId        = m_entity.EntityId,
                Transform       = new MyTransformD(matrix),
                LinearVelocity  = m_entity.Physics.LinearVelocity,
                AngularVelocity = m_entity.Physics.AngularVelocity,
            };

            if (m_timeStampData.Count >= MAX_POSHISTORY)
            {
                m_timeStampData.Remove(m_timeStampData.First().Key);
            }

            m_currentTimestamp = timeStamp;
        }
コード例 #4
0
        public void ServerResponse(uint timeStamp, ref MyTransformD serverPositionAndOrientation)
        {
            if (timeStamp < m_lastTSFromServer)
            {
                return;
            }

            if (m_timeStampData.ContainsKey(timeStamp) == false)
            {
                m_entity.PositionComp.SetWorldMatrix(serverPositionAndOrientation.TransformMatrix, null, true);
                return;
            }

            MyTimeStampValues cachedData = m_timeStampData[timeStamp];

            var          mat   = m_entity.WorldMatrix;
            MyTransformD delta = UpdateValues(m_entity, ref serverPositionAndOrientation, ref cachedData);

            mat.Translation = serverPositionAndOrientation.Position;
            m_entity.PositionComp.SetWorldMatrix(mat, null, true);

            UpdateDeltaPosition(timeStamp, ref delta);

            m_lastTSFromServer = timeStamp;
        }
コード例 #5
0
        public void OverwriteServerPosition(uint timestamp, ref MyTimeStampValues data)
        {
            if (m_timeStampData.Count <= 0)
                return;

            for (uint i = timestamp; i <= m_currentTimestamp; ++i)
            {
                OverWriteData(i, ref data);
            }
        }
コード例 #6
0
 void UpdateData(uint i, ref Vector3 deltaLinear, ref Vector3 deltaAngular)
 {
     if (m_timeStampData.ContainsKey(i))
     {
         MyTimeStampValues cachedData = m_timeStampData[i];
         cachedData.LinearVelocity  += deltaLinear;
         cachedData.AngularVelocity += deltaAngular;
         m_timeStampData[i]          = cachedData;
     }
 }
コード例 #7
0
        void UpdateData(uint i, ref MyTransformD delta)
        {
            if (m_timeStampData.ContainsKey(i))
            {
                MyTimeStampValues cachedData = m_timeStampData[i];

                cachedData.Transform.Position += delta.Position;
                Quaternion.Multiply(ref delta.Rotation, ref cachedData.Transform.Rotation, out cachedData.Transform.Rotation);
                m_timeStampData[i] = cachedData;
            }
        }
コード例 #8
0
        void OverWriteData(uint i, ref MyTimeStampValues delta)
        {
            if (m_timeStampData.ContainsKey(i))
            {
                MyTimeStampValues cachedData = m_timeStampData[i];

                cachedData.LinearVelocity     = delta.LinearVelocity;
                cachedData.Transform.Position = delta.Transform.Position;
                m_timeStampData[i]            = cachedData;
            }
        }
コード例 #9
0
        public void UpdateDeltaPosition(uint timestamp, ref MyTimeStampValues data)
        {
            if (m_timeStampData.Count <= 0)
            {
                return;
            }

            for (uint i = timestamp; i <= m_currentTimestamp; ++i)
            {
                UpdateData(i, ref data);
            }
        }
コード例 #10
0
        public void OverwriteServerPosition(uint timestamp, ref MyTimeStampValues data)
        {
            if (m_timeStampData.Count <= 0)
            {
                return;
            }

            for (uint i = timestamp; i <= m_currentTimestamp; ++i)
            {
                OverWriteData(i, ref data);
            }
        }
コード例 #11
0
        void UpdateData(uint i, ref MyTimeStampValues delta)
        {
            if (m_timeStampData.ContainsKey(i))
            {
                MyTimeStampValues cachedData = m_timeStampData[i];

                cachedData.AngularVelocity    += delta.AngularVelocity;
                cachedData.LinearVelocity     += delta.LinearVelocity;
                cachedData.Transform.Position += delta.Transform.Position;
                cachedData.Transform.Position += delta.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                Quaternion.Multiply(ref delta.Transform.Rotation, ref cachedData.Transform.Rotation, out cachedData.Transform.Rotation);
                m_timeStampData[i] = cachedData;
            }
        }
コード例 #12
0
        void ClientRead(VRage.Library.Collections.BitStream stream)
        {
            uint timeStamp = stream.ReadUInt32();

            if (m_lastRecievedTimeStamp > timeStamp)
            {
                return;
            }
            m_lastRecievedTimeStamp = timeStamp;

            MyTimeStampValues serverPositionAndOrientation = new MyTimeStampValues();

            serverPositionAndOrientation.Transform          = new MyTransformD();
            serverPositionAndOrientation.Transform.Position = stream.ReadVector3D();
            serverPositionAndOrientation.Transform.Rotation = stream.ReadQuaternionNorm();
            serverPositionAndOrientation.LinearVelocity     = stream.ReadVector3();
            serverPositionAndOrientation.AngularVelocity    = stream.ReadVector3();

            serverPositionAndOrientation.LinearVelocity  /= MyEntityPhysicsStateGroup.EffectiveSimulationRatio;
            serverPositionAndOrientation.AngularVelocity /= MyEntityPhysicsStateGroup.EffectiveSimulationRatio;

            CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream);
        }
コード例 #13
0
        public void ServerResponse(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation)
        {
            if (timeStamp < m_lastTSFromServer)
                return;      

            if (m_timeStampData.ContainsKey(timeStamp) == false)
            {
                m_entity.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true);
                return;
            }

            MyTimeStampValues cachedData = m_timeStampData[timeStamp];
      
            MatrixD worldMatrix = m_entity.PositionComp.WorldMatrix;

            MyTimeStampValues delta = new MyTimeStampValues();

            delta.Transform.Position = serverPositionAndOrientation.Transform.Position - cachedData.Transform.Position;

            double deltaL = delta.Transform.Position.Length();

            MyCharacter character = (m_entity as MyCharacter);

            cachedData.Transform.Rotation = Quaternion.Inverse(cachedData.Transform.Rotation);
            Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref cachedData.Transform.Rotation, out delta.Transform.Rotation);
            if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity()/ (60f * Sync.RelativeSimulationRatio)))
            {
                delta.Transform.Position = delta.Transform.Position * 0.2;
               
            }
            delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f);
            Vector3D position = worldMatrix.Translation;

            position += delta.Transform.Position;

            delta.LinearVelocity = serverPositionAndOrientation.LinearVelocity -cachedData.LinearVelocity;

            delta.AngularVelocity = serverPositionAndOrientation.AngularVelocity - cachedData.AngularVelocity;

            double deltaVelocity = delta.LinearVelocity.LengthSquared();

            if (deltaVelocity > 0.1 * 0.1)
            {
                m_entity.Physics.LinearVelocity += delta.LinearVelocity;
            }

            deltaVelocity = delta.AngularVelocity.LengthSquared();

            if (deltaVelocity > 0.01 * 0.01)
            {
                m_entity.Physics.AngularVelocity += delta.AngularVelocity;
            } 

            Quaternion orientation = Quaternion.CreateFromForwardUp(worldMatrix.Forward, worldMatrix.Up);


            Quaternion normalized = cachedData.Transform.Rotation;
            normalized.Normalize();
            cachedData.Transform.Rotation = normalized;
            normalized = serverPositionAndOrientation.Transform.Rotation;
            normalized.Normalize();
            serverPositionAndOrientation.Transform.Rotation = normalized;

            double eps = 0.001;
            if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, cachedData.Transform.Rotation)) < 1 - eps)
            {
                Quaternion.Multiply(ref delta.Transform.Rotation, ref orientation, out orientation);
                MatrixD matrix = MatrixD.CreateFromQuaternion(orientation);
                MatrixD currentMatrix = m_entity.PositionComp.WorldMatrix;
                Vector3D translation = currentMatrix.Translation;
                currentMatrix.Translation = Vector3D.Zero;
                if (currentMatrix.EqualsFast(ref matrix, 0.01) == false)
                {
                    matrix.Translation = translation;
                    m_entity.PositionComp.SetWorldMatrix(matrix, null, true);
                }
            }


            if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity()/ (60f * Sync.RelativeSimulationRatio)))
            {
                m_entity.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position);
            }
            else if (deltaL > POSITION_TOLERANCE)
            {
                m_entity.PositionComp.SetPosition(position);
            }
           

            UpdateDeltaPosition(timeStamp, ref delta);

            m_lastTSFromServer = timeStamp;    
        }
コード例 #14
0
        MyTransformD UpdateValues(MyEntity entity, ref MyTransformD serverPositionAndOrientation, ref MyTimeStampValues cachedData)
        {
            MyTransformD delta = new MyTransformD();

            delta.Position = serverPositionAndOrientation.Position - cachedData.Transform.Position;

            cachedData.Transform.Rotation = Quaternion.Inverse(cachedData.Transform.Rotation);
            Quaternion.Multiply(ref serverPositionAndOrientation.Rotation, ref cachedData.Transform.Rotation, out delta.Rotation);
            delta.Rotation = Quaternion.Identity;

            MatrixD matrix = entity.WorldMatrix;

            matrix.Translation = Vector3D.Zero;
            MatrixD correctionMatrix = MatrixD.Multiply(matrix, delta.TransformMatrix);

            correctionMatrix.Translation += entity.WorldMatrix.Translation;
            entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);

            return(delta);
        }
コード例 #15
0
        public void ServerResponse(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation)
        {
            if (timeStamp < m_lastTSFromServer)
            {
                return;
            }

            if (m_timeStampData.ContainsKey(timeStamp) == false)
            {
                m_entity.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true);
                return;
            }

            MyTimeStampValues cachedData = m_timeStampData[timeStamp];

            MatrixD worldMatrix = m_entity.PositionComp.WorldMatrix;

            MyTimeStampValues delta = new MyTimeStampValues();

            delta.Transform.Position = serverPositionAndOrientation.Transform.Position - cachedData.Transform.Position;

            double deltaL = delta.Transform.Position.Length();

            MyCharacter character = (m_entity as MyCharacter);

            cachedData.Transform.Rotation = Quaternion.Inverse(cachedData.Transform.Rotation);
            Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref cachedData.Transform.Rotation, out delta.Transform.Rotation);
            if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity() / (60f * Sync.RelativeSimulationRatio)))
            {
                delta.Transform.Position = delta.Transform.Position * 0.2;
            }
            delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f);
            Vector3D position = worldMatrix.Translation;

            position += delta.Transform.Position;

            delta.LinearVelocity = serverPositionAndOrientation.LinearVelocity - cachedData.LinearVelocity;

            delta.AngularVelocity = serverPositionAndOrientation.AngularVelocity - cachedData.AngularVelocity;

            double deltaVelocity = delta.LinearVelocity.LengthSquared();

            if (deltaVelocity > 0.1 * 0.1)
            {
                m_entity.Physics.LinearVelocity += delta.LinearVelocity;
            }

            deltaVelocity = delta.AngularVelocity.LengthSquared();

            if (deltaVelocity > 0.01 * 0.01)
            {
                m_entity.Physics.AngularVelocity += delta.AngularVelocity;
            }

            Quaternion orientation = Quaternion.CreateFromForwardUp(worldMatrix.Forward, worldMatrix.Up);


            Quaternion normalized = cachedData.Transform.Rotation;

            normalized.Normalize();
            cachedData.Transform.Rotation = normalized;
            normalized = serverPositionAndOrientation.Transform.Rotation;
            normalized.Normalize();
            serverPositionAndOrientation.Transform.Rotation = normalized;

            double eps = 0.001;

            if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, cachedData.Transform.Rotation)) < 1 - eps)
            {
                Quaternion.Multiply(ref delta.Transform.Rotation, ref orientation, out orientation);
                MatrixD  matrix        = MatrixD.CreateFromQuaternion(orientation);
                MatrixD  currentMatrix = m_entity.PositionComp.WorldMatrix;
                Vector3D translation   = currentMatrix.Translation;
                currentMatrix.Translation = Vector3D.Zero;
                if (currentMatrix.EqualsFast(ref matrix, 0.01) == false)
                {
                    matrix.Translation = translation;
                    m_entity.PositionComp.SetWorldMatrix(matrix, null, true);
                }
            }


            if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity() / (60f * Sync.RelativeSimulationRatio)))
            {
                m_entity.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position);
            }
            else if (deltaL > POSITION_TOLERANCE)
            {
                if (m_entity is MyCharacter)
                {
                    (m_entity as MyCharacter).CacheMoveDelta(ref delta.Transform.Position);
                }
                else
                {
                    m_entity.PositionComp.SetPosition(position);
                }
            }


            UpdateDeltaPosition(timeStamp, ref delta);

            m_lastTSFromServer = timeStamp;
        }
        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);
            }
        }
コード例 #17
0
        void UpdateData(uint i, ref MyTimeStampValues delta)
        {
            if (m_timeStampData.ContainsKey(i))
            {
                MyTimeStampValues cachedData = m_timeStampData[i];

                cachedData.AngularVelocity += delta.AngularVelocity;
                cachedData.LinearVelocity += delta.LinearVelocity;
                cachedData.Transform.Position += delta.Transform.Position;
                cachedData.Transform.Position += delta.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                Quaternion.Multiply(ref delta.Transform.Rotation, ref cachedData.Transform.Rotation, out cachedData.Transform.Rotation);
                m_timeStampData[i] = cachedData;
            }
        }
コード例 #18
0
        MyTransformD UpdateValues(MyEntity entity, ref MyTransformD serverPositionAndOrientation, ref MyTimeStampValues cachedData)
        {

            MyTransformD delta = new MyTransformD();

            delta.Position = serverPositionAndOrientation.Position - cachedData.Transform.Position;

            cachedData.Transform.Rotation = Quaternion.Inverse(cachedData.Transform.Rotation);
            Quaternion.Multiply(ref serverPositionAndOrientation.Rotation, ref cachedData.Transform.Rotation, out delta.Rotation);
            delta.Rotation = Quaternion.Identity;

            MatrixD matrix = entity.WorldMatrix;
            matrix.Translation = Vector3D.Zero;
            MatrixD correctionMatrix = MatrixD.Multiply(matrix, delta.TransformMatrix);
            correctionMatrix.Translation += entity.WorldMatrix.Translation;
            entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);

            return delta;
        }
コード例 #19
0
        void ServerWrite(VRage.Library.Collections.BitStream stream, ulong clientId)
        {
            bool clientUpdate = m_clientUpdateFlag[clientId];
            stream.WriteBool(clientUpdate);
            if (clientUpdate)
            {
                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 applyRotation = false;
                double eps = 0.001;
                if (Math.Abs(Quaternion.Dot(clientData.Transform.Rotation, serverData.Rotation)) < 1 - eps)
                {
                    applyRotation = true;
                }

                bool isValidPosition = true;
                bool correctServerPosition = false;

                CalculatePositionDifference(clientId, out isValidPosition, out correctServerPosition, out delta.Transform.Position);

                bool isValidClientPosition = isValidPosition;

                if ((correctServerPosition && isValidPosition) || applyRotation)
                {
                    MatrixD matrix = Entity.WorldMatrix;
                    MatrixD correctionMatrix = MatrixD.Multiply(matrix.GetOrientation(), delta.Transform.TransformMatrix);
                    correctionMatrix.Translation += Entity.WorldMatrix.Translation;

                    if (correctServerPosition)
                    {
                        isValidClientPosition = IsPositionValid(new MyTransformD(correctionMatrix));
                    }

                    if (isValidClientPosition)
                    {
                        Entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);
                        MyEntityPhysicsStateGroup support = MySupportHelper.FindPhysics(Entity);
                        if (support != null && support.MoveHandler != null)
                        {
                            support.MoveHandler(ref matrix, ref correctionMatrix);
                        }
                    }
                    else if (applyRotation)
                    {
                        correctionMatrix.Translation = Entity.WorldMatrix.Translation;
                        Entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);
                    }

                }

                stream.WriteBool(!isValidClientPosition);

                if (!isValidClientPosition)
                {
                    serverData = new MyTransformD(Entity.WorldMatrix);
                    stream.Write(serverData.Position);

                    CustomServerWrite(m_serverClientData[clientId].TimeStamp, clientId, stream);
                }
            }

            stream.Write(Entity.Physics != null ? Entity.Physics.LinearVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero);
            stream.Write(Entity.Physics != null ? Entity.Physics.AngularVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero);           
        }
コード例 #20
0
        public void UpdateDeltaPosition(uint timestamp, ref MyTimeStampValues data)
        {
            if (m_timeStampData.Count <= 0)
                return;

            for (uint i = timestamp; i <= m_currentTimestamp; ++i)
            {
                UpdateData(i, ref data);
            }
        }
        void ServerWrite(VRage.Library.Collections.BitStream stream, ulong clientId)
        {
            bool clientUpdate = m_clientUpdateFlag[clientId];

            stream.WriteBool(clientUpdate);
            if (clientUpdate)
            {
                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   applyRotation = false;
                double eps           = 0.001;
                if (Math.Abs(Quaternion.Dot(clientData.Transform.Rotation, serverData.Rotation)) < 1 - eps)
                {
                    applyRotation = true;
                }

                bool isValidPosition       = true;
                bool correctServerPosition = false;

                CalculatePositionDifference(clientId, out isValidPosition, out correctServerPosition, out delta.Transform.Position);

                bool isValidClientPosition = isValidPosition;

                if ((correctServerPosition && isValidPosition) || applyRotation)
                {
                    MatrixD matrix           = Entity.WorldMatrix;
                    MatrixD correctionMatrix = MatrixD.Multiply(matrix.GetOrientation(), delta.Transform.TransformMatrix);
                    correctionMatrix.Translation += Entity.WorldMatrix.Translation;

                    if (correctServerPosition)
                    {
                        isValidClientPosition = IsPositionValid(new MyTransformD(correctionMatrix));
                    }

                    if (isValidClientPosition)
                    {
                        Entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);
                        MyEntityPhysicsStateGroup support = MySupportHelper.FindPhysics(Entity);
                        if (support != null && support.MoveHandler != null)
                        {
                            support.MoveHandler(ref matrix, ref correctionMatrix);
                        }
                    }
                    else if (applyRotation)
                    {
                        correctionMatrix.Translation = Entity.WorldMatrix.Translation;
                        Entity.PositionComp.SetWorldMatrix(correctionMatrix, null, true);
                    }
                }

                stream.WriteBool(!isValidClientPosition);

                if (!isValidClientPosition)
                {
                    serverData = new MyTransformD(Entity.WorldMatrix);
                    stream.Write(serverData.Position);

                    CustomServerWrite(m_serverClientData[clientId].TimeStamp, clientId, stream);
                }
            }

            stream.Write(Entity.Physics != null ? Entity.Physics.LinearVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero);
            stream.Write(Entity.Physics != null ? Entity.Physics.AngularVelocity * MyEntityPhysicsStateGroup.EffectiveSimulationRatio : Vector3.Zero);
        }
 protected virtual void CustomClientRead(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation, VRage.Library.Collections.BitStream stream)
 {
     if (m_timestamp != null)
     {
         m_timestamp.ServerResponse(timeStamp, ref serverPositionAndOrientation);
     }
 }
        void ClientRead(VRage.Library.Collections.BitStream stream)
        {    
            uint timeStamp = stream.ReadUInt32();
            if(m_lastRecievedTimeStamp > timeStamp)
            {
                return;
            }
            m_lastRecievedTimeStamp = timeStamp;

            MyTimeStampValues serverPositionAndOrientation = new MyTimeStampValues();
            serverPositionAndOrientation.Transform = new MyTransformD();
            serverPositionAndOrientation.Transform.Position = stream.ReadVector3D();
            serverPositionAndOrientation.Transform.Rotation = stream.ReadQuaternionNorm();
            serverPositionAndOrientation.LinearVelocity = stream.ReadVector3();
            serverPositionAndOrientation.AngularVelocity = stream.ReadVector3();

            serverPositionAndOrientation.LinearVelocity /= MyEntityPhysicsStateGroup.EffectiveSimulationRatio;
            serverPositionAndOrientation.AngularVelocity /= MyEntityPhysicsStateGroup.EffectiveSimulationRatio;
           
            CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream);
        }
コード例 #24
0
        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;
                bool hasJetpack = m_character.JetpackComp != null;
                if (hasJetpack && m_character.JetpackComp.TurnedOn && m_character.IsDead == false)
                {
                    if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, clientNormalized)) < 1 - eps )
                    {
                        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);
            }
        }
コード例 #25
0
        void OverWriteData(uint i, ref MyTimeStampValues delta)
        {
            if (m_timeStampData.ContainsKey(i))
            {
                MyTimeStampValues cachedData = m_timeStampData[i];

                cachedData.LinearVelocity = delta.LinearVelocity;
                cachedData.Transform.Position = delta.Transform.Position;
                m_timeStampData[i] = cachedData;
            }
        }