Exemplo n.º 1
0
        /// <summary>
        /// Reads direct information from track
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        private object ReadDirect(SSBHParser reader, uint flags)
        {
            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Transform))
            {
                var Transform = new AnimTrackTransform()
                {
                    SX = reader.ReadSingle(),
                    SY = reader.ReadSingle(),
                    SZ = reader.ReadSingle(),
                    RX = reader.ReadSingle(),
                    RY = reader.ReadSingle(),
                    RZ = reader.ReadSingle(),
                    RW = reader.ReadSingle(),
                    X  = reader.ReadSingle(),
                    Y  = reader.ReadSingle(),
                    Z  = reader.ReadSingle(),
                    CompensateScale = reader.ReadInt32()
                };

                return(Transform);
            }

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Texture))
            {
                return(new AnimTrackTexture()
                {
                    UnkFloat1 = reader.ReadSingle(),
                    UnkFloat2 = reader.ReadSingle(),
                    UnkFloat3 = reader.ReadSingle(),
                    UnkFloat4 = reader.ReadSingle(),
                    Unknown = reader.ReadInt32()
                });
            }

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Float))
            {
                return(reader.ReadSingle());
            }

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.PatternIndex))
            {
                return(reader.ReadInt32());
            }

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Boolean))
            {
                return(reader.ReadByte() == 1);
            }

            if (CheckFlag(flags, 0x00FF, ANIM_TRACKFLAGS.Vector4))
            {
                return(new AnimTrackCustomVector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
            }

            return(null);
        }
Exemplo n.º 2
0
        public object[] ReadTrack(AnimTrack Track)
        {
            Console.WriteLine(Track.Name + " " + Track.Flags.ToString() + " " + Track.FrameCount + " " + Track.DataOffset.ToString("X"));
            List <object> output = new List <object>();

            using (SSBHParser parser = new SSBHParser(new MemoryStream(AnimFile.Buffer)))
            {
                parser.Seek(Track.DataOffset);

                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Boolean))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            output.Add(new AnimTrackBool(parser.ReadBits(1) == 1));
                        }
                    }
                    else
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Constant))
                    {
                        output.Add(new AnimTrackBool(parser.ReadBits(1) == 1));
                    }
                }
                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Vector4))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        int[]   ByteCounts = new int[9];
                        int[]   BitCounts  = new int[9];
                        float[] Start      = new float[9];
                        float[] End        = new float[9];
                        for (int i = 0; i < 4; i++)
                        {
                            Start[i] = parser.ReadSingle();
                            End[i]   = parser.ReadSingle();
                            long Count = parser.ReadInt64();
                            long bytes = (Count >> 3);
                            int  bits  = ((int)Count & 0x7);

                            if ((i >= 0 && i <= 0 && (TrackFlag & 0x3) == 0x3) || //isotrophic scale
                                (i >= 0 && i <= 2 && (TrackFlag & 0x3) == 0x1) || //normal scale
                                (i > 2 && i <= 5 && (TrackFlag & 0x4) > 0) ||
                                (i > 5 && i <= 8 && (TrackFlag & 0x8) > 0))
                            {
                                //reads
                                {
                                    BitCounts[i]  = bits;
                                    ByteCounts[i] = (int)bytes;
                                }
                            }
                        }

                        float X = parser.ReadSingle();
                        float Y = parser.ReadSingle();
                        float Z = parser.ReadSingle();
                        float W = parser.ReadSingle();

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            AnimTrackCustomVector4 Vector = new AnimTrackCustomVector4();
                            for (int j = 0; j < 4; j++)
                            {
                                int ValueBitCount = ByteCounts[j] * 8 + BitCounts[j];
                                int Value         = parser.ReadBits(ValueBitCount);
                                int scale         = 0;
                                for (int k = 0; k < ValueBitCount; k++)
                                {
                                    scale |= 0x1 << k;
                                }

                                float FrameValue = Lerp(Start[j], End[j], 0, 1, Value / (float)scale);
                                if (float.IsNaN(FrameValue))
                                {
                                    FrameValue = 0;
                                }

                                switch (j)
                                {
                                case 0: if (ValueBitCount > 0)
                                    {
                                        Vector.X = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.X = X;
                                    } break;

                                case 1: if (ValueBitCount > 0)
                                    {
                                        Vector.Y = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.Y = Y;
                                    } break;

                                case 2: if (ValueBitCount > 0)
                                    {
                                        Vector.Z = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.Z = Z;
                                    } break;

                                case 3: if (ValueBitCount > 0)
                                    {
                                        Vector.W = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.W = W;
                                    } break;
                                }
                            }

                            output.Add(Vector);
                        }
                    }
                    else
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Constant))
                    {
                        output.Add(new AnimTrackCustomVector4()
                        {
                            X = parser.ReadSingle(),
                            Y = parser.ReadSingle(),
                            Z = parser.ReadSingle(),
                            W = parser.ReadSingle()
                        });
                    }
                }
                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Transform))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        int[]   ByteCounts = new int[9];
                        int[]   BitCounts  = new int[9];
                        float[] Start      = new float[9];
                        float[] End        = new float[9];
                        for (int i = 0; i < 9; i++)
                        {
                            Start[i] = parser.ReadSingle();
                            End[i]   = parser.ReadSingle();
                            long Count = parser.ReadInt64();
                            long bytes = (Count >> 3);
                            int  bits  = ((int)Count & 0x7);

                            if ((i >= 0 && i <= 0 && (TrackFlag & 0x3) == 0x3) || //isotrophic scale
                                (i >= 0 && i <= 2 && (TrackFlag & 0x3) == 0x1) || //normal scale
                                (i > 2 && i <= 5 && (TrackFlag & 0x4) > 0) ||
                                (i > 5 && i <= 8 && (TrackFlag & 0x8) > 0))
                            {
                                //reads
                                {
                                    BitCounts[i]  = bits;
                                    ByteCounts[i] = (int)bytes;
                                }
                            }
                        }

                        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();

                        parser.ReadInt32(); // ????

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            AnimTrackTransform Transform = new AnimTrackTransform();
                            for (int j = 0; j < 9; j++)
                            {
                                int ValueBitCount = ByteCounts[j] * 8 + BitCounts[j];
                                int Value         = parser.ReadBits(ValueBitCount);
                                int scale         = 0;
                                for (int k = 0; k < ValueBitCount; k++)
                                {
                                    scale |= 0x1 << k;
                                }

                                float FrameValue = Lerp(Start[j], End[j], 0, 1, Value / (float)scale);
                                if (float.IsNaN(FrameValue))
                                {
                                    FrameValue = 0;
                                }

                                if ((TrackFlag & 0x3) == 0x3)
                                {
                                    //Scale Isotropic
                                    if (j == 0)
                                    {
                                        Transform.SX = FrameValue;
                                        Transform.SY = FrameValue;
                                        Transform.SZ = FrameValue;
                                    }
                                }
                                else if ((TrackFlag & 0x3) == 0x1)
                                {
                                    //Scale normal
                                    switch (j)
                                    {
                                    case 0:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SX = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SX = XSCA;
                                        }
                                        break;

                                    case 1:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SY = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SY = YSCA;
                                        }
                                        break;

                                    case 2:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SZ = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SZ = ZSCA;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.SX = XSCA;
                                    Transform.SY = YSCA;
                                    Transform.SZ = ZSCA;
                                }

                                //Rotation
                                if ((TrackFlag & 0x4) > 0)
                                {
                                    switch (j)
                                    {
                                    case 3:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RX = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RX = XROT;
                                        }
                                        break;

                                    case 4:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RY = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RY = YROT;
                                        }
                                        break;

                                    case 5:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RZ = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RZ = ZROT;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.RX = XROT;
                                    Transform.RY = YROT;
                                    Transform.RZ = ZROT;
                                    Transform.RW = WROT;
                                }

                                // Position
                                if ((TrackFlag & 0x8) > 0)
                                {
                                    switch (j)
                                    {
                                    case 6:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.X = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.X = XPOS;
                                        }
                                        break;

                                    case 7:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.Y = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.Y = YPOS;
                                        }
                                        break;

                                    case 8:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.Z = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.Z = ZPOS;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.X = XPOS;
                                    Transform.Y = YPOS;
                                    Transform.Z = ZPOS;
                                }
                            }
                            if ((TrackFlag & 0x4) > 0)
                            {
                                // Rotation w
                                bool Wflip = parser.ReadBits(1) == 1;// (TrackFlag & 0x1) == 0 ? parser.ReadBits(1) == 1 : true;

                                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;
                                }
                            }

                            output.Add(Transform);
                        }
                    }
                    else if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.ConstTransform))
                    {
                        output.Add(new AnimTrackTransform()
                        {
                            SX = parser.ReadSingle(),
                            SY = parser.ReadSingle(),
                            SZ = parser.ReadSingle(),
                            RX = parser.ReadSingle(),
                            RY = parser.ReadSingle(),
                            RZ = parser.ReadSingle(),
                            RW = parser.ReadSingle(),
                            X  = parser.ReadSingle(),
                            Y  = parser.ReadSingle(),
                            Z  = parser.ReadSingle(),
                        });

                        parser.ReadInt32(); // ????
                    }
                }
            }

            return(output.ToArray());
        }