Beispiel #1
0
        /// <summary>
        /// Compress position to integers and push it to the buffer, required bytes count: <see cref="PositionRequiredBytes"/>
        /// </summary>
        /// <param name="bytesStack">Buffer where position will be pushed</param>
        /// <param name="position">Position to be compressed and pushed</param>
        public static void PushCompressedPosition(this BytesStack bytesStack, Vector3 position)
        {
            //Reverse order when writing to stack
            //Always use little-endian so compression and decompression are machines independent
            var z = CompressPositionZ(position.z);

            if (!BitConverter.IsLittleEndian)
            {
                z = SwapEndianness(z);
            }
            bytesStack.PushInt(z, PositionZRequiredBytes);

            var y = CompressPositionY(position.y);

            if (!BitConverter.IsLittleEndian)
            {
                y = SwapEndianness(y);
            }
            bytesStack.PushInt(y, PositionYRequiredBytes);

            var x = CompressPositionX(position.x);

            if (!BitConverter.IsLittleEndian)
            {
                x = SwapEndianness(x);
            }
            bytesStack.PushInt(x, PositionXRequiredBytes);
        }
Beispiel #2
0
        /// <summary>
        /// Compress vector3 to integers and push it to the buffer
        /// </summary>
        /// <param name="bytesStack">Buffer where vector3 will be pushed</param>
        /// <param name="vector3">Vector3 to be compressed and pushed</param>
        /// <param name="minElementValue">Minimal value of the encoded vector3</param>
        /// <param name="maxElementValue">Maximal value of the encoded vector3</param>
        /// <param name="bytesPerElement">Bytes count that will be used per each element</param>
        public static void PushCompressedVector3(this BytesStack bytesStack, Vector3 vector3, float minElementValue,
                                                 float maxElementValue, int bytesPerElement)
        {
            //Reverse order when writing to stack
            //Always use little-endian so compression and decompression are machines independent
            var z = CompressFloatToInt(vector3.z, minElementValue, maxElementValue, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                z = SwapEndianness(z);
            }
            bytesStack.PushInt(z, bytesPerElement);

            var y = CompressFloatToInt(vector3.y, minElementValue, maxElementValue, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                y = SwapEndianness(y);
            }
            bytesStack.PushInt(y, bytesPerElement);

            var x = CompressFloatToInt(vector3.x, minElementValue, maxElementValue, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                x = SwapEndianness(x);
            }
            bytesStack.PushInt(x, bytesPerElement);
        }
Beispiel #3
0
        /// <summary>
        /// Compress color to integers and push it to the buffer
        /// </summary>
        /// <param name="bytesStack">Buffer where color will be pushed</param>
        /// <param name="color">Color to be compressed and pushed</param>
        /// <param name="bytesPerElement">Bytes count that will be used per each element</param>
        public static void PushCompressedColor(this BytesStack bytesStack, Color color, int bytesPerElement)
        {
            //Reverse order when writing to stack
            //Always use little-endian so compression and decompression are machines independent
            var a = CompressFloatToInt(color.a, 0.0f, 1.0f, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                a = SwapEndianness(a);
            }
            bytesStack.PushInt(a, bytesPerElement);

            var b = CompressFloatToInt(color.b, 0.0f, 1.0f, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                b = SwapEndianness(b);
            }
            bytesStack.PushInt(b, bytesPerElement);

            var g = CompressFloatToInt(color.g, 0.0f, 1.0f, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                g = SwapEndianness(g);
            }
            bytesStack.PushInt(g, bytesPerElement);

            var r = CompressFloatToInt(color.r, 0.0f, 1.0f, bytesPerElement);

            if (!BitConverter.IsLittleEndian)
            {
                r = SwapEndianness(r);
            }
            bytesStack.PushInt(r, bytesPerElement);
        }
Beispiel #4
0
        /// <summary>
        /// Compress rotation to integers and push it to the buffer, required bytes count: <see cref="RotationPrecision"/>
        /// </summary>
        /// <param name="bytesStack">Buffer where rotation will be pushed</param>
        /// <param name="rotation">Rotation to be compressed and pushed</param>
        public static void PushCompressedRotation(this BytesStack bytesStack, Quaternion rotation)
        {
            //Algorithm based on the "smallest three" method described at:
            //http://gafferongames.com/networked-physics/snapshot-compression/
            var maxIndex = (byte)0;
            var maxValue = float.MinValue;
            var sign     = 1f;

            // Find the maximum element in the quaternion
            for (var i = 0; i < 4; i++)
            {
                var element = rotation[i];
                var abs     = Mathf.Abs(rotation[i]);
                if (!(abs > maxValue))
                {
                    continue;
                }
                // Maximum element is always compressed as positive, all other elements are negated if needed
                sign     = (element < 0) ? -1 : 1;
                maxIndex = (byte)i;
                maxValue = abs;
            }

            // If the maximum element is approximately equal to 1.0f all other elements are approximately equal to 0.0f and does not have to be encoded
            if (Mathf.Approximately(maxValue, 1.0f))
            {
                //Use 4-7 indexes to determine which element is maximum and it is approximately equal to 1.0f
                bytesStack.PushInt(maxIndex + 4, 1);
                return;
            }

            //Reverse order when writing to stack
            // Compress and encode only smallest three Quaternion components as little endian integers
            if (maxIndex != 3)
            {
                var w = CompressFloatToInt(rotation.w * sign, -1.0f, 1.0f, DefaultBytesForCompressedFloat);
                if (!BitConverter.IsLittleEndian)
                {
                    w = SwapEndianness(w);
                }
                bytesStack.PushInt(w, DefaultBytesForCompressedFloat);
            }

            if (maxIndex != 2)
            {
                var z = CompressFloatToInt(rotation.z * sign, -1.0f, 1.0f, DefaultBytesForCompressedFloat);
                if (!BitConverter.IsLittleEndian)
                {
                    z = SwapEndianness(z);
                }
                bytesStack.PushInt(z, DefaultBytesForCompressedFloat);
            }

            if (maxIndex != 1)
            {
                var y = CompressFloatToInt(rotation.y * sign, -1.0f, 1.0f, DefaultBytesForCompressedFloat);
                if (!BitConverter.IsLittleEndian)
                {
                    y = SwapEndianness(y);
                }
                bytesStack.PushInt(y, DefaultBytesForCompressedFloat);
            }

            if (maxIndex != 0)
            {
                var x = CompressFloatToInt(rotation.x * sign, -1.0f, 1.0f, DefaultBytesForCompressedFloat);
                if (!BitConverter.IsLittleEndian)
                {
                    x = SwapEndianness(x);
                }
                bytesStack.PushInt(x, DefaultBytesForCompressedFloat);
            }

            bytesStack.PushInt(BitConverter.IsLittleEndian ? maxIndex : SwapEndianness(maxIndex), 1);
        }
Beispiel #5
0
 /// <summary>
 /// Pushes the enum integer value with minimum required bytes
 /// </summary>
 /// <param name="bytesStack">Buffer where enum is pushed</param>
 /// <param name="intValue">Enum value casted to integer</param>
 /// <typeparam name="T">Enum type</typeparam>
 public static void PushEnum <T>(this BytesStack bytesStack, int intValue)
     where T : IComparable, IConvertible, IFormattable
 {
     bytesStack.PushInt(intValue, RequiredBytes <T>());
 }