예제 #1
0
        public static H3D OpenAsH3D(Stream Input, GFPackage.Header Header, H3DDict <H3DBone> Skeleton = null)
        {
            H3D Output = default(H3D);

            BinaryReader Reader = new BinaryReader(Input);

            Input.Seek(Header.Entries[0].Address, SeekOrigin.Begin);

            uint MagicNum = Reader.ReadUInt32();

            switch (MagicNum)
            {
            case GFModelConstant:
                GFModelPack MdlPack = new GFModelPack();

                //High Poly Pokémon model
                Input.Seek(Header.Entries[0].Address, SeekOrigin.Begin);

                MdlPack.Models.Add(new GFModel(Reader, "PM_HighPoly"));

                //Low Poly Pokémon model
                Input.Seek(Header.Entries[1].Address, SeekOrigin.Begin);

                MdlPack.Models.Add(new GFModel(Reader, "PM_LowPoly"));

                //Pokémon Shader package
                Input.Seek(Header.Entries[2].Address, SeekOrigin.Begin);

                GFPackage.Header PSHeader = GFPackage.GetPackageHeader(Input);

                foreach (GFPackage.Entry Entry in PSHeader.Entries)
                {
                    Input.Seek(Entry.Address, SeekOrigin.Begin);

                    GFShader sh = new GFShader(Reader);

                    MdlPack.AddShader(sh);
                }

                //More shaders
                Input.Seek(Header.Entries[3].Address, SeekOrigin.Begin);

                if (GFPackage.IsValidPackage(Input))
                {
                    GFPackage.Header PCHeader = GFPackage.GetPackageHeader(Input);

                    foreach (GFPackage.Entry Entry in PCHeader.Entries)
                    {
                        Input.Seek(Entry.Address, SeekOrigin.Begin);

                        GFShader sh = new GFShader(Reader);

                        MdlPack.AddShader(sh);
                    }
                }

                Output = MdlPack.ToH3D();

                break;

            case GFTextureConstant:
                Output = new H3D();

                foreach (GFPackage.Entry Entry in Header.Entries)
                {
                    Input.Seek(Entry.Address, SeekOrigin.Begin);

                    Output.Textures.Add(new GFTexture(Reader).ToH3DTexture());
                }

                break;

            case GFMotionConstant:
                Output = new H3D();

                if (Skeleton == null)
                {
                    break;
                }

                for (int Index = 0; Index < Header.Entries.Length; Index++)
                {
                    Input.Seek(Header.Entries[Index].Address, SeekOrigin.Begin);

                    if (Input.Position + 4 > Input.Length)
                    {
                        break;
                    }
                    if (Reader.ReadUInt32() != GFMotionConstant)
                    {
                        continue;
                    }

                    Input.Seek(-4, SeekOrigin.Current);

                    GFMotion Mot = new GFMotion(Reader, Index);

                    H3DAnimation    SklAnim = Mot.ToH3DSkeletalAnimation(Skeleton);
                    H3DMaterialAnim MatAnim = Mot.ToH3DMaterialAnimation();
                    H3DAnimation    VisAnim = Mot.ToH3DVisibilityAnimation();

                    if (SklAnim != null)
                    {
                        SklAnim.Name = $"Motion_{Mot.Index}";

                        Output.SkeletalAnimations.Add(SklAnim);
                    }

                    if (MatAnim != null)
                    {
                        MatAnim.Name = $"Motion_{Mot.Index}";

                        Output.MaterialAnimations.Add(MatAnim);
                    }

                    if (VisAnim != null)
                    {
                        VisAnim.Name = $"Motion_{Mot.Index}";

                        Output.VisibilityAnimations.Add(VisAnim);
                    }
                }

                break;

            case BCHConstant:
                Output = new H3D();

                foreach (GFPackage.Entry Entry in Header.Entries)
                {
                    Input.Seek(Entry.Address, SeekOrigin.Begin);

                    MagicNum = Reader.ReadUInt32();

                    if (MagicNum != BCHConstant)
                    {
                        continue;
                    }

                    Input.Seek(-4, SeekOrigin.Current);

                    byte[] Buffer = Reader.ReadBytes(Entry.Length);

                    Output.Merge(H3D.Open(Buffer));
                }

                break;
            }

            return(Output);
        }
예제 #2
0
        public static H3D IdentifyAndOpen(string FileName, H3DDict <H3DBone> Skeleton = null)
        {
            //Formats that can by identified by extensions
            string FilePath = Path.GetDirectoryName(FileName);

            switch (Path.GetExtension(FileName).ToLower())
            {
            case ".txt":
                H3D AllFiles = new H3D();

                string[] files = File.ReadAllLines(FileName);

                string Parent = FilePath;

                foreach (string File in files)
                {
                    AllFiles.Merge(IdentifyAndOpen(Path.Combine(Parent, File)));
                }

                return(AllFiles);

            case ".gmp":
                GF1MotionPack MotPack = new GF1MotionPack(new BinaryReader(new FileStream(FileName, FileMode.Open)));
                return(MotPack.ToH3D(Skeleton));

            case ".smd": return(new SMD(FileName).ToH3D(FilePath));

            case ".obj": return(new OBJ(FileName).ToH3D(FilePath));

            case ".mtl": return(new OBJ(FileName).ToH3D(FilePath));

            case ".cmif": return(new CMIFFile(new FileStream(FileName, FileMode.Open)).ToH3D());

            case ".png":
                H3D Out = new H3D();
                Out.Textures.Add(new H3DTexture(FileName, true));
                return(Out);

            case ".gfbmdl":
                return(new GFModel(new BinaryReader(new FileStream(FileName, FileMode.Open)), Path.GetFileNameWithoutExtension(FileName)).ToH3D());

            case ".mbn":
                using (FileStream Input = new FileStream(FileName, FileMode.Open))
                {
                    H3D BaseScene = H3D.Open(File.ReadAllBytes(FileName.Replace(".mbn", ".bch")));

                    MBn ModelBinary = new MBn(new BinaryReader(Input), BaseScene);

                    return(ModelBinary.ToH3D());
                }
            }

            //Formats that can only be indetified by "magic numbers"
            H3D Output = null;

            using (FileStream FS = new FileStream(FileName, FileMode.Open))
            {
                Output = IdentifyByMagic(FS, Skeleton, FileName);
            }

            return(Output);
        }
