public void CompressAndDecompressQuaternion_Iterate_0_to_360() { // stepSize 1: 360 * 360 * 360 = 46 million [takes 96 s] // stepSize 5: 72 * 72 * 72 = 373 thousand [takes 700 ms] // stepSize 10: 36 * 36 * 36 = 46 thousand [takes 100 ms] // // => 10 is enough. 700ms accumulates in hours of time waited over // the years.. const int stepSize = 10; for (int x = 0; x <= 360; x += stepSize) { for (int y = 0; y <= 360; y += stepSize) { for (int z = 0; z <= 360; z += stepSize) { // we need a normalized value Quaternion value = Quaternion.Euler(x, y, z).normalized; // compress uint data = Compression.CompressQuaternion(value); // decompress Quaternion decompressed = Compression.DecompressQuaternion(data); // compare them. Quaternion.Angle is easiest to get the angle // between them. using .eulerAngles would give 0, 90, 360 which is // hard to compare. float angle = Quaternion.Angle(value, decompressed); // 1 degree tolerance Assert.That(Mathf.Abs(angle), Is.LessThanOrEqualTo(1)); } } } }
void ClientAuthorityUpdate() { if (!isServer && HasEitherMovedRotatedScaled()) { // serialize // local Position/Orientation for VR sUpport // send to server CmdClientToServerSync(targetTransform.LocalPosition, Compression.CompressQuaternion(targetTransform.LocalOrientation), targetTransform.LocalScale); } }
public void ServerTeleport(Vector3 LocalPosition, Quaternion LocalOrientation) { // To prevent applying the Position Updates received from client (if they have ClientAuth) while being teleported. // clientAuthorityBeforeTeleport defaults to false when not teleporting, if it is true then it means that teleport // was previously called but not finished therefore we should keep it as true so that 2nd teleport call doesn't clear authority clientAuthorityBeforeTeleport = clientAuthority || clientAuthorityBeforeTeleport; clientAuthority = false; DoTeleport(LocalPosition, LocalOrientation); // tell all clients about new values RpcTeleport(LocalPosition, Compression.CompressQuaternion(LocalOrientation), clientAuthorityBeforeTeleport); }
public void SerializeIntoWriterTest() { NetworkWriter writer = new NetworkWriter(); Vector3 position = new Vector3(1, 2, 3); Quaternion rotation = new Quaternion(0.1f, 0.2f, 0.3f, 0.4f); Vector3 scale = new Vector3(0.5f, 0.6f, 0.7f); NetworkTransformBase.SerializeIntoWriter(writer, position, rotation, scale, true, true); NetworkReader reader = new NetworkReader(writer.ToArray()); Assert.That(reader.ReadVector3(), Is.EqualTo(position)); Assert.That(reader.ReadUInt(), Is.EqualTo(Compression.CompressQuaternion(rotation))); Assert.That(reader.ReadVector3(), Is.EqualTo(scale)); }
public void CompressAndDecompressQuaternion() { // we need a normalized value Quaternion value = new Quaternion(1, 3, 4, 2).normalized; // compress uint data = Compression.CompressQuaternion(value); Assert.That(data, Is.EqualTo(0xA83E2F07)); // decompress Quaternion decompressed = Compression.DecompressQuaternion(data); Assert.That(decompressed.x, Is.EqualTo(value.x).Within(0.005f)); Assert.That(decompressed.y, Is.EqualTo(value.y).Within(0.005f)); Assert.That(decompressed.z, Is.EqualTo(value.z).Within(0.005f)); Assert.That(decompressed.w, Is.EqualTo(value.w).Within(0.005f)); }
public void CompressAndDecompressQuaternion_90DegreeEuler() { // we need a normalized value Quaternion value = Quaternion.Euler(0, 90, 0).normalized; // compress uint data = Compression.CompressQuaternion(value); // decompress Quaternion decompressed = Compression.DecompressQuaternion(data); // compare them. Quaternion.Angle is easiest to get the angle // between them. using .eulerAngles would give 0, 90, 360 which is // hard to compare. Debug.Log("euler=" + decompressed.eulerAngles); float angle = Quaternion.Angle(value, decompressed); // 1 degree tolerance Assert.That(Mathf.Abs(angle), Is.LessThanOrEqualTo(1)); }
public void RotationIsWithinPrecision(Quaternion rotationIn) { uint packed = Compression.CompressQuaternion(rotationIn); Quaternion rotationOut = Compression.DecompressQuaternion(packed); Assert.That(rotationOut.x, Is.Not.NaN, "x was NaN"); Assert.That(rotationOut.y, Is.Not.NaN, "y was NaN"); Assert.That(rotationOut.z, Is.Not.NaN, "z was NaN"); Assert.That(rotationOut.w, Is.Not.NaN, "w was NaN"); Vector3 inVec = rotationIn * Vector3.forward; Vector3 outVec = rotationOut * Vector3.forward; // allow for extra precision when rotating vector float precision = AllowedPrecision * 2; Assert.AreEqual(inVec.x, outVec.x, precision, $"x off by {Mathf.Abs(inVec.x - outVec.x)}"); Assert.AreEqual(inVec.y, outVec.y, precision, $"y off by {Mathf.Abs(inVec.y - outVec.y)}"); Assert.AreEqual(inVec.z, outVec.z, precision, $"z off by {Mathf.Abs(inVec.z - outVec.z)}"); }
public void QuaternionCompressIsWithinPrecision(Quaternion inRot) { uint packed = Compression.CompressQuaternion(inRot); Quaternion outRot = Compression.DecompressQuaternion(packed); Assert.That(outRot.x, Is.Not.NaN, "x was NaN"); Assert.That(outRot.y, Is.Not.NaN, "y was NaN"); Assert.That(outRot.z, Is.Not.NaN, "z was NaN"); Assert.That(outRot.w, Is.Not.NaN, "w was NaN"); int largest = Compression.FindLargestIndex(inRot); float sign = Mathf.Sign(inRot[largest]); // flip sign of A if largest is negative // Q == (-Q) Assert.AreEqual(sign * inRot.x, outRot.x, AllowedPrecision, $"x off by {Mathf.Abs(sign * inRot.x - outRot.x)}"); Assert.AreEqual(sign * inRot.y, outRot.y, AllowedPrecision, $"y off by {Mathf.Abs(sign * inRot.y - outRot.y)}"); Assert.AreEqual(sign * inRot.z, outRot.z, AllowedPrecision, $"z off by {Mathf.Abs(sign * inRot.z - outRot.z)}"); Assert.AreEqual(sign * inRot.w, outRot.w, AllowedPrecision, $"w off by {Mathf.Abs(sign * inRot.w - outRot.w)}"); }
public void CompressAndDecompressQuaternion_2674() { // we need a normalized value Quaternion value = Quaternion.Euler(338.850037f, 170.609955f, 182.979996f).normalized; Debug.Log("immediate=" + value.eulerAngles); // compress uint data = Compression.CompressQuaternion(value); // decompress Quaternion decompressed = Compression.DecompressQuaternion(data); // compare them. Quaternion.Angle is easiest to get the angle // between them. using .eulerAngles would give 0, 90, 360 which is // hard to compare. // (51.6, 355.5, 348.1) Debug.Log("euler=" + decompressed.eulerAngles); float angle = Quaternion.Angle(value, decompressed); // 1 degree tolerance Assert.That(Mathf.Abs(angle), Is.LessThanOrEqualTo(1)); }
void ServerUpdate() { RpcMove(targetTransform.LocalPosition, Compression.CompressQuaternion(targetTransform.LocalOrientation), targetTransform.LocalScale); }