private static PositionUpdateMsg CreatePositionMsg(MyEntity entity)
        {
            var m = entity.WorldMatrix;
            PositionUpdateMsg msg = new PositionUpdateMsg();

            msg.EntityId    = entity.EntityId;
            msg.Orientation = new HalfVector4(Quaternion.CreateFromForwardUp(m.Forward, m.Up).ToVector4());
            msg.Position    = m.Translation;
            if (entity.Physics != null)
            {
                if (MyPerGameSettings.EnableMultiplayerVelocityCompensation)
                {
                    float ratio = MathHelper.Clamp(Sandbox.Engine.Physics.MyPhysics.SimulationRatio, 0, 2);

                    msg.LinearVelocity  = entity.Physics.LinearVelocity * ratio;
                    msg.AngularVelocity = entity.Physics.AngularVelocity * ratio;
                }
                else
                {
                    msg.LinearVelocity  = entity.Physics.LinearVelocity;
                    msg.AngularVelocity = entity.Physics.AngularVelocity;
                }
            }
            return(msg);
        }
示例#2
0
        internal virtual void OnPositionUpdate(ref PositionUpdateMsg msg, MyNetworkClient sender)
        {
            // Validate that client sending position update to server is reponsible for update
            if (Sync.IsServer && !ResponsibleForUpdate(sender))
            {
                return;
            }

            if (!Sync.IsServer && ResponsibleForUpdate(Sync.Clients.LocalClient))
            {
                return;
            }

            var q = msg.Orientation;
            var m = Matrix.CreateFromQuaternion(q);

            var world = MatrixD.CreateWorld(msg.Position, m.Forward, m.Up);

            Debug.Assert(Entity.PositionComp != null, "Entity doesn't not have position component");
            if (Entity.PositionComp != null)
            {
                Entity.PositionComp.SetWorldMatrix(world, this);
            }

            if (Entity.Physics != null)
            {
                Entity.Physics.LinearVelocity  = msg.LinearVelocity;
                Entity.Physics.AngularVelocity = msg.AngularVelocity;

                if (MyPerGameSettings.EnableMultiplayerVelocityCompensation)
                {
                    float ratio = MathHelper.Clamp(Sandbox.Engine.Physics.MyPhysics.SimulationRatio, 0.1f, 2);

                    Entity.Physics.LinearVelocity  /= ratio;
                    Entity.Physics.AngularVelocity /= ratio;
                }

                Entity.Physics.UpdateAccelerations();

                if (!Entity.Physics.IsMoving && Entity.Physics.RigidBody != null && Entity.Physics.RigidBody.IsAddedToWorld)
                {
                    Entity.Physics.RigidBody.Deactivate();
                }
            }

            if (Sync.IsServer)
            {
                MarkPhysicsDirty();
            }
            else
            {
                // Store last update from server
                m_isLocallyDirty        = false;
                m_lastUpdateFrame       = MyMultiplayer.Static.FrameCounter;
                m_lastServerPosition    = msg.Position;
                m_lastServerOrientation = msg.Orientation;
            }
        }
        internal virtual void OnPositionUpdate(ref PositionUpdateMsg msg, MyNetworkClient sender)
        {
            Debug.Assert(false == false, "When interpolation enabled, this should not be called");
            if (!ResponsibleForUpdate(sender))
            {
                // This happens when server just accepted state change (e.g. enter cockpit), but some messages about character position will come eventually from client
                return;
            }

            ResetUpdateTimer();

            var q = Quaternion.FromVector4(msg.Orientation.ToVector4());
            var m = Matrix.CreateFromQuaternion(q);

            m_interpolator.TargetMatrix  = MatrixD.CreateWorld(msg.Position, m.Forward, m.Up);
            m_interpolator.CurrentMatrix = Entity.WorldMatrix;
            m_interpolator.Time          = 0;

            MyMultiplayer.Static.RegisterForTick(this);

            Debug.Assert(Entity.PositionComp != null, "Entity doesn't not have position component");
            if (Entity.PositionComp != null)
            {
                Entity.PositionComp.SetWorldMatrix(m_interpolator.TargetMatrix, this);
            }

            if (Entity.Physics != null)
            {
                Entity.Physics.LinearVelocity  = msg.LinearVelocity;
                Entity.Physics.AngularVelocity = msg.AngularVelocity;

                if (MyPerGameSettings.EnableMultiplayerVelocityCompensation)
                {
                    float ratio = MathHelper.Clamp(Sandbox.Engine.Physics.MyPhysics.SimulationRatio, 0.1f, 2);

                    Entity.Physics.LinearVelocity  /= ratio;
                    Entity.Physics.AngularVelocity /= ratio;
                }

                Entity.Physics.UpdateAccelerations();

                if (!Entity.Physics.IsMoving && Entity.Physics.RigidBody != null && Entity.Physics.RigidBody.IsAddedToWorld)
                {
                    Entity.Physics.RigidBody.Deactivate();
                }
            }
        }
        private void SendPositionUpdate()
        {
            float epsilonSq = 0.05f * 0.05f;

            if (m_updateFrameCount == ConstantMovementUpdateCount && (Entity.Physics == null ||
                                                                      Entity.Physics.LinearAcceleration.LengthSquared() > epsilonSq ||
                                                                      Entity.Physics.AngularAcceleration.LengthSquared() > epsilonSq))
            {
                m_updateFrameCount = DefaultUpdateCount;
            }

            if (MyMultiplayer.Static != null && MyMultiplayer.Static.FrameCounter - m_lastUpdateFrame >= m_updateFrameCount)
            {
                m_updateFrameCount = ConstantMovementUpdateCount;

                // TODO: abstraction would be nice
                var syncGrid = this as MySyncGrid;
                if (syncGrid != null)
                {
                    var g = MyCubeGridGroups.Static.Physical.GetGroup(syncGrid.Entity);

                    PositionUpdateBatchMsg msg = new PositionUpdateBatchMsg();
                    msg.Positions = new List <PositionUpdateMsg>(g.Nodes.Count);

                    foreach (var node in g.Nodes)
                    {
                        msg.Positions.Add(CreatePositionMsg(node.NodeData));
                        node.NodeData.SyncObject.ResetUpdateTimer();
                        node.NodeData.SyncObject.m_positionDirty = false;
                    }

                    MySession.Static.SyncLayer.SendMessageToAll(ref msg);
                }
                else
                {
                    ResetUpdateTimer();
                    PositionUpdateMsg msg = CreatePositionMsg(Entity);
                    MySession.Static.SyncLayer.SendMessageToAll(ref msg);
                }
                m_positionDirty = false;
            }
            else if (MyMultiplayer.Static != null)
            {
                MyMultiplayer.Static.RegisterForTick(this);
                m_positionDirty = true;
            }
        }
示例#5
0
        /// <summary>
        /// Serializes sync entity physics, default implementation serializes position, orientation, linear and angular velocity.
        /// </summary>
        public virtual void SerializePhysics(BitStream stream, MyNetworkClient sender, bool highOrientationCompression = false)
        {
            PositionUpdateMsg msg = stream.Writing ? CreatePositionMsg(Entity) : default(PositionUpdateMsg);

            stream.Serialize(ref msg.Position); // 24B
            if (highOrientationCompression)
            {
                stream.SerializeNormCompressed(ref msg.Orientation); // 29b
            }
            else
            {
                stream.SerializeNorm(ref msg.Orientation); // 52b
            }
            stream.Serialize(ref msg.LinearVelocity);      // 6B
            stream.Serialize(ref msg.AngularVelocity);     // 6B
            if (stream.Reading)
            {
                OnPositionUpdate(ref msg, sender);
            }
        }
 static void UpdateCallback(MySyncEntity sync, ref PositionUpdateMsg msg, MyNetworkClient sender)
 {
     sync.OnPositionUpdate(ref msg, sender);
 }
示例#7
0
        internal override void OnPositionUpdate(ref PositionUpdateMsg msg, MyNetworkClient sender)
        {//TODO consider removing this after new netcode implementation
            if (Entity.PositionComp != null && Entity.GridSystems.JumpSystem != null)
                if (!Entity.GridSystems.JumpSystem.CheckReceivedCoordinates(ref msg.Position))
                    return;

            base.OnPositionUpdate(ref msg, sender);
        }
示例#8
0
        private void SendPositionUpdate()
        {
            if (MyMultiplayer.Static == null)
            {
                return;
            }
            Debug.Assert(MySandboxGame.Static != null);
            float epsilonSq = 0.05f * 0.05f;

            if (m_updateFrameCount == ConstantMovementUpdateCount && (Entity.Physics == null ||
                                                                      Entity.Physics.LinearAcceleration.LengthSquared() > epsilonSq ||
                                                                      Entity.Physics.AngularAcceleration.LengthSquared() > epsilonSq))
            {
                m_updateFrameCount = DefaultUpdateCount;
            }

            bool timeForUpdate;

            if (MyFakes.NEW_POS_UPDATE_TIMING)
            {
                timeForUpdate = (MySandboxGame.Static.UpdateTime - m_lastUpdateTime).Seconds > (m_updateFrameCount / MyEngineConstants.UPDATE_STEPS_PER_SECOND);
            }
            else
            {
                timeForUpdate = MyMultiplayer.Static.FrameCounter - m_lastUpdateFrame >= m_updateFrameCount;
            }

            if (timeForUpdate)
            {
                m_updateFrameCount = ConstantMovementUpdateCount;

                // TODO: abstraction would be nice
                var syncGrid = this as MySyncGrid;
                if (syncGrid != null)
                {
                    var g = MyCubeGridGroups.Static.Physical.GetGroup(syncGrid.Entity);

                    PositionUpdateBatchMsg msg = new PositionUpdateBatchMsg();
                    msg.Positions = new List <PositionUpdateMsg>(g.Nodes.Count);

                    foreach (var node in g.Nodes)
                    {
                        msg.Positions.Add(CreatePositionMsg(node.NodeData));
                        node.NodeData.SyncObject.ResetUpdateTimer();
                        node.NodeData.SyncObject.m_positionDirty = false;
                    }

                    MySession.Static.SyncLayer.SendMessageToAll(ref msg);
                }
                else
                {
                    ResetUpdateTimer();
                    PositionUpdateMsg msg = CreatePositionMsg(Entity);
                    MySession.Static.SyncLayer.SendMessageToAll(ref msg);
                }
                m_positionDirty = false;
            }
            else if (MyMultiplayer.Static != null)
            {
                MyMultiplayer.Static.RegisterForTick(this);
                m_positionDirty = true;
            }
        }
示例#9
0
        internal virtual void OnPositionUpdate(ref PositionUpdateMsg msg, MyNetworkClient sender)
        {
            // Validate that client sending position update to server is reponsible for update
            if (Sync.IsServer && !ResponsibleForUpdate(sender))
                return;

            if (!Sync.IsServer && ResponsibleForUpdate(Sync.Clients.LocalClient))
                return;

            var q = msg.Orientation;
            var m = Matrix.CreateFromQuaternion(q);

            var world = MatrixD.CreateWorld(msg.Position, m.Forward, m.Up);

            Debug.Assert(Entity.PositionComp != null, "Entity doesn't not have position component");
            if (Entity.PositionComp != null)
                Entity.PositionComp.SetWorldMatrix(world, this);

            if (Entity.Physics != null)
            {
                Entity.Physics.LinearVelocity = msg.LinearVelocity;
                Entity.Physics.AngularVelocity = msg.AngularVelocity;

                if (MyPerGameSettings.EnableMultiplayerVelocityCompensation)
                {
                    float ratio = MathHelper.Clamp(Sandbox.Engine.Physics.MyPhysics.SimulationRatio, 0.1f, 2);

                    Entity.Physics.LinearVelocity /= ratio;
                    Entity.Physics.AngularVelocity /= ratio;
                }

                Entity.Physics.UpdateAccelerations();

                if (!Entity.Physics.IsMoving && Entity.Physics.RigidBody != null && Entity.Physics.RigidBody.IsAddedToWorld)
                {
                    Entity.Physics.RigidBody.Deactivate();
                }
            }

            if (Sync.IsServer)
            {
                MarkPhysicsDirty();
            }
            else
            {
                // Store last update from server
                m_isLocallyDirty = false;
                m_lastUpdateFrame = MyMultiplayer.Static.FrameCounter;
                m_lastServerPosition = msg.Position;
                m_lastServerOrientation = msg.Orientation;
            }
        }
示例#10
0
        internal static PositionUpdateMsg CreatePositionMsg(IMyEntity entity)
        {
            var m = entity.WorldMatrix;
            PositionUpdateMsg msg = new PositionUpdateMsg();
            msg.EntityId = entity.EntityId;
            msg.Orientation = Quaternion.CreateFromForwardUp(m.Forward, m.Up);
            msg.Position = m.Translation;
            if (entity.Physics != null)
            {
                if (MyPerGameSettings.EnableMultiplayerVelocityCompensation)
                {
                    float ratio = MathHelper.Clamp(Sandbox.Engine.Physics.MyPhysics.SimulationRatio, 0, 2);

                    msg.LinearVelocity = entity.Physics.LinearVelocity * ratio;
                    msg.AngularVelocity = entity.Physics.AngularVelocity * ratio;
                }
                else
                {
                    msg.LinearVelocity = entity.Physics.LinearVelocity;
                    msg.AngularVelocity = entity.Physics.AngularVelocity;
                }
            }
            return msg;
        }