예제 #3
0
        public static H3D IdentifyByMagic(Stream Stream, H3DDict <H3DBone> Skeleton, string FileName)
        {
            H3D Output = null;

            if (Stream.Length > 4)
            {
                BinaryReader Reader = new BinaryReader(Stream);

                uint MagicNum = Reader.ReadUInt32();

                Stream.Seek(-4, SeekOrigin.Current);

                string Magic = Encoding.ASCII.GetString(Reader.ReadBytes(4));

                Stream.Seek(0, SeekOrigin.Begin);

                if (Magic.StartsWith("BCH"))
                {
                    return(H3D.Open(Reader.ReadBytes((int)Stream.Length)));
                }
                else if (Magic.StartsWith("MOD") && FileName != null)
                {
                    return(LoadMTModel(Reader, FileName, Path.GetDirectoryName(FileName)));
                }
                else if (Magic.StartsWith("TEX") && FileName != null)
                {
                    return(new MTTexture(Reader, Path.GetFileNameWithoutExtension(FileName)).ToH3D());
                }
                else if (Magic.StartsWith("MFX"))
                {
                    MTShader = new MTShaderEffects(Reader);
                }
                else if (Magic.StartsWith("CGFX"))
                {
                    return(Gfx.Open(Stream));
                }
                else if (Magic.StartsWith("CMIF"))
                {
                    return(new CMIFFile(Stream).ToH3D());
                }
                else
                {
                    switch (MagicNum)
                    {
                    case GFModel.MagicNum:
                        GFModel Model = new GFModel(Reader, "Model");
                        Output = Model.ToH3D();
                        Output.SourceData.Add(Model);

                        break;

                    case GFTexture.MagicNum:
                        //Can be GFShader or GFTexture
                        Reader.BaseStream.Seek(0x8, SeekOrigin.Current);

                        string GFMagicStr = StringUtils.ReadPaddedString(Reader, 8);

                        if (GFMagicStr == GFTexture.MagicStr)
                        {
                            Reader.BaseStream.Seek(-0x10, SeekOrigin.Current);
                            Output = new H3D();
                            Output.Textures.Add(new GFTexture(Reader).ToH3DTexture());
                        }
                        else
                        {
                            Reader.BaseStream.Seek(0x8, SeekOrigin.Current);
                            GFMagicStr = StringUtils.ReadPaddedString(Reader, 8);

                            if (GFMagicStr == GFShader.MagicStr)
                            {
                                Reader.BaseStream.Seek(-0x18, SeekOrigin.Current);
                                Output = new H3D();
                                Output.SourceData.Add(new GFShader(Reader));
                            }
                        }

                        break;

                    case GFModelPack.MagicNum:
                        if (GFModelPack.IsModelPack(Reader))
                        {
                            Output = new GFModelPack(Reader).ToH3D();
                        }
                        break;

                    case GFMotion.MagicNum:
                        if (Skeleton != null)
                        {
                            Output = new H3D();

                            GFMotion Motion = new GFMotion(Reader, 0);

                            H3DAnimation    SklAnim = Motion.ToH3DSkeletalAnimation(Skeleton);
                            H3DMaterialAnim MatAnim = Motion.ToH3DMaterialAnimation();
                            H3DAnimation    VisAnim = Motion.ToH3DVisibilityAnimation();

                            if (SklAnim != null)
                            {
                                Output.SkeletalAnimations.Add(SklAnim);
                            }
                            if (MatAnim != null)
                            {
                                Output.MaterialAnimations.Add(MatAnim);
                            }
                            if (VisAnim != null)
                            {
                                Output.VisibilityAnimations.Add(VisAnim);
                            }
                        }

                        break;
                    }

                    if (GFMotionPack.IsGFL2MotionPack(Reader))
                    {
                        GFMotionPack Pack = new GFMotionPack(Reader);
                        Output = Pack.ToH3D(Skeleton);
                    }
                    if (GF1MotionPack.IsGFL1MotionPack(Reader))
                    {
                        Output = new GF1MotionPack(Reader).ToH3D(Skeleton);
                    }
                }
            }

            return(Output);
        }
예제 #4
0
        public static H3D OpenAsH3D(Stream Input, GFPackage.Header Header, int FileIndex, int AnimCount, H3DDict <H3DBone> Skeleton = null)
        {
            int fileIndex = FileIndex;
            H3D Output    = default(H3D);

            BinaryReader Reader = new BinaryReader(Input);

            try
            {
                Input.Seek(Header.Entries[0].Address, SeekOrigin.Begin);

                uint MagicNum = Reader.ReadUInt32();

                switch (MagicNum)
                {
                case GFModelConstant:
                    GFModelPack MdlPack = new GFModelPack();

                    //High Poly Pokémon model
                    Input.Seek(Header.Entries[0].Address, SeekOrigin.Begin);

                    MdlPack.Models.Add(new GFModel(Reader, "PM_HighPoly"));

                    //Low Poly Pokémon model
                    Input.Seek(Header.Entries[1].Address, SeekOrigin.Begin);

                    MdlPack.Models.Add(new GFModel(Reader, "PM_LowPoly"));

                    //Pokémon Shader package
                    Input.Seek(Header.Entries[2].Address, SeekOrigin.Begin);

                    GFPackage.Header PSHeader = GFPackage.GetPackageHeader(Input);

                    foreach (GFPackage.Entry Entry in PSHeader.Entries)
                    {
                        Input.Seek(Entry.Address, SeekOrigin.Begin);

                        MdlPack.Shaders.Add(new GFShader(Reader));
                    }

                    //More shaders
                    Input.Seek(Header.Entries[3].Address, SeekOrigin.Begin);

                    if (GFPackage.IsValidPackage(Input))
                    {
                        GFPackage.Header PCHeader = GFPackage.GetPackageHeader(Input);

                        foreach (GFPackage.Entry Entry in PCHeader.Entries)
                        {
                            Input.Seek(Entry.Address, SeekOrigin.Begin);

                            MdlPack.Shaders.Add(new GFShader(Reader));
                        }
                    }

                    Output = MdlPack.ToH3D();

                    break;

                case GFTextureConstant:
                    Output = new H3D();

                    foreach (GFPackage.Entry Entry in Header.Entries)
                    {
                        Input.Seek(Entry.Address, SeekOrigin.Begin);

                        Output.Textures.Add(new GFTexture(Reader).ToH3DTexture());
                    }

                    break;

                case GFMotionConstant:
                    Output = new H3D();

                    if (Skeleton == null)
                    {
                        break;
                    }
                    HashSet <uint> sklAdresses        = new HashSet <uint>();
                    HashSet <uint> materialAdresses   = new HashSet <uint>();
                    HashSet <uint> visibilityAdresses = new HashSet <uint>();
                    for (int Index = 0; Index < Header.Entries.Length; Index++)
                    {
                        Input.Seek(Header.Entries[Index].Address, SeekOrigin.Begin);
                        if (Input.Position + 4 > Input.Length)
                        {
                            break;
                        }
                        if (Reader.ReadUInt32() != GFMotionConstant)
                        {
                            continue;
                        }

                        Input.Seek(-4, SeekOrigin.Current);

                        GFMotion Mot = new GFMotion(Reader, Index);

                        H3DAnimation    SklAnim = Mot.ToH3DSkeletalAnimation(Skeleton);
                        H3DMaterialAnim MatAnim = Mot.ToH3DMaterialAnimation();
                        H3DAnimation    VisAnim = Mot.ToH3DVisibilityAnimation();

                        if (SklAnim != null)
                        {
                            // SklAnim.Name = $"Motion_{Mot.Index}";

                            // Output.SkeletalAnimations.Add(SklAnim);

                            if (!sklAdresses.Contains(Header.Entries[Index].Address))
                            {
                                Output.SkeletalAnimations.Add(SklAnim);
                                sklAdresses.Add(Header.Entries[Index].Address);
                                Console.WriteLine("skeletal " + Header.Entries[Index].Address);
                            }
                        }

                        if (MatAnim != null)
                        {
                            //MatAnim.Name = $"Motion_{Mot.Index}";

                            if (!materialAdresses.Contains(Header.Entries[Index].Address))
                            {
                                Output.MaterialAnimations.Add(MatAnim);
                                materialAdresses.Add(Header.Entries[Index].Address);
                                Console.WriteLine("material " + Header.Entries[Index].Address);
                            }
                        }

                        if (VisAnim != null)
                        {
                            //VisAnim.Name = $"Motion_{Mot.Index}";

                            Output.VisibilityAnimations.Add(VisAnim);
                            if (!visibilityAdresses.Contains(Header.Entries[Index].Address))
                            {
                                Output.VisibilityAnimations.Add(VisAnim);
                                visibilityAdresses.Add(Header.Entries[Index].Address);
                                Console.WriteLine("visibility " + Header.Entries[Index].Address);
                            }
                        }
                    }
                    // Console.WriteLine(Output.SkeletalAnimations.Count);
                    // Console.WriteLine(AnimCount);
                    while (Output.SkeletalAnimations.Count > AnimCount)
                    {
                        Output.SkeletalAnimations.Remove(Output.SkeletalAnimations.Count - 1);
                    }
                    // if (fileIndex == 4)
                    // {
                    //
                    // }
                    //todo здесь проверку
                    // if (Output.SkeletalAnimations.Any())
                    // {
                    //     Output.SkeletalAnimations.Remove(Output.SkeletalAnimations.Count-1);
                    // }

                    break;

                case BCHConstant:
                    Output = new H3D();

                    foreach (GFPackage.Entry Entry in Header.Entries)
                    {
                        Input.Seek(Entry.Address, SeekOrigin.Begin);

                        MagicNum = Reader.ReadUInt32();

                        if (MagicNum != BCHConstant)
                        {
                            continue;
                        }

                        Input.Seek(-4, SeekOrigin.Current);

                        byte[] Buffer = Reader.ReadBytes(Entry.Length);

                        Output.Merge(H3D.Open(Buffer));
                    }

                    break;
                }

                return(Output);
            }
            catch (EndOfStreamException e)
            {
                return(new H3D());

                throw;
            }
        }
예제 #5
0
파일: Program.cs 프로젝트: Aqua-0/SPICA
        static void Main(string[] args)
        {
            List <string> argsList = new List <string>(args);

            if (args.Length > 0)
            {
                WorkMode mode = WorkMode.None;
                switch (args[0])
                {
                case "texturemerge":
                    mode = WorkMode.TextureMerge;
                    break;

                case "objconvert":
                    mode = WorkMode.OBJConvert;
                    break;

                case "cmif":
                    mode = WorkMode.CMIFConvert;
                    break;
                }
                if (mode != WorkMode.None)
                {
                    string input  = null;
                    string donor  = null;
                    string output = null;
                    if (argsList.Contains("-i"))
                    {
                        int index = argsList.IndexOf("-i") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - input");
                            return;
                        }
                        else
                        {
                            input = args[index];
                        }
                    }

                    if (argsList.Contains("-d"))
                    {
                        int index = argsList.IndexOf("-d") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - donor");
                            return;
                        }
                        else
                        {
                            donor = args[index];
                        }
                    }

                    if (argsList.Contains("-o"))
                    {
                        int index = argsList.IndexOf("-o") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - output");
                            return;
                        }
                        else
                        {
                            output = args[index];
                        }
                    }

                    if (input == null)
                    {
                        Console.WriteLine("Input argument missing");
                        return;
                    }
                    if (mode == WorkMode.TextureMerge && donor == null)
                    {
                        Console.WriteLine("Texture merge donor argument missing");
                        return;
                    }

                    H3D Scene = new H3D();

                    if (donor != null)
                    {
                        using (FileStream FS = new FileStream(donor, FileMode.Open))
                        {
                            Console.WriteLine("Starting conversion");
                            if (FS.Length > 4)
                            {
                                BinaryReader Reader = new BinaryReader(FS);

                                uint MagicNum = Reader.ReadUInt32();

                                FS.Seek(-4, SeekOrigin.Current);

                                string Magic = Encoding.ASCII.GetString(Reader.ReadBytes(4));

                                FS.Seek(0, SeekOrigin.Begin);

                                if (Magic.StartsWith("BCH"))
                                {
                                    Console.WriteLine("Merging H3D " + donor);

                                    Scene = H3D.Open(Reader.ReadBytes((int)FS.Length));

                                    FS.Dispose();
                                }
                            }
                        }
                    }

                    string outFile = output;
                    if (outFile == null)
                    {
                        outFile = Path.GetFileNameWithoutExtension(input) + "_conv.bch";
                    }

                    switch (mode)
                    {
                    case WorkMode.OBJConvert:
                        Scene.Materials.Clear();
                        Scene.Models.Clear();
                        goto case WorkMode.TextureMerge;

                    case WorkMode.TextureMerge:
                    {
                        bool textureless = false;
                        if (argsList.Contains("-notextures"))
                        {
                            Console.WriteLine("No texture mode");
                            textureless = true;
                        }
                        Console.WriteLine("Merging OBJ " + input);

                        Scene.Merge(new OBJ(input).ToH3D(Directory.GetParent(input).FullName, textureless));
                    }
                    break;

                    case WorkMode.CMIFConvert:
                    {
                        Console.WriteLine("Converting Common Interchange file to H3D...");

                        Scene.Merge(new CMIFFile(new FileStream(input, FileMode.Open)).ToH3D());
                    }
                    break;
                    }



                    H3D.Save(outFile, Scene);

                    Console.WriteLine("Saved as " + outFile);
                }
            }
            else
            {
                printHelp();
            }
        }
예제 #6
0
        public static H3D IdentifyAndOpen(string FileName, H3DDict <H3DBone> Skeleton = null)
        {
            //Formats that can by identified by extensions
            string FilePath = Path.GetDirectoryName(FileName);

            switch (Path.GetExtension(FileName).ToLower())
            {
            case ".txt":
                H3D AllFiles = new H3D();

                string[] files = File.ReadAllLines(FileName);

                string Parent = FilePath;

                foreach (string File in files)
                {
                    AllFiles.Merge(IdentifyAndOpen(Path.Combine(Parent, File)));
                }

                return(AllFiles);

            case ".gmp":
                H3D           OutputH3D = new H3D();
                GF1MotionPack MotPack   = new GF1MotionPack(new BinaryReader(new FileStream(FileName, FileMode.Open)));
                foreach (GF1Motion Mot in MotPack)
                {
                    H3DAnimation SklAnim = Mot.ToH3DSkeletalAnimation(Skeleton);

                    SklAnim.Name = $"Motion_{Mot.Index}";

                    OutputH3D.SkeletalAnimations.Add(SklAnim);
                }
                return(OutputH3D);

            case ".smd": return(new SMD(FileName).ToH3D(FilePath));

            case ".obj": return(new OBJ(FileName).ToH3D(FilePath));

            case ".mtl": return(new OBJ(FileName).ToH3D(FilePath));

            case ".cmif": return(new CMIFFile(new FileStream(FileName, FileMode.Open)).ToH3D());

            case ".png":
                H3D Out = new H3D();
                Out.Textures.Add(new H3DTexture(FileName, true));
                return(Out);

            case ".gfbmdl":
                H3DModel model = new GFModel(new BinaryReader(new FileStream(FileName, FileMode.Open)), Path.GetFileNameWithoutExtension(FileName)).ToH3DModel();
                H3D      Scene = new H3D();
                Scene.Models.Add(model);
                return(Scene);

            case ".mbn":
                using (FileStream Input = new FileStream(FileName, FileMode.Open))
                {
                    H3D BaseScene = H3D.Open(File.ReadAllBytes(FileName.Replace(".mbn", ".bch")));

                    MBn ModelBinary = new MBn(new BinaryReader(Input), BaseScene);

                    return(ModelBinary.ToH3D());
                }
            }

            //Formats that can only be indetified by "magic numbers"
            H3D Output = null;

            using (FileStream FS = new FileStream(FileName, FileMode.Open))
            {
                if (FS.Length > 4)
                {
                    BinaryReader Reader = new BinaryReader(FS);

                    uint MagicNum = Reader.ReadUInt32();

                    FS.Seek(-4, SeekOrigin.Current);

                    string Magic = Encoding.ASCII.GetString(Reader.ReadBytes(4));

                    FS.Seek(0, SeekOrigin.Begin);

                    if (Magic.StartsWith("BCH"))
                    {
                        return(H3D.Open(Reader.ReadBytes((int)FS.Length)));
                    }
                    else if (Magic.StartsWith("MOD"))
                    {
                        return(LoadMTModel(Reader, FileName, Path.GetDirectoryName(FileName)));
                    }
                    else if (Magic.StartsWith("TEX"))
                    {
                        return(new MTTexture(Reader, Path.GetFileNameWithoutExtension(FileName)).ToH3D());
                    }
                    else if (Magic.StartsWith("MFX"))
                    {
                        MTShader = new MTShaderEffects(Reader);
                    }
                    else if (Magic.StartsWith("CGFX"))
                    {
                        return(Gfx.Open(FS));
                    }
                    else if (Magic.StartsWith("CMIF"))
                    {
                        return(new CMIFFile(new FileStream(FileName, FileMode.Open)).ToH3D());
                    }
                    else
                    {
                        if (GFPackage.IsValidPackage(FS))
                        {
                            GFPackage.Header PackHeader = GFPackage.GetPackageHeader(FS);

                            switch (PackHeader.Magic)
                            {
                            case "AL": Output = GFAreaLOD.OpenAsH3D(FS, PackHeader, 1); break;

                            case "AD": Output = GFPackedTexture.OpenAsH3D(FS, PackHeader, 1); break;

                            //case "BG": Output = GFL2OverWorld.OpenAsH3D(FS, PackHeader, Skeleton); break;
                            case "BS": Output = GFBtlSklAnim.OpenAsH3D(FS, PackHeader, Skeleton); break;

                            case "CM": Output = GFCharaModel.OpenAsH3D(FS, PackHeader); break;

                            case "GR": Output = GFOWMapModel.OpenAsH3D(FS, PackHeader); break;

                            case "MM": Output = GFOWCharaModel.OpenAsH3D(FS, PackHeader); break;

                            case "PC": Output = GFPkmnModel.OpenAsH3D(FS, PackHeader, Skeleton); break;

                            case "LL":
                            default:
                            case "PT": Output = GFPackedTexture.OpenAsH3D(FS, PackHeader, 0); break;

                            case "PK":
                            case "PB":
                                Output = GFPkmnSklAnim.OpenAsH3D(FS, PackHeader, Skeleton); break;
                            }
                        }
                        else
                        {
                            switch (MagicNum)
                            {
                            case GFModel.MagicNum:
                                Output = new H3D();

                                Output.Models.Add(new GFModel(Reader, "Model").ToH3DModel());

                                break;

                            case GFTexture.MagicNum:
                                Output = new H3D();

                                Output.Textures.Add(new GFTexture(Reader).ToH3DTexture());

                                break;

                            case GFModelPack.MagicNum:
                                Output = new GFModelPack(Reader).ToH3D();
                                break;

                            case 0x00060000:
                                if (Skeleton != null)
                                {
                                    Output = new H3D();

                                    GFMotion Motion = new GFMotion(Reader, 0);

                                    H3DAnimation    SklAnim = Motion.ToH3DSkeletalAnimation(Skeleton);
                                    H3DMaterialAnim MatAnim = Motion.ToH3DMaterialAnimation();
                                    H3DAnimation    VisAnim = Motion.ToH3DVisibilityAnimation();

                                    if (SklAnim != null)
                                    {
                                        Output.SkeletalAnimations.Add(SklAnim);
                                    }
                                    if (MatAnim != null)
                                    {
                                        Output.MaterialAnimations.Add(MatAnim);
                                    }
                                    if (VisAnim != null)
                                    {
                                        Output.VisibilityAnimations.Add(VisAnim);
                                    }
                                }

                                break;
                            }
                        }
                    }
                }
            }

            return(Output);
        }
예제 #7
0
        public static H3D IdentifyAndOpen(string fileName, H3DDict <H3DBone> skeleton = null)
        {
            //Formats that can by identified by extensions
            var filePath = Path.GetDirectoryName(fileName);

            switch (Path.GetExtension(fileName).ToLower())
            {
            case ".smd": return(new SMD(fileName).ToH3D(filePath));

            case ".obj": return(new OBJ(fileName).ToH3D(filePath));

            case ".mbn":
                using (var input = new FileStream(fileName, FileMode.Open))
                {
                    var baseScene = H3D.Open(File.ReadAllBytes(fileName.Replace(".mbn", ".bch")));

                    var modelBinary = new MBn(new BinaryReader(input), baseScene);

                    return(modelBinary.ToH3D());
                }
            }

            //Formats that can only be indetified by "magic numbers"
            var output = default(H3D);

            using (var fs = new FileStream(fileName, FileMode.Open))
            {
                if (fs.Length > 4)
                {
                    var reader = new BinaryReader(fs);

                    var magicNum = reader.ReadUInt32();

                    fs.Seek(-4, SeekOrigin.Current);

                    var magic = Encoding.ASCII.GetString(reader.ReadBytes(4));

                    fs.Seek(0, SeekOrigin.Begin);

                    if (magic.StartsWith("BCH"))
                    {
                        return(H3D.Open(reader.ReadBytes((int)fs.Length)));
                    }
                    else if (magic.StartsWith("MOD"))
                    {
                        return(LoadMTModel(reader, fileName, Path.GetDirectoryName(fileName)));
                    }
                    else if (magic.StartsWith("TEX"))
                    {
                        return(new MTTexture(reader, Path.GetFileNameWithoutExtension(fileName)).ToH3D());
                    }
                    else if (magic.StartsWith("MFX"))
                    {
                        _mtShader = new MTShaderEffects(reader);
                    }
                    else if (magic.StartsWith("CGFX"))
                    {
                        return(Gfx.Open(fs));
                    }
                    else
                    {
                        if (GFPackage.IsValidPackage(fs))
                        {
                            var packHeader = GFPackage.GetPackageHeader(fs);

                            switch (packHeader.Magic)
                            {
                            case "AD": output = GFPackedTexture.OpenAsH3D(fs, packHeader, 1); break;

                            case "BG": output = GFL2OverWorld.OpenAsH3D(fs, packHeader, skeleton); break;

                            case "BS": output = GFBtlSklAnim.OpenAsH3D(fs, packHeader, skeleton); break;

                            case "CM": output = GFCharaModel.OpenAsH3D(fs, packHeader); break;

                            case "GR": output = GFOWMapModel.OpenAsH3D(fs, packHeader); break;

                            case "MM": output = GFOWCharaModel.OpenAsH3D(fs, packHeader); break;

                            case "PC": output = GFPkmnModel.OpenAsH3D(fs, packHeader, skeleton); break;

                            case "PT": output = GFPackedTexture.OpenAsH3D(fs, packHeader, 0); break;

                            case "PK":
                            case "PB": output = GFPkmnSklAnim.OpenAsH3D(fs, packHeader, skeleton); break;
                            }
                        }
                        else
                        {
                            switch (magicNum)
                            {
                            case 0x15122117:
                                output = new H3D();

                                output.Models.Add(new GFModel(reader, "Model").ToH3DModel());

                                break;

                            case 0x15041213:
                                output = new H3D();

                                output.Textures.Add(new GFTexture(reader).ToH3DTexture());

                                break;

                            case 0x00010000: output = new GFModelPack(reader).ToH3D(); break;

                            case 0x00060000:
                                if (skeleton != null)
                                {
                                    output = new H3D();

                                    var motion = new GFMotion(reader, 0);

                                    var sklAnim = motion.ToH3DSkeletalAnimation(skeleton);
                                    var matAnim = motion.ToH3DMaterialAnimation();
                                    var visAnim = motion.ToH3DVisibilityAnimation();

                                    if (sklAnim != null)
                                    {
                                        output.SkeletalAnimations.Add(sklAnim);
                                    }
                                    if (matAnim != null)
                                    {
                                        output.MaterialAnimations.Add(matAnim);
                                    }
                                    if (visAnim != null)
                                    {
                                        output.VisibilityAnimations.Add(visAnim);
                                    }
                                }

                                break;
                            }
                        }
                    }
                }
            }

            return(output);
        }
예제 #8
0
        public static H3D IdentifyAndOpen(string FileName, H3DDict <H3DBone> Skeleton = null)
        {
            //Formats that can by identified by extensions
            string FilePath = Path.GetDirectoryName(FileName);

            switch (Path.GetExtension(FileName).ToLower())
            {
            case ".smd": return(new SMD(FileName).ToH3D(FilePath));

            case ".obj": return(new OBJ(FileName).ToH3D(FilePath));

            case ".mbn":
                using (FileStream Input = new FileStream(FileName, FileMode.Open))
                {
                    H3D BaseScene = H3D.Open(File.ReadAllBytes(FileName.Replace(".mbn", ".bch")));

                    MBn ModelBinary = new MBn(new BinaryReader(Input), BaseScene);

                    return(ModelBinary.ToH3D());
                }
            }

            //Formats that can only be indetified by "magic numbers"
            H3D Output = null;

            using (FileStream FS = new FileStream(FileName, FileMode.Open))
            {
                if (FS.Length > 4)
                {
                    BinaryReader Reader = new BinaryReader(FS);

                    uint MagicNum = Reader.ReadUInt32();

                    FS.Seek(-4, SeekOrigin.Current);

                    string Magic = Encoding.ASCII.GetString(Reader.ReadBytes(4));

                    FS.Seek(0, SeekOrigin.Begin);

                    if (Magic.StartsWith("BCH"))
                    {
                        return(H3D.Open(Reader.ReadBytes((int)FS.Length)));
                    }
                    else if (Magic.StartsWith("MOD"))
                    {
                        return(LoadMTModel(Reader, FileName, Path.GetDirectoryName(FileName)));
                    }
                    else if (Magic.StartsWith("TEX"))
                    {
                        return(new MTTexture(Reader, Path.GetFileNameWithoutExtension(FileName)).ToH3D());
                    }
                    else if (Magic.StartsWith("MFX"))
                    {
                        MTShader = new MTShaderEffects(Reader);
                    }
                    else if (Magic.StartsWith("CGFX"))
                    {
                        return(Gfx.Open(FS));
                    }
                    else
                    {
                        if (GFPackage.IsValidPackage(FS))
                        {
                            GFPackage.Header PackHeader = GFPackage.GetPackageHeader(FS);

                            switch (PackHeader.Magic)
                            {
                            case "AD": Output = GFPackedTexture.OpenAsH3D(FS, PackHeader, 1); break;

                            case "BG": Output = GFL2OverWorld.OpenAsH3D(FS, PackHeader, Skeleton); break;

                            case "BS": Output = GFBtlSklAnim.OpenAsH3D(FS, PackHeader, Skeleton); break;

                            case "CM": Output = GFCharaModel.OpenAsH3D(FS, PackHeader); break;

                            case "GR": Output = GFOWMapModel.OpenAsH3D(FS, PackHeader); break;

                            case "MM": Output = GFOWCharaModel.OpenAsH3D(FS, PackHeader); break;

                            case "PC": Output = GFPkmnModel.OpenAsH3D(FS, PackHeader, Skeleton); break;

                            case "PT": Output = GFPackedTexture.OpenAsH3D(FS, PackHeader, 0); break;

                            case "PK":
                            case "PB":
                                Output = GFPkmnSklAnim.OpenAsH3D(FS, PackHeader, Skeleton); break;
                            }
                        }
                        else
                        {
                            switch (MagicNum)
                            {
                            case 0x15122117:
                                Output = new H3D();

                                Output.Models.Add(new GFModel(Reader, "Model").ToH3DModel());

                                break;

                            case 0x15041213:
                                Output = new H3D();

                                Output.Textures.Add(new GFTexture(Reader).ToH3DTexture());

                                break;

                            case 0x00010000: Output = new GFModelPack(Reader).ToH3D(); break;

                            case 0x00060000:
                                if (Skeleton != null)
                                {
                                    Output = new H3D();

                                    GFMotion Motion = new GFMotion(Reader, 0);

                                    H3DAnimation    SklAnim = Motion.ToH3DSkeletalAnimation(Skeleton);
                                    H3DMaterialAnim MatAnim = Motion.ToH3DMaterialAnimation();
                                    H3DAnimation    VisAnim = Motion.ToH3DVisibilityAnimation();

                                    if (SklAnim != null)
                                    {
                                        Output.SkeletalAnimations.Add(SklAnim);
                                    }
                                    if (MatAnim != null)
                                    {
                                        Output.MaterialAnimations.Add(MatAnim);
                                    }
                                    if (VisAnim != null)
                                    {
                                        Output.VisibilityAnimations.Add(VisAnim);
                                    }
                                }

                                break;
                            }
                        }
                    }
                }
            }

            return(Output);
        }
예제 #9
0
파일: Form1.cs 프로젝트: VelouriasMoon/FEAT
        private void Open(string infile)
        {
            FileAttributes fileAttributes = File.GetAttributes(infile);

            if (fileAttributes.HasFlag(FileAttributes.Directory))
            {
                if (ModifierKeys == Keys.Control)
                {
                    AddLine(richTextBox1, $"Building Arc from {Path.GetFileName(infile)}...");
                    FEArc.PackArc(infile, Alignment, enablePaddingToolStripMenuItem.Checked);
                    AddLine(richTextBox1, "Done");
                }
                else if (ModifierKeys == Keys.Shift)
                {
                    AddLine(richTextBox1, $"Building BCH from {Path.GetFileName(infile)}...");

                    if (infile.EndsWith("_"))
                    {
                        infile = infile.Substring(0, infile.Length - "_".Length);
                    }

                    if (File.Exists(infile + ".bch"))
                    {
                        File.Delete(infile + ".bch");
                    }

                    List <string> files = Directory.GetFiles(infile, "*.*", SearchOption.AllDirectories).ToList();
                    H3D           Scene = new H3D();
                    Scene.ConverterVersion      = 44139;
                    Scene.BackwardCompatibility = 34;
                    Scene.ForwardCompatibility  = 35;
                    foreach (string file in files)
                    {
                        Bitmap texture;
                        try
                        {
                            texture = (Bitmap)Bitmap.FromFile(file);
                        }
                        catch (OutOfMemoryException)
                        {
                            Console.WriteLine("invalid image format, skipping");
                            continue;
                        }
                        Scene.Textures.Add(new H3DTexture(Path.GetFileNameWithoutExtension(file), texture, SPICA.PICA.Commands.PICATextureFormat.RGBA8));
                    }

                    if (Scene.Textures.Count <= 0)
                    {
                        AddLine(richTextBox1, "Error");
                        AddLine(richTextBox1, $"No images found in {Path.GetFileName(infile)}");
                    }
                    else
                    {
                        H3D.Save($"{infile}.bch", Scene);
                        AddLine(richTextBox1, "Done");
                    }
                    return;
                }
                else if (ModifierKeys == Keys.Alt)
                {
                    AddLine(richTextBox1, $"Building CTPK from {Path.GetFileName(infile)}...");
                    CTPK.MakeCTPK(infile);
                    AddLine(richTextBox1, "Done");
                }
                else
                {
                    foreach (string p in (new DirectoryInfo(infile)).GetFiles().Select(f => f.FullName))
                    {
                        Open(p);
                    }
                    foreach (string p in (new DirectoryInfo(infile)).GetDirectories().Select(f => f.FullName))
                    {
                        Open(p);
                    }
                }
            }
            else
            {
                byte[] data    = File.ReadAllBytes(infile);
                string magic   = FEIO.GetMagic(data);
                string ext     = Path.GetExtension(infile);
                string outpath = ext.Length == 0 ? infile : infile.Replace(ext, "");

                if (ModifierKeys == Keys.Control || batchCompressToolStripMenuItem.Checked) // Compression Method
                {
                    byte[] cmp;
                    if (lZ10CompressionToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz10...");
                        try
                        {
                            cmp = FEIO.LZ10Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (lZ11ToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz11...");
                        try
                        {
                            cmp = FEIO.LZ11Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (lZ13ToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz13...");
                        try
                        {
                            cmp = FEIO.LZ13Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else
                    {
                        AddLine(richTextBox1, "No Compression Method Selected, How did this even happen?");
                    }
                }
                else if (ext == ".lz" || magic == "Yaz0" || ext == ".cms" || ext == ".cmp") // Decompress Method
                {
                    byte[] dcmp;
                    if (data[0] == 0x10)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz10...");
                        try
                        {
                            dcmp = FEIO.LZ10Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ10
                    else if (data[0] == 0x11)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz11...");
                        try
                        {
                            dcmp = FEIO.LZ11Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ11
                    else if (data[0] == 0x13 && data[4] == 0x11)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz13...");
                        try
                        {
                            dcmp = FEIO.LZ13Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ13
                    else if (magic == "Yaz0")
                    {
                        AddLine(richTextBox1, "Yaz0 Method not implemented");
                        return;
                    } //Yaz0
                    if (File.Exists(infile.Replace(".lz", "")) && autoExtractToolStripMenuItem.Checked)
                    {
                        Open(infile.Replace(".lz", ""));
                    }
                }
                else if (ext == ".arc") //Archive file
                {
                    AddLine(richTextBox1, $"Extract Files from {Path.GetFileName(infile)}...");
                    FEArc.ExtractArc(outpath, data);
                    AddLine(richTextBox1, "Done");
                }
                else if (magic == "BCH" || magic == "CGFX") //BCH / Bcres file
                {
                    H3D Scene = new H3D();
                    if (magic == "CGFX")
                    {
                        Scene = Gfx.Open(infile).ToH3D();
                    }
                    else
                    {
                        Scene = H3D.Open(data);
                    }

                    if (Directory.Exists(outpath))
                    {
                        Directory.Delete(outpath, true);
                    }
                    if (File.Exists(outpath))
                    {
                        outpath = outpath + "_";
                    }

                    //Export method for textures, this is always enabled by default
                    if (Scene.Textures.Count > 0)
                    {
                        AddLine(richTextBox1, $"Extracting Textures from {Path.GetFileName(infile)}...");
                        if (!Directory.Exists(outpath))
                        {
                            Directory.CreateDirectory(outpath);
                        }

                        foreach (var texture in Scene.Textures)
                        {
                            Image img = texture.ToBitmap();
                            img.Save($"{outpath}\\{texture.Name}.png", System.Drawing.Imaging.ImageFormat.Png);
                        }
                        AddLine(richTextBox1, "Done");
                    }
                    if (exportDaeToolStripMenuItem.Checked || exportSMDToolStripMenuItem.Checked && Scene.Models.Count > 0)
                    {
                        AddLine(richTextBox1, $"Extracting Models from {Path.GetFileName(infile)}...");
                        if (!Directory.Exists(outpath))
                        {
                            Directory.CreateDirectory(outpath);
                        }

                        for (int i = 0; i < Scene.Models.Count; i++)
                        {
                            if (exportDaeToolStripMenuItem.Checked)
                            {
                                DAE dae = new DAE(Scene, i);
                                dae.Save($"{outpath}\\{Scene.Models[i].Name}.dae");
                            }
                            if (exportSMDToolStripMenuItem.Checked)
                            {
                                SMD smd = new SMD(Scene, i);
                                smd.Save($"{outpath}\\{Scene.Models[i].Name}.smd");
                            }
                        }
                        AddLine(richTextBox1, "Done");
                    }
                }
                else if (magic == "CTPK") //CTPK file
                {
                    AddLine(richTextBox1, $"Extract Textures from {Path.GetFileName(infile)}...");
                    CTPK.ExtractCTPK(infile);
                    AddLine(richTextBox1, "Done");
                }
                else if (ext == ".bin")
                {
                    if (FEIO.ReadStringFromArray(data, Encoding.UTF8, 0x20).Contains("MESS_ARCHIVE"))
                    {
                        AddLine(richTextBox1, $"Extracting Message Archive {Path.GetFileName(infile)}...");
                        FEMessage.ExtractMessage(infile.Replace(ext, ".txt"), data);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (enableBinDecomplingToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Decompiling {Path.GetFileName(infile)} to txt...");
                        FEBin.ExtractBin(infile);
                        AddLine(richTextBox1, "Done");
                    }
                }
                if (deleteAfterProcessingToolStripMenuItem.Checked)
                {
                    File.Delete(infile);
                }
            }
        }
예제 #10
0
        public static H3D OpenAsH3D(Stream input, GFPackage.Header header, H3DDict <H3DBone> skeleton = null)
        {
            var output = default(H3D);

            var reader = new BinaryReader(input);

            input.Seek(header.Entries[0].Address, SeekOrigin.Begin);

            var magicNum = reader.ReadUInt32();

            switch (magicNum)
            {
            case GFModelConstant:
                var mdlPack = new GFModelPack();

                //High Poly Pokémon model
                input.Seek(header.Entries[0].Address, SeekOrigin.Begin);

                mdlPack.Models.Add(new GFModel(reader, "PM_HighPoly"));

                //Low Poly Pokémon model
                input.Seek(header.Entries[1].Address, SeekOrigin.Begin);

                mdlPack.Models.Add(new GFModel(reader, "PM_LowPoly"));

                //Pokémon Shader package
                input.Seek(header.Entries[2].Address, SeekOrigin.Begin);

                var psHeader = GFPackage.GetPackageHeader(input);

                foreach (var entry in psHeader.Entries)
                {
                    input.Seek(entry.Address, SeekOrigin.Begin);

                    mdlPack.Shaders.Add(new GFShader(reader));
                }

                //More shaders
                input.Seek(header.Entries[3].Address, SeekOrigin.Begin);

                if (GFPackage.IsValidPackage(input))
                {
                    var pcHeader = GFPackage.GetPackageHeader(input);

                    foreach (var entry in pcHeader.Entries)
                    {
                        input.Seek(entry.Address, SeekOrigin.Begin);

                        mdlPack.Shaders.Add(new GFShader(reader));
                    }
                }

                output = mdlPack.ToH3D();

                break;

            case GFTextureConstant:
                output = new H3D();

                foreach (var entry in header.Entries)
                {
                    input.Seek(entry.Address, SeekOrigin.Begin);

                    output.Textures.Add(new GFTexture(reader).ToH3DTexture());
                }

                break;

            case GFMotionConstant:
                output = new H3D();

                if (skeleton == null)
                {
                    break;
                }

                for (var index = 0; index < header.Entries.Length; index++)
                {
                    input.Seek(header.Entries[index].Address, SeekOrigin.Begin);

                    if (input.Position + 4 > input.Length)
                    {
                        break;
                    }
                    if (reader.ReadUInt32() != GFMotionConstant)
                    {
                        continue;
                    }

                    input.Seek(-4, SeekOrigin.Current);

                    var mot = new GFMotion(reader, index);

                    var sklAnim = mot.ToH3DSkeletalAnimation(skeleton);
                    var matAnim = mot.ToH3DMaterialAnimation();
                    var visAnim = mot.ToH3DVisibilityAnimation();

                    if (sklAnim != null)
                    {
                        sklAnim.Name = $"Motion_{mot.Index}";

                        output.SkeletalAnimations.Add(sklAnim);
                    }

                    if (matAnim != null)
                    {
                        matAnim.Name = $"Motion_{mot.Index}";

                        output.MaterialAnimations.Add(matAnim);
                    }

                    if (visAnim != null)
                    {
                        visAnim.Name = $"Motion_{mot.Index}";

                        output.VisibilityAnimations.Add(visAnim);
                    }
                }

                break;

            case BCHConstant:
                output = new H3D();

                foreach (var entry in header.Entries)
                {
                    input.Seek(entry.Address, SeekOrigin.Begin);

                    magicNum = reader.ReadUInt32();

                    if (magicNum != BCHConstant)
                    {
                        continue;
                    }

                    input.Seek(-4, SeekOrigin.Current);

                    var buffer = reader.ReadBytes(entry.Length);

                    output.Merge(H3D.Open(buffer));
                }

                break;
            }

            return(output);
        }