Example #1
0
        /// <summary>
        /// Compressed vector track and writes it to writer
        /// </summary>
        /// <param name="w"></param>
        /// <param name="values"></param>
        private void CompressVectorTrack(BinaryWriter w, IList <object> values)
        {
            // Process
            short Flags        = 0;
            short BitsPerEntry = 0;

            Quantanizer v1 = new Quantanizer();
            Quantanizer v2 = new Quantanizer();
            Quantanizer v3 = new Quantanizer();
            Quantanizer v4 = new Quantanizer();

            foreach (AnimTrackCustomVector4 vec in values)
            {
                v1.Add(vec.X);
                v2.Add(vec.Y);
                v3.Add(vec.Z);
                v4.Add(vec.W);
            }

            BitsPerEntry = (short)(v1.GetBitCount(Epsilon) + v2.GetBitCount(Epsilon) + v3.GetBitCount(Epsilon) + v4.GetBitCount(Epsilon));

            //TODO: this is bugged
            // Write Compressed Header
            w.Write((short)0x04);
            w.Write(Flags);
            w.Write((short)(0x10 + 0x10 * 4));            // default values offset
            w.Write(BitsPerEntry);
            w.Write(0x10 + 0x10 * 4 + sizeof(float) * 4); // compressed data start
            w.Write(values.Count);                        // frame count

            // table
            w.Write(v1.Min); w.Write(v1.Max); w.Write(v1.GetBitCount(Epsilon));
            w.Write(v2.Min); w.Write(v2.Max); w.Write(v2.GetBitCount(Epsilon));
            w.Write(v3.Min); w.Write(v3.Max); w.Write(v3.GetBitCount(Epsilon));
            w.Write(v4.Min); w.Write(v4.Max); w.Write(v4.GetBitCount(Epsilon));

            // default values
            w.Write(((AnimTrackCustomVector4)values[0]).X);
            w.Write(((AnimTrackCustomVector4)values[0]).Y);
            w.Write(((AnimTrackCustomVector4)values[0]).Z);
            w.Write(((AnimTrackCustomVector4)values[0]).W);

            // compressed data
            BitWriter bitWriter = new BitWriter();

            foreach (AnimTrackCustomVector4 vec in values)
            {
                bitWriter.WriteBits(v1.GetQuantanizedValue(vec.X), v1.GetBitCount(Epsilon));
                bitWriter.WriteBits(v2.GetQuantanizedValue(vec.Y), v2.GetBitCount(Epsilon));
                bitWriter.WriteBits(v3.GetQuantanizedValue(vec.Z), v3.GetBitCount(Epsilon));
                bitWriter.WriteBits(v4.GetQuantanizedValue(vec.W), v4.GetBitCount(Epsilon));
            }
            w.Write(bitWriter.GetBytes());
        }
