public override void Destroy() { if (m_supportPhysics != null) { m_supportPhysics.OnVelocityChanged -= m_onSupportVelocityChanged; m_supportPhysics.OnMoved -= m_onSupportMove; m_supportPhysics = null; } base.Destroy(); }
public float GetGroupPriority(int frameCountWithoutSync, MyClientInfo forClient) { // Called only on server if (Entity.Physics == null || Entity.Physics.IsStatic) { return(0); } if (MyEntityPhysicsStateGroup.ResponsibleForUpdate(Entity, forClient.EndpointId)) { return(1000); } return(0); }
public void SetSupport(MyEntityPhysicsStateGroup physicsGroup) { if (m_supportPhysics != physicsGroup) { if (m_supportPhysics != null) { m_supportPhysics.OnMoved -= m_onSupportMove; m_supportPhysics.OnVelocityChanged -= m_onSupportVelocityChanged; } m_supportPhysics = physicsGroup; if (m_supportPhysics != null) { m_supportPhysics.OnMoved += m_onSupportMove; m_supportPhysics.OnVelocityChanged += m_onSupportVelocityChanged; } } }
public override void ClientUpdate(uint timestamp) { base.ClientUpdate(timestamp); if (MySession.Static.ControlledEntity != m_character) { if (m_supportTimeStamp != null) { m_supportTimeStamp.Clear(); } return; } var physGroup = MyExternalReplicable.FindByObject(m_character).FindStateGroup <MyCharacterPhysicsStateGroup>(); if (physGroup == null) { if (m_supportTimeStamp != null) { m_supportTimeStamp.Clear(); } return; } m_supportPhysics = physGroup.FindSupportDelegate(); physGroup.SetSupport(m_supportPhysics); if (m_supportPhysics != null) { if (m_supportTimeStamp == null) { m_supportTimeStamp = new MyTimestampHelper(null); } m_supportTimeStamp.SetEntity(m_supportPhysics.Entity); m_supportTimeStamp.Update(timestamp); } else { if (m_supportTimeStamp != null) { m_supportTimeStamp.Clear(); } } }
static MyEntityPhysicsStateGroup SphereBounds(MyCharacter character, float radius) { if (DEBUG_DRAW) { VRageRender.MyRenderProxy.DebugDrawSphere(character.PositionComp.GetPosition(), radius, Color.Green, 1, false, false); } // Sphere with radius 5m around character BoundingSphereD sphere = new BoundingSphereD(character.PositionComp.GetPosition(), radius); var list = MyEntities.GetEntitiesInSphere(ref sphere); try { MyEntityPhysicsStateGroup closest = null; float distanceSq = float.MaxValue; foreach (var entity in list) { if (!IsValid(entity, false)) { continue; } float distSq = (float)entity.PositionComp.WorldAABB.DistanceSquared(sphere.Center); if (distSq < distanceSq && distSq < (radius * radius)) { var phys = FindPhysics(entity); if (phys != null) { closest = phys; distanceSq = distSq; } } } return(closest); } finally { list.Clear(); } }
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); }