bool ReadTransform(BitStream stream, MyEntity entity, Vector3D? deltaPosBase, bool applyWhenReading, bool movingOnServer, ref Vector3D outPosition, ref Quaternion outOrientation, ref MatrixD outWorldMartix, Func<MyEntity, Vector3D, bool> posValidation = null, MovedDelegate moveHandler = null) { Vector3D position; if (stream.ReadBool()) { position = stream.ReadVector3D(); // 24 B } else { Vector3 pos = stream.ReadVector3(); // 6 B if (deltaPosBase != null) { position = pos + deltaPosBase.Value; } else { position = pos; } } Quaternion orientation; bool lowPrecisionOrientation = stream.ReadBool(); if (lowPrecisionOrientation) { orientation = stream.ReadQuaternionNormCompressed(); // 29b } else { orientation = stream.ReadQuaternionNorm(); // 52b } if (entity != null) { movingOnServer |= (entity.PositionComp.GetPosition() - position).LengthSquared() > epsilonSq; if (movingOnServer && applyWhenReading && (posValidation == null || posValidation(entity, position))) { MatrixD matrix = MatrixD.CreateFromQuaternion(orientation); if (matrix.IsValid()) { matrix.Translation = position; outPosition = matrix.Translation; outOrientation = orientation; outWorldMartix = matrix; return true; } return false; } } return false; }
/// <summary> /// Serializes physics and takes into account support (what's entity standing on) /// </summary> private void SerializePhysicsWithSupport(BitStream stream, EndpointId forClient,uint timestamp, byte packetId, int maxBitPosition) { if (stream.Writing) { // TODO: only prototype implementation SetSupport(FindSupportDelegate()); stream.WriteBool(m_supportPhysics != null); if (m_supportPhysics != null) { stream.WriteInt64(m_supportPhysics.Entity.EntityId); var localToParent = Entity.WorldMatrix * MatrixD.Invert(m_supportPhysics.Entity.PositionComp.WorldMatrix); stream.Write(localToParent.Translation); stream.Write(Quaternion.CreateFromForwardUp(localToParent.Forward, localToParent.Up).ToVector4()); bool moving = IsMoving(Entity); stream.WriteBool(moving); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, !IsControlledLocally, moving); } else { base.Serialize(stream, forClient,timestamp, packetId, maxBitPosition); } } else { if (stream.ReadBool()) { MyEntity support; bool apply = MyEntities.TryGetEntityById(stream.ReadInt64(), out support) && !IsControlledLocally; var pos = stream.ReadVector3D(); var orient = Quaternion.FromVector4(stream.ReadVector4()); if (apply) { var old = Entity.PositionComp.WorldMatrix; MatrixD localToParent = MatrixD.CreateFromQuaternion(orient); localToParent.Translation = pos; MatrixD matrix = localToParent * support.WorldMatrix; Entity.PositionComp.SetWorldMatrix(matrix, null, true); SetSupport(MySupportHelper.FindPhysics(support)); var handler = MoveHandler; if (handler != null) { handler(ref old, ref matrix); } } else { SetSupport(null); } bool moving = stream.ReadBool(); SerializeVelocities(stream, Entity, EffectiveSimulationRatio, apply, moving); } else { SetSupport(null); base.Serialize(stream, forClient, timestamp, packetId, maxBitPosition); } } }