Example #2
0
        /// <summary>
        /// Compresses <see cref="AnimTrackTransform" track and writes to writer/>
        /// </summary>
        /// <param name="w"></param>
        /// <param name="values"></param>
        private void CompressTransformTracks(BinaryWriter w, IList <object> values)
        {
            Quantanizer SX = new Quantanizer();
            Quantanizer SY = new Quantanizer();
            Quantanizer SZ = new Quantanizer();
            Quantanizer RX = new Quantanizer();
            Quantanizer RY = new Quantanizer();
            Quantanizer RZ = new Quantanizer();
            Quantanizer X  = new Quantanizer();
            Quantanizer Y  = new Quantanizer();
            Quantanizer Z  = new Quantanizer();

            // pre-process
            foreach (AnimTrackTransform transform in values)
            {
                SX.Add(transform.SX);
                SY.Add(transform.SY);
                SZ.Add(transform.SZ);
                RX.Add(transform.RX);
                RY.Add(transform.RY);
                RZ.Add(transform.RZ);
                X.Add(transform.X);
                Y.Add(transform.Y);
                Z.Add(transform.Z);
            }

            short  Flags        = 0;
            ushort BitsPerEntry = 0;

            bool hasScale    = (!SX.Constant || !SY.Constant || !SZ.Constant);
            bool hasRotation = (!RX.Constant || !RY.Constant || !RZ.Constant);
            bool hasPosition = (!X.Constant || !Y.Constant || !Z.Constant);


            if (!hasScale)
            {
                Flags |= 0x02;
            }
            else
            {
                BitsPerEntry += (ushort)((SX.Constant ? 0 : SX.GetBitCount(Epsilon)) + (SY.Constant ? 0 : SY.GetBitCount(Epsilon)) + (SZ.Constant ? 0 : SZ.GetBitCount(Epsilon)));
                Flags        |= 0x01;
            }
            if (hasRotation)
            {
                BitsPerEntry += (ushort)((RX.Constant ? 0 : RX.GetBitCount(Epsilon)) + (RY.Constant ? 0 : RY.GetBitCount(Epsilon)) + (RZ.Constant ? 0 : RZ.GetBitCount(Epsilon)) + 1); // the 1 is for extra w rotation bit
                Flags        |= 0x04;
            }
            if (hasPosition)
            {
                BitsPerEntry += (ushort)((X.Constant ? 0 : X.GetBitCount(Epsilon)) + (Y.Constant ? 0 : Y.GetBitCount(Epsilon)) + (Z.Constant ? 0 : Z.GetBitCount(Epsilon)));
                Flags        |= 0x08;
            }

            // Compressed Header
            w.Write((short)0x04);
            w.Write(Flags);
            w.Write((short)(0x10 + 0x10 * 9));             // default values offset
            w.Write(BitsPerEntry);
            w.Write(0x10 + 0x10 * 9 + sizeof(float) * 11); // compressed data start
            w.Write(values.Count);                         // frame count

            // write chunks
            w.Write(SX.Min); w.Write(SX.Max); w.Write((long)SX.GetBitCount(Epsilon));
            w.Write(SY.Min); w.Write(SY.Max); w.Write((long)SY.GetBitCount(Epsilon));
            w.Write(SZ.Min); w.Write(SZ.Max); w.Write((long)SZ.GetBitCount(Epsilon));
            w.Write(RX.Min); w.Write(RX.Max); w.Write((long)RX.GetBitCount(Epsilon));
            w.Write(RY.Min); w.Write(RY.Max); w.Write((long)RY.GetBitCount(Epsilon));
            w.Write(RZ.Min); w.Write(RZ.Max); w.Write((long)RZ.GetBitCount(Epsilon));
            w.Write(X.Min); w.Write(X.Max); w.Write((long)X.GetBitCount(Epsilon));
            w.Write(Y.Min); w.Write(Y.Max); w.Write((long)Y.GetBitCount(Epsilon));
            w.Write(Z.Min); w.Write(Z.Max); w.Write((long)Z.GetBitCount(Epsilon));

            // write default values
            AnimTrackTransform defaultValue = (AnimTrackTransform)values[0];

            w.Write(defaultValue.SX);
            w.Write(defaultValue.SY);
            w.Write(defaultValue.SZ);
            w.Write(defaultValue.RX);
            w.Write(defaultValue.RY);
            w.Write(defaultValue.RZ);
            w.Write(defaultValue.RW);
            w.Write(defaultValue.X);
            w.Write(defaultValue.Y);
            w.Write(defaultValue.Z);
            w.Write(0);

            // write compressed values
            BitWriter writer = new BitWriter();

            foreach (AnimTrackTransform transform in values)
            {
                if (hasScale)
                {
                    writer.WriteBits(SX.GetQuantanizedValue(transform.SX), SX.GetBitCount(Epsilon));
                    writer.WriteBits(SY.GetQuantanizedValue(transform.SY), SY.GetBitCount(Epsilon));
                    writer.WriteBits(SZ.GetQuantanizedValue(transform.SZ), SZ.GetBitCount(Epsilon));
                }
                if (hasRotation)
                {
                    writer.WriteBits(RX.GetQuantanizedValue(transform.RX), RX.GetBitCount(Epsilon));
                    writer.WriteBits(RY.GetQuantanizedValue(transform.RY), RY.GetBitCount(Epsilon));
                    writer.WriteBits(RZ.GetQuantanizedValue(transform.RZ), RZ.GetBitCount(Epsilon));
                }
                if (hasPosition)
                {
                    writer.WriteBits(X.GetQuantanizedValue(transform.X), X.GetBitCount(Epsilon));
                    writer.WriteBits(Y.GetQuantanizedValue(transform.Y), Y.GetBitCount(Epsilon));
                    writer.WriteBits(Z.GetQuantanizedValue(transform.Z), Z.GetBitCount(Epsilon));
                }
                if (hasRotation)
                {
                    // flip w bit

                    float calculateW = (float)Math.Sqrt(Math.Abs(1 - (
                                                                     RX.DecompressedValue(transform.RX) * RX.DecompressedValue(transform.RX) +
                                                                     RY.DecompressedValue(transform.RY) * RY.DecompressedValue(transform.RY) +
                                                                     RZ.DecompressedValue(transform.RZ) * RZ.DecompressedValue(transform.RZ))));

                    writer.WriteBits(Math.Sign((int)transform.RW) != Math.Sign((int)calculateW) ? 1 : 0, 1);
                }
            }

            w.Write(writer.GetBytes());
        }
        /// <summary>
        /// Compresses <see cref="AnimTrackTransform"></see> track and writes to writer
        /// </summary>
        /// <param name="w"></param>
        /// <param name="values"></param>
        private void CompressTransformTracks(BinaryWriter w, IList <object> values)
        {
            Quantanizer sx = new Quantanizer();
            Quantanizer sy = new Quantanizer();
            Quantanizer sz = new Quantanizer();
            Quantanizer rx = new Quantanizer();
            Quantanizer ry = new Quantanizer();
            Quantanizer rz = new Quantanizer();
            Quantanizer x  = new Quantanizer();
            Quantanizer y  = new Quantanizer();
            Quantanizer z  = new Quantanizer();

            // pre-process
            foreach (AnimTrackTransform transform in values)
            {
                sx.Add(transform.Sx);
                sy.Add(transform.Sy);
                sz.Add(transform.Sz);
                rx.Add(transform.Rx);
                ry.Add(transform.Ry);
                rz.Add(transform.Rz);
                x.Add(transform.X);
                y.Add(transform.Y);
                z.Add(transform.Z);
            }

            short  flags        = 0;
            ushort bitsPerEntry = 0;

            bool hasScale    = (!sx.Constant || !sy.Constant || !sz.Constant);
            bool hasRotation = (!rx.Constant || !ry.Constant || !rz.Constant);
            bool hasPosition = (!x.Constant || !y.Constant || !z.Constant);

            if (sx.GetBitCount(epsilon) == -1 || sy.GetBitCount(epsilon) == -1 || (sz.GetBitCount(epsilon) == -1 || rx.GetBitCount(epsilon) == -1) || (ry.GetBitCount(epsilon) == -1 || rz.GetBitCount(epsilon) == -1 || (x.GetBitCount(epsilon) == -1 || y.GetBitCount(epsilon) == -1)) || z.GetBitCount(epsilon) == -1)
            {
                throw new Exception("Compression Level is too small to compress!");
            }

            if (!hasScale)
            {
                flags |= 0x02;
            }
            else
            {
                bitsPerEntry += (ushort)((sx.Constant ? 0 : sx.GetBitCount(epsilon)) + (sy.Constant ? 0 : sy.GetBitCount(epsilon)) + (sz.Constant ? 0 : sz.GetBitCount(epsilon)));
                flags        |= 0x01;
            }
            if (hasRotation)
            {
                bitsPerEntry += (ushort)((rx.Constant ? 0 : rx.GetBitCount(epsilon)) + (ry.Constant ? 0 : ry.GetBitCount(epsilon)) + (rz.Constant ? 0 : rz.GetBitCount(epsilon)) + 1); // the 1 is for extra w rotation bit
                flags        |= 0x04;
            }
            if (hasPosition)
            {
                bitsPerEntry += (ushort)((x.Constant ? 0 : x.GetBitCount(epsilon)) + (y.Constant ? 0 : y.GetBitCount(epsilon)) + (z.Constant ? 0 : z.GetBitCount(epsilon)));
                flags        |= 0x08;
            }

            // Compressed Header
            w.Write((short)0x04);
            w.Write(flags);
            w.Write((short)160);
            w.Write(bitsPerEntry);
            w.Write(204);
            w.Write(values.Count);
            w.Write(sx.Min);
            w.Write(sx.Max);
            w.Write(hasScale ? sx.GetBitCount(epsilon) : 16L);
            w.Write(sy.Min);
            w.Write(sy.Max);
            w.Write(hasScale ? sy.GetBitCount(epsilon) : 16L);
            w.Write(sz.Min);
            w.Write(sz.Max);
            w.Write(hasScale ? sz.GetBitCount(epsilon) : 16L);
            w.Write(rx.Min);
            w.Write(rx.Max);
            w.Write(hasRotation ? rx.GetBitCount(epsilon) : 16L);
            w.Write(ry.Min);
            w.Write(ry.Max);
            w.Write(hasRotation ? ry.GetBitCount(epsilon) : 16L);
            w.Write(rz.Min);
            w.Write(rz.Max);
            w.Write(hasRotation ? rz.GetBitCount(epsilon) : 16L);
            w.Write(x.Min);
            w.Write(x.Max);
            w.Write(hasPosition ? x.GetBitCount(epsilon) : 16L);
            w.Write(y.Min);
            w.Write(y.Max);
            w.Write(hasPosition ? y.GetBitCount(epsilon) : 16L);
            w.Write(z.Min);
            w.Write(z.Max);
            w.Write(hasPosition ? z.GetBitCount(epsilon) : 16L);
            AnimTrackTransform defaultValue = (AnimTrackTransform)values[0];

            w.Write(defaultValue.Sx);
            w.Write(defaultValue.Sy);
            w.Write(defaultValue.Sz);
            w.Write(defaultValue.Rx);
            w.Write(defaultValue.Ry);
            w.Write(defaultValue.Rz);
            w.Write(defaultValue.Rw);
            w.Write(defaultValue.X);
            w.Write(defaultValue.Y);
            w.Write(defaultValue.Z);
            w.Write(0);

            // write compressed values
            BitWriter writer = new BitWriter();

            foreach (AnimTrackTransform transform in values)
            {
                if (hasScale)
                {
                    writer.WriteBits(sx.GetQuantanizedValue(transform.Sx), sx.GetBitCount(epsilon));
                    writer.WriteBits(sy.GetQuantanizedValue(transform.Sy), sy.GetBitCount(epsilon));
                    writer.WriteBits(sz.GetQuantanizedValue(transform.Sz), sz.GetBitCount(epsilon));
                }
                if (hasRotation)
                {
                    writer.WriteBits(rx.GetQuantanizedValue(transform.Rx), rx.GetBitCount(epsilon));
                    writer.WriteBits(ry.GetQuantanizedValue(transform.Ry), ry.GetBitCount(epsilon));
                    writer.WriteBits(rz.GetQuantanizedValue(transform.Rz), rz.GetBitCount(epsilon));
                }
                if (hasPosition)
                {
                    writer.WriteBits(x.GetQuantanizedValue(transform.X), x.GetBitCount(epsilon));
                    writer.WriteBits(y.GetQuantanizedValue(transform.Y), y.GetBitCount(epsilon));
                    writer.WriteBits(z.GetQuantanizedValue(transform.Z), z.GetBitCount(epsilon));
                }
                if (hasRotation)
                {
                    // flip w bit

                    float calculateW = (float)Math.Sqrt(Math.Abs(1 - (
                                                                     rx.DecompressedValue(transform.Rx) * rx.DecompressedValue(transform.Rx) +
                                                                     ry.DecompressedValue(transform.Ry) * ry.DecompressedValue(transform.Ry) +
                                                                     rz.DecompressedValue(transform.Rz) * rz.DecompressedValue(transform.Rz))));

                    writer.WriteBits(Math.Sign(transform.Rw) != Math.Sign(calculateW) ? 1 : 0, 1);
                }
            }

            w.Write(writer.GetBytes());
        }
