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