public static CompressedQuaternion Deserialize(global::Improbable.Worker.CInterop.SchemaObject obj) { var instance = new CompressedQuaternion(); { instance.Data = obj.GetUint32(1); } return(instance); }
/// <summary> /// Utility method for creating a TransformInternal Snapshot. /// </summary> /// <param name="location"> /// The location of an entity, given as a Unity Vector3. /// </param> /// <param name="rotation"> /// The rotation of an entity, given as a Unity Quaternion. /// </param> /// <param name="velocity"> /// The velocity of an entity, given as a Unity Vector3. /// </param> /// <remarks> /// This method populates a TransformInternal with compressed representations of the given arguments. /// </remarks> public static TransformInternal.Snapshot CreateTransformSnapshot( Vector3 location = default, Quaternion rotation = default, Vector3 velocity = default) { return(new TransformInternal.Snapshot { Location = FixedPointVector3.FromUnityVector(location), Rotation = CompressedQuaternion.FromUnityQuaternion(rotation), Velocity = FixedPointVector3.FromUnityVector(velocity), TicksPerSecond = 1f / Time.fixedDeltaTime }); }
/// <summary> /// Decompresses a quaternion from a packed uint32 to an unpacked Unity Quaternion. /// </summary> /// <param name="compressedQuaternion"> /// The CompressedQuaternion to decompress. /// </param> /// <remarks> /// <para> /// The underlying uint contains the "smallest three" components of a quaternion. The first two bits of /// of the uint encode which component is the largest value. This component's value is then computed as /// 1 minus the sum of the squares of the smallest three components. /// </para> /// <para> /// This method is marked as unsafe due to the use of stack allocation. /// </para> /// </remarks> /// <returns> /// A decompressed Unity Quaternion. /// </returns> internal static unsafe UnityEngine.Quaternion ToUnityQuaternion(CompressedQuaternion compressedQuaternion) { // The raw uint representing a compressed quaternion. var compressedValue = compressedQuaternion.Data; // Stack allocate float array to ensure it's discarded when the method returns. // q[x, y, z, w] var q = stackalloc float[4]; // Mask of 23 0's and 9 1's. const uint mask = (1u << 9) - 1u; // Only need the two leftmost bits to find the index of the largest component. int largestIndex = (int)(compressedValue >> 30); float sumSquares = 0; for (var i = 3; i >= 0; --i) { if (i != largestIndex) { // Apply mask to return the 9 bits representing a component's value. uint magnitude = compressedValue & mask; // Get the 10th bit from the right (the signbit of the component). uint signBit = (compressedValue >> 9) & 0x1; // Convert back from the range [0,1] to [0, 1/sqrt(2)]. q[i] = SqrtHalf * ((float)magnitude) / mask; // If signbit is set, negate the value. if (signBit == 1) { q[i] *= -1; } // Add to the rolling sum of each component's square value. sumSquares += Mathf.Pow(q[i], 2); // Shift right by 10 so that the next component's bits are evaluated in the next loop iteration. compressedValue >>= 10; } } // The value of the largest component is 1 - the sum of the squares of the smallest three components. q[largestIndex] = Mathf.Sqrt(1f - sumSquares); return(new Quaternion(q[0], q[1], q[2], q[3])); }
/// <summary> /// Extension method for converting a Quaternion to a CompressedQuaternion. /// </summary> public static CompressedQuaternion ToCompressedQuaternion(this Quaternion quaternion) { return(CompressedQuaternion.FromUnityQuaternion(quaternion)); }
public bool Equals(CompressedQuaternion other) { return(Data == other.Data); }
public static void Serialize(CompressedQuaternion instance, global::Improbable.Worker.CInterop.SchemaObject obj) { { obj.AddUint32(1, instance.Data); } }
/// <summary> /// Returns whether two CompressedQuaternion variables are different. /// </summary> internal static bool HasChanged(CompressedQuaternion a, CompressedQuaternion b) { return(a.Data != b.Data); }