Exemplo n.º 1
0
        private static float[] GetDefaultValues(SSBHParser parser, int valueCount)
        {
            float[] defaultValues = new float[valueCount];
            for (int i = 0; i < valueCount; i++)
            {
                defaultValues[i] = parser.ReadSingle();
            }

            return(defaultValues);
        }
Exemplo n.º 2
0
        public override void PostProcess(SSBHParser R)
        {
            R.Seek(OffsetToData);

            if (DataType == MatlEnums.ParamDataType.Float)
            {
                DataObject = R.ReadSingle();
            }
            else if (DataType == MatlEnums.ParamDataType.Boolean)
            {
                DataObject = R.ReadUInt32() == 1;
            }
            else if (DataType == MatlEnums.ParamDataType.Vector4)
            {
                DataObject = R.Parse <MatlVector4>();
            }
            else if (DataType == MatlEnums.ParamDataType.String)
            {
                DataObject = R.Parse <MtalString>();
            }
            else if (DataType == MatlEnums.ParamDataType.Sampler)
            {
                DataObject = R.Parse <MtalSampler>();
            }
            else if (DataType == MatlEnums.ParamDataType.UvTransform)
            {
                DataObject = R.Parse <MTAL_UVTransform>();
            }
            else if (DataType == MatlEnums.ParamDataType.BlendState)
            {
                DataObject = R.Parse <MatlBlendState>();
            }
            else if (DataType == MatlEnums.ParamDataType.RasterizerState)
            {
                DataObject = R.Parse <MatlRasterizerState>();
            }
        }
Exemplo n.º 3
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.º 4
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);
        }
Exemplo n.º 5
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());
        }