Exemplo n.º 1
0
        /// <summary>
        /// Reads the data from a compressed track
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        private object[] ReadCompressed(SSBHParser reader, uint flags)
        {
            List <object> output = new List <object>();

            uint dataOffset = (uint)reader.BaseStream.Position;
            SSBHAnimCompressedHeader header = reader.ByteToType <SSBHAnimCompressedHeader>();

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Boolean))
            {
                ReadBooleans(reader, output, dataOffset, header);
            }
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Texture))
            {
                // TODO: What type is this
            }
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Float))
            {
                //TODO: What type is this
            }
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.PatternIndex))
            {
                //TODO: What type is this
            }
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Vector4))
            {
                ReadVector4(reader, output, dataOffset, header);
            }
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Transform))
            {
                ReadTransform(reader, output, dataOffset, header);
            }

            return(output.ToArray());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Decompresses values in a track
        /// </summary>
        /// <param name="parser"></param>
        /// <param name="dataOffset"></param>
        /// <param name="header"></param>
        /// <param name="valueCount"></param>
        /// <returns></returns>
        private List <float[]> DecompressValues(SSBHParser parser, uint dataOffset, SSBHAnimCompressedHeader header, int valueCount)
        {
            List <float[]> transforms = new List <float[]>(header.FrameCount);

            // PreProcess
            SSBHAnimCompressedItem[] items = parser.ByteToType <SSBHAnimCompressedItem>(valueCount);

            parser.Seek(dataOffset + header.DefaultDataOffset);

            float[] defaultValues = GetDefaultValues(parser, valueCount);

            parser.Seek(dataOffset + header.CompressedDataOffset);
            for (int frameIndex = 0; frameIndex < header.FrameCount; frameIndex++)
            {
                // Copy default values.
                float[] values = new float[valueCount];
                for (int i = 0; i < valueCount; i++)
                {
                    values[i] = defaultValues[i];
                }

                for (int itemIndex = 0; itemIndex < items.Length; itemIndex++)
                {
                    var item = items[itemIndex];

                    // Decompress
                    int valueBitCount = (int)item.Count;
                    if (valueBitCount == 0)
                    {
                        continue;
                    }

                    int value = parser.ReadBits(valueBitCount);
                    int scale = 0;
                    for (int k = 0; k < valueBitCount; k++)
                    {
                        scale |= 0x1 << k;
                    }

                    float frameValue = Lerp(item.Start, item.End, 0, 1, value / (float)scale);
                    if (float.IsNaN(frameValue))
                    {
                        frameValue = 0;
                    }

                    values[itemIndex] = frameValue;
                }

                transforms.Add(values);
            }

            return(transforms);
        }
Exemplo n.º 3
0
        /// <summary>
        /// decompresses transform values from a track
        /// </summary>
        /// <param name="parser"></param>
        /// <param name="dataOffset"></param>
        /// <param name="header"></param>
        /// <returns></returns>
        private AnimTrackTransform[] DecompressTransform(SSBHParser parser, uint dataOffset, SSBHAnimCompressedHeader header)
        {
            AnimTrackTransform[] transforms = new AnimTrackTransform[header.FrameCount];

            // PreProcess
            SSBHAnimCompressedItem[] items = parser.ByteToType <SSBHAnimCompressedItem>(9);

            parser.Seek(dataOffset + header.DefaultDataOffset);

            float XSCA = parser.ReadSingle();
            float YSCA = parser.ReadSingle();
            float ZSCA = parser.ReadSingle();
            float XROT = parser.ReadSingle();
            float YROT = parser.ReadSingle();
            float ZROT = parser.ReadSingle();
            float WROT = parser.ReadSingle();
            float XPOS = parser.ReadSingle();
            float YPOS = parser.ReadSingle();
            float ZPOS = parser.ReadSingle();
            float CSCA = parser.ReadSingle();

            parser.Seek(dataOffset + header.CompressedDataOffset);
            for (int frame = 0; frame < header.FrameCount; frame++)
            {
                AnimTrackTransform transform = new AnimTrackTransform()
                {
                    X  = XPOS,
                    Y  = YPOS,
                    Z  = ZPOS,
                    RX = XROT,
                    RY = YROT,
                    RZ = ZROT,
                    RW = WROT,
                    SX = XSCA,
                    SY = YSCA,
                    SZ = ZSCA,
                    CompensateScale = CSCA
                };
                for (int itemIndex = 0; itemIndex < items.Length; itemIndex++)
                {
                    // First check if this track should be parsed
                    // TODO: Don't hard code these flags.
                    if (!((itemIndex == 0 && (header.Flags & 0x3) == 0x3) || //isotropic scale
                          (itemIndex >= 0 && itemIndex <= 2 && (header.Flags & 0x3) == 0x1) ||       //normal scale
                          (itemIndex > 2 && itemIndex <= 5 && (header.Flags & 0x4) > 0) ||
                          (itemIndex > 5 && itemIndex <= 8 && (header.Flags & 0x8) > 0)))
                    {
                        continue;
                    }

                    var item = items[itemIndex];

                    // Decompress
                    int valueBitCount = (int)item.Count;
                    if (valueBitCount == 0)
                    {
                        continue;
                    }

                    int value = parser.ReadBits(valueBitCount);
                    int scale = 0;
                    for (int k = 0; k < valueBitCount; k++)
                    {
                        scale |= 0x1 << k;
                    }

                    float frameValue = Lerp(item.Start, item.End, 0, 1, value / (float)scale);
                    if (float.IsNaN(frameValue))
                    {
                        frameValue = 0;
                    }

                    // the Transform type relies a lot on flags

                    if ((header.Flags & 0x3) == 0x3)
                    {
                        //Scale Compensate
                        if (itemIndex == 0)
                        {
                            transform.CompensateScale = frameValue;
                        }
                    }
                    if ((header.Flags & 0x3) == 0x1)
                    {
                        //Scale normal
                        switch (itemIndex)
                        {
                        case 0:
                            transform.SX = frameValue;
                            break;

                        case 1:
                            transform.SY = frameValue;
                            break;

                        case 2:
                            transform.SZ = frameValue;
                            break;
                        }
                    }
                    //Rotation and Position
                    switch (itemIndex)
                    {
                    case 3:
                        transform.RX = frameValue;
                        break;

                    case 4:
                        transform.RY = frameValue;
                        break;

                    case 5:
                        transform.RZ = frameValue;
                        break;

                    case 6:
                        transform.X = frameValue;
                        break;

                    case 7:
                        transform.Y = frameValue;
                        break;

                    case 8:
                        transform.Z = frameValue;
                        break;
                    }
                }

                // Rotations have an extra bit at the end
                if ((header.Flags & 0x4) > 0)
                {
                    bool wFlip = parser.ReadBits(1) == 1;

                    // W is calculated
                    transform.RW = (float)Math.Sqrt(Math.Abs(1 - (transform.RX * transform.RX + transform.RY * transform.RY + transform.RZ * transform.RZ)));

                    if (wFlip)
                    {
                        transform.RW = -transform.RW;
                    }
                }

                transforms[frame] = transform;
            }

            return(transforms);
        }