Example #4
0
        /// <summary>
        /// Compresses <see cref="AnimTrackTransform"></see> track and writes to writer
        /// </summary>
        /// <param name="w"></param>
        /// <param name="values"></param>
        private void CompressTransformTracks(BinaryWriter w, IList <object> values)
        {
            Quantanizer sx = new Quantanizer();
            Quantanizer sy = new Quantanizer();
            Quantanizer sz = new Quantanizer();
            Quantanizer rx = new Quantanizer();
            Quantanizer ry = new Quantanizer();
            Quantanizer rz = new Quantanizer();
            Quantanizer x  = new Quantanizer();
            Quantanizer y  = new Quantanizer();
            Quantanizer z  = new Quantanizer();

            // pre-process
            foreach (AnimTrackTransform transform in values)
            {
                sx.Add(transform.Sx);
                sy.Add(transform.Sy);
                sz.Add(transform.Sz);
                rx.Add(transform.Rx);
                ry.Add(transform.Ry);
                rz.Add(transform.Rz);
                x.Add(transform.X);
                y.Add(transform.Y);
                z.Add(transform.Z);
            }

            short  flags        = 0;
            ushort bitsPerEntry = 0;

            bool hasScale    = (!sx.Constant || !sy.Constant || !sz.Constant);
            bool hasRotation = (!rx.Constant || !ry.Constant || !rz.Constant);
            bool hasPosition = (!x.Constant || !y.Constant || !z.Constant);


            if (!hasScale)
            {
                flags |= 0x02;
            }
            else
            {
                bitsPerEntry += (ushort)((sx.Constant ? 0 : sx.GetBitCount(epsilon)) + (sy.Constant ? 0 : sy.GetBitCount(epsilon)) + (sz.Constant ? 0 : sz.GetBitCount(epsilon)));
                flags        |= 0x01;
            }
            if (hasRotation)
            {
                bitsPerEntry += (ushort)((rx.Constant ? 0 : rx.GetBitCount(epsilon)) + (ry.Constant ? 0 : ry.GetBitCount(epsilon)) + (rz.Constant ? 0 : rz.GetBitCount(epsilon)) + 1); // the 1 is for extra w rotation bit
                flags        |= 0x04;
            }
            if (hasPosition)
            {
                bitsPerEntry += (ushort)((x.Constant ? 0 : x.GetBitCount(epsilon)) + (y.Constant ? 0 : y.GetBitCount(epsilon)) + (z.Constant ? 0 : z.GetBitCount(epsilon)));
                flags        |= 0x08;
            }

            // Compressed Header
            w.Write((short)0x04);
            w.Write(flags);
            w.Write((short)(0x10 + 0x10 * 9));             // default values offset
            w.Write(bitsPerEntry);
            w.Write(0x10 + 0x10 * 9 + sizeof(float) * 11); // compressed data start
            w.Write(values.Count);                         // frame count

            // write chunks
            w.Write(sx.Min); w.Write(sx.Max); w.Write((long)sx.GetBitCount(epsilon));
            w.Write(sy.Min); w.Write(sy.Max); w.Write((long)sy.GetBitCount(epsilon));
            w.Write(sz.Min); w.Write(sz.Max); w.Write((long)sz.GetBitCount(epsilon));
            w.Write(rx.Min); w.Write(rx.Max); w.Write((long)rx.GetBitCount(epsilon));
            w.Write(ry.Min); w.Write(ry.Max); w.Write((long)ry.GetBitCount(epsilon));
            w.Write(rz.Min); w.Write(rz.Max); w.Write((long)rz.GetBitCount(epsilon));
            w.Write(x.Min); w.Write(x.Max); w.Write((long)x.GetBitCount(epsilon));
            w.Write(y.Min); w.Write(y.Max); w.Write((long)y.GetBitCount(epsilon));
            w.Write(z.Min); w.Write(z.Max); w.Write((long)z.GetBitCount(epsilon));

            // write default values
            AnimTrackTransform defaultValue = (AnimTrackTransform)values[0];

            w.Write(defaultValue.Sx);
            w.Write(defaultValue.Sy);
            w.Write(defaultValue.Sz);
            w.Write(defaultValue.Rx);
            w.Write(defaultValue.Ry);
            w.Write(defaultValue.Rz);
            w.Write(defaultValue.Rw);
            w.Write(defaultValue.X);
            w.Write(defaultValue.Y);
            w.Write(defaultValue.Z);
            w.Write(0);

            // write compressed values
            BitWriter writer = new BitWriter();

            foreach (AnimTrackTransform transform in values)
            {
                if (hasScale)
                {
                    writer.WriteBits(sx.GetQuantanizedValue(transform.Sx), sx.GetBitCount(epsilon));
                    writer.WriteBits(sy.GetQuantanizedValue(transform.Sy), sy.GetBitCount(epsilon));
                    writer.WriteBits(sz.GetQuantanizedValue(transform.Sz), sz.GetBitCount(epsilon));
                }
                if (hasRotation)
                {
                    writer.WriteBits(rx.GetQuantanizedValue(transform.Rx), rx.GetBitCount(epsilon));
                    writer.WriteBits(ry.GetQuantanizedValue(transform.Ry), ry.GetBitCount(epsilon));
                    writer.WriteBits(rz.GetQuantanizedValue(transform.Rz), rz.GetBitCount(epsilon));
                }
                if (hasPosition)
                {
                    writer.WriteBits(x.GetQuantanizedValue(transform.X), x.GetBitCount(epsilon));
                    writer.WriteBits(y.GetQuantanizedValue(transform.Y), y.GetBitCount(epsilon));
                    writer.WriteBits(z.GetQuantanizedValue(transform.Z), z.GetBitCount(epsilon));
                }
                if (hasRotation)
                {
                    // flip w bit

                    float calculateW = (float)Math.Sqrt(Math.Abs(1 - (
                                                                     rx.DecompressedValue(transform.Rx) * rx.DecompressedValue(transform.Rx) +
                                                                     ry.DecompressedValue(transform.Ry) * ry.DecompressedValue(transform.Ry) +
                                                                     rz.DecompressedValue(transform.Rz) * rz.DecompressedValue(transform.Rz))));

                    writer.WriteBits(Math.Sign((int)transform.Rw) != Math.Sign((int)calculateW) ? 1 : 0, 1);
                }
            }

            w.Write(writer.GetBytes());
        }