public static Vector3D Transform(ref Vector3D v, ref MyTransformD t2) { Vector3D result; Transform(ref v, ref t2, out result); return(result); }
public static MyTransformD Transform(ref MyTransformD t1, ref MyTransformD t2) { MyTransformD md; Transform(ref t1, ref t2, out md); return(md); }
public static Vector3D Transform(ref Vector3D v, ref MyTransformD t2) { Vector3D vectord; Transform(ref v, ref t2, out vectord); return(vectord); }
public static MyTransformD Transform(ref MyTransformD t1, ref MyTransformD t2) { MyTransformD result; Transform(ref t1, ref t2, out result); return(result); }
public static void Transform(ref MyTransformD t1, ref MyTransformD t2, out MyTransformD result) { Vector3D newPos; Vector3D.Transform(ref t1.Position, ref t2.Rotation, out newPos); newPos += t2.Position; Quaternion newRot; Quaternion.Multiply(ref t1.Rotation, ref t2.Rotation, out newRot); result.Position = newPos; result.Rotation = newRot; }
public static void Transform(ref MyTransformD t1, ref MyTransformD t2, out MyTransformD result) { Vector3D vectord; Quaternion quaternion; Vector3D.Transform(ref t1.Position, ref t2.Rotation, out vectord); vectord += t2.Position; Quaternion.Multiply(ref t1.Rotation, ref t2.Rotation, out quaternion); result.Position = vectord; result.Rotation = quaternion; }
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]; MyTransformD delta = UpdateValues(m_entity, ref serverPositionAndOrientation, ref cachedData); UpdateDeltaPosition(timeStamp, ref delta); m_lastTSFromServer = timeStamp; }
public override void Init(MyObjectBuilder_SessionComponent sessionComponent) { base.Init(sessionComponent); var coordSysBuilder = sessionComponent as MyObjectBuilder_CoordinateSystem; this.m_lastCoordSysId = coordSysBuilder.LastCoordSysId; foreach(var coordSys in coordSysBuilder.CoordSystems) { MyTransformD origin = new MyTransformD(); origin.Position = coordSys.Position; origin.Rotation = coordSys.Rotation; MyLocalCoordSys newCoordSys = new MyLocalCoordSys(origin, m_coorsSystemSize); newCoordSys.Id = coordSys.Id; m_localCoordSystems.Add(coordSys.Id, newCoordSys); } }
protected virtual bool IsPositionValid(MyTransformD clientPos) { return true; }
public static MyTransformD Transform(ref MyTransformD t1, ref MyTransformD t2) { MyTransformD result; Transform(ref t1, ref t2, out result); return result; }
void ClientRead(VRage.Library.Collections.BitStream stream) { bool hasClientData= stream.ReadBool(); uint? timeStamp = null; if (hasClientData) { timeStamp = stream.ReadUInt32(); m_lastRecievedTimeStamp = timeStamp.Value; bool isUpdate = stream.ReadBool(); if (isUpdate) { MyTransformD serverTransform = new MyTransformD(); serverTransform.Position = stream.ReadVector3D(); serverTransform.Rotation = Quaternion.Identity; CustomClientRead(timeStamp.Value, ref serverTransform, stream); } } Vector3 serverLinearVelocity = stream.ReadVector3(); Vector3 serverAngularVelocity = stream.ReadVector3(); MyTimeStampValues? clientData = null; if (timeStamp.HasValue) { clientData = m_timestamp.GetTransform(timeStamp.Value); } if (clientData.HasValue) { Vector3 linearDelta = serverLinearVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.LinearVelocity; Entity.Physics.LinearVelocity += Vector3.Round(linearDelta, 2); Vector3 angularDelta = serverAngularVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio - clientData.Value.AngularVelocity; Entity.Physics.AngularVelocity += Vector3.Round(angularDelta, 2); m_timestamp.UpdateDeltaVelocities(timeStamp.Value, ref linearDelta, ref angularDelta); } else { Vector3 linearVelocity = serverLinearVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio; Entity.Physics.LinearVelocity = Vector3.Round(linearVelocity, 2); Vector3 angularVelocity = serverAngularVelocity / MyEntityPhysicsStateGroup.EffectiveSimulationRatio; Entity.Physics.AngularVelocity = Vector3.Round(angularVelocity, 2); } }
protected virtual void CustomClientRead(uint timeStamp, ref MyTransformD serverPositionAndOrientation, VRage.Library.Collections.BitStream stream) { if (m_timestamp != null) { m_timestamp.ServerResponse(timeStamp, ref serverPositionAndOrientation); } }
/// <summary> /// Converts world position to be snapped to closest grid. /// </summary> /// <param name="worldPos">World position.</param> /// <param name="gridSize">Grid size.</param> /// <param name="staticGridAlignToCenter">Is grid align to static.</param> /// <returns></returns> public CoordSystemData SnapWorldPosToClosestGrid(ref Vector3D worldPos, double gridSize, bool staticGridAlignToCenter) { m_lastSelectedCoordSys = m_selectedCoordSys; MyLocalCoordSys localCoordSys = null; localCoordSys = this.GetClosestCoordSys(ref worldPos); // If no coord sys found, return origin(0,0,0) with no rotation! if (localCoordSys == null) { localCoordSys = new MyLocalCoordSys(m_coorsSystemSize); m_selectedCoordSys = 0; } else m_selectedCoordSys = localCoordSys.Id; if (m_selectedCoordSys == 0) { m_localCoordExist = false; } else { m_localCoordExist = true; } if (m_selectedCoordSys != m_lastSelectedCoordSys) { m_selectionChanged = true; if(OnCoordinateChange != null) OnCoordinateChange(); } else m_selectionChanged = false; //if (!m_localCoordExist && m_selectionChanged) //{ // this.Disable(); //} //else if (m_selectionChanged && m_lastSelectedCoordSys == 0) //{ // this.Enable(); //} CoordSystemData coordData = new CoordSystemData(); Quaternion rotation = localCoordSys.Origin.Rotation; Quaternion invRotation = Quaternion.Inverse(rotation); Vector3D position = localCoordSys.Origin.Position; Vector3D vec = worldPos - position; vec = Vector3D.Transform(vec, invRotation); MyCoordinateSystem.GetPosRoundedToGrid(ref vec, gridSize, staticGridAlignToCenter); coordData.LocalSnappedPos = vec; vec = Vector3D.Transform(vec, rotation); MyTransformD localCoordsTransform = new MyTransformD(); localCoordsTransform.Position = position + vec; localCoordsTransform.Rotation = rotation; coordData.SnappedTransform = localCoordsTransform; coordData.Origin = localCoordSys.Origin; return coordData; }
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); }
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; }
/// <summary> /// Creates coord system and sends it to clients. Should be called only on server. /// </summary> /// <param name="cubeGrid">Cube grid that is an origin.</param> /// <param name="staticGridAlignToCenter">Indcates if grid should be aligned to center or no.</param> public void CreateCoordSys(MyCubeGrid cubeGrid, bool staticGridAlignToCenter, bool sync = false) { //In me this system is not working for now (will change after implementing planets there) //if(MyPerGameSettings.Game == GameEnum.ME_GAME) //{ // return; //} Debug.Assert(Sync.IsServer, "Called on client. This method should be called only on server."); MyTransformD origin = new MyTransformD(cubeGrid.PositionComp.WorldMatrix); origin.Rotation.Normalize(); float gridSize = cubeGrid.GridSize; if (!staticGridAlignToCenter) { origin.Position -= (origin.Rotation.Forward + origin.Rotation.Right + origin.Rotation.Up) * gridSize * 0.5f; } MyLocalCoordSys localCoordSys = new MyLocalCoordSys(origin, m_coorsSystemSize); long newId = m_lastCoordSysId++; // Just raise by one. There wont be so much id's for long to be overflooded. localCoordSys.Id = newId; m_localCoordSystems.Add(newId, localCoordSys); if (cubeGrid.LocalCoordSystem != 0) this.UnregisterCubeGrid(cubeGrid); this.RegisterCubeGrid(cubeGrid, localCoordSys); MyCreateCoordSysBuffer createCoordSysBuffer = new MyCreateCoordSysBuffer(); createCoordSysBuffer.Position = origin.Position; createCoordSysBuffer.Rotation = origin.Rotation; createCoordSysBuffer.Id = newId; if(sync) MyMultiplayer.RaiseStaticEvent(x => CoordSysCreated_Client, createCoordSysBuffer); }
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); } }
public static Vector3D Transform(ref Vector3D v, ref MyTransformD t2) { Vector3D result; Transform(ref v, ref t2, out result); return result; }
public static void Transform(ref Vector3D v, ref MyTransformD t2, out Vector3D result) { Vector3D.Transform(ref v, ref t2.Rotation, out result); result += t2.Position; }
public void UpdateDeltaPosition(uint timestamp, ref MyTransformD data) { if (m_timeStampData.Count <= 0) return; for (uint i = timestamp; i <= m_currentTimestamp; ++i) { UpdateData(i, ref data); } }
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; } }
private static void CoordSysCreated_Client(MyCreateCoordSysBuffer createBuffer) { MyTransformD origin = new MyTransformD(); origin.Position = createBuffer.Position; origin.Rotation = createBuffer.Rotation; MyCoordinateSystem.Static.CreateCoordSys_ClientInternal(ref origin, createBuffer.Id); }
protected override bool IsPositionValid(MyTransformD clientDelta) { if (m_character.Physics != null && m_character.Physics.CharacterProxy != null) { float offset = 2 * MyPerGameSettings.PhysicsConvexRadius + 0.03f; float width = (m_character.Definition.CharacterCollisionWidth * m_character.Definition.CharacterCollisionScale) - offset; float height = (m_character.Definition.CharacterCollisionHeight - m_character.Definition.CharacterCollisionWidth * m_character.Definition.CharacterCollisionScale) - offset; HkCapsuleShape capsule = new HkCapsuleShape(Vector3.Up * height / 2.0f, Vector3.Down * height / 2.0f, width / 2.0f); m_results.Clear(); clientDelta.Position = clientDelta.Position + m_character.WorldMatrix.Up * (m_character.Definition.CharacterCollisionHeight/2 + offset); MyPhysics.GetPenetrationsShape(capsule, ref clientDelta.Position, ref clientDelta.Rotation, m_results, MyPhysics.CollisionLayers.DefaultCollisionLayer); bool otherFound = false; foreach (var colision in m_results) { if (colision.Body.Quality == HkCollidableQualityType.Character) { continue; } otherFound = true; } return !otherFound; } return false; }
/// <summary> /// Only creates coord system. Call only on client in reaction on server create. /// </summary> /// <param name="transform">Origin of the coord system.</param> /// <param name="coordSysId">Coord system id that should be used in creation.</param> private void CreateCoordSys_ClientInternal(ref MyTransformD transform, long coordSysId) { MyLocalCoordSys localCoordSys = new MyLocalCoordSys(transform, m_coorsSystemSize); localCoordSys.Id = coordSysId; m_localCoordSystems.Add(coordSysId, localCoordSys); }