public void AddShader(GFShader Shader) { if (Shader.HasVertexShader) { Console.WriteLine("Adding shader " + Shader.Name + " as vertex shader."); VertexShaders.Add(Shader); } else { Console.WriteLine("Adding shader " + Shader.Name + " as material shader."); MaterialShaders.Add(Shader); } }
public static uint GetTexEnvConfigHash(GFShader Shader) { FNV1a FNV = new FNV1a(); foreach (PICATexEnvStage Stage in Shader.TexEnvStages) { FNV.Hash(Stage.Color.ToUInt32()); FNV.Hash(Stage.Combiner.ToUInt32()); FNV.Hash(Stage.Operand.ToUInt32()); FNV.Hash(Stage.Scale.ToUInt32()); FNV.Hash(Stage.Source.ToUInt32()); FNV.Hash(Stage.UpdateAlphaBuffer ? 1 : 0); FNV.Hash(Stage.UpdateColorBuffer ? 1 : 0); } FNV.Hash(Shader.TexEnvBufferColor.ToUInt32()); return(FNV.HashCode); }
public H3D ToH3D() { H3D Output = new H3D(); H3DLUT L = new H3DLUT(); L.Name = GFModel.DefaultLUTName; for (int MdlIndex = 0; MdlIndex < Models.Count; MdlIndex++) { GFModel Model = Models[MdlIndex]; H3DModel Mdl = Model.ToH3DModel(); for (int MatIndex = 0; MatIndex < Model.Materials.Count; MatIndex++) { H3DMaterialParams Params = Mdl.Materials[MatIndex].MaterialParams; string FragShaderName = Model.Materials[MatIndex].FragShaderName; string VtxShaderName = Model.Materials[MatIndex].VtxShaderName; GFShader FragShader = Shaders.FirstOrDefault(x => x.Name == FragShaderName); GFShader VtxShader = Shaders.FirstOrDefault(x => x.Name == VtxShaderName); if (FragShader != null) { Params.TexEnvBufferColor = FragShader.TexEnvBufferColor; Array.Copy(FragShader.TexEnvStages, Params.TexEnvStages, 6); } if (VtxShader != null) { foreach (KeyValuePair <uint, Vector4> KV in VtxShader.VtxShaderUniforms) { Params.VtxShaderUniforms.Add(KV.Key, KV.Value); } foreach (KeyValuePair <uint, Vector4> KV in VtxShader.GeoShaderUniforms) { Params.GeoShaderUniforms.Add(KV.Key, KV.Value); } } } foreach (GFLUT LUT in Model.LUTs) { L.Samplers.Add(new H3DLUTSampler() { Name = LUT.Name, Table = LUT.Table }); } Output.Models.Add(Mdl); } Output.LUTs.Add(L); Output.CopyMaterials(); foreach (GFTexture Texture in Textures) { Output.Textures.Add(Texture.ToH3DTexture()); } return(Output); }
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 H3D ToH3D() { H3D Output = new H3D(); Output.SourceData.Add(this); H3DLUT L = new H3DLUT(); L.Name = GFModel.DefaultLUTName; for (int MdlIndex = 0; MdlIndex < Models.Count; MdlIndex++) { GFModel Model = Models[MdlIndex]; H3DModel Mdl = Model.ToH3DModel(); for (int MatIndex = 0; MatIndex < Model.Materials.Count; MatIndex++) { H3DMaterialParams Params = Mdl.Materials[MatIndex].MaterialParams; string FragShaderName = Model.Materials[MatIndex].FragShaderName; string VtxShaderName = Model.Materials[MatIndex].VtxShaderName; GFShader FragShader = MaterialShaders.FirstOrDefault(x => x.Name == FragShaderName); GFShader VtxShader = MaterialShaders.FirstOrDefault(x => x.Name == VtxShaderName); if (FragShader != null) { Params.TexEnvBufferColor = FragShader.TexEnvBufferColor; Array.Copy(FragShader.TexEnvStages, Params.TexEnvStages, 6); } Params.MetaData.Add(new H3DMetaDataValue("OriginMaterialHash", (int)GetTexEnvConfigHash(Params))); if (VtxShader != null) { foreach (KeyValuePair <uint, Vector4> KV in VtxShader.VtxShaderUniforms) { Params.VtxShaderUniforms.Add(KV.Key, KV.Value); } foreach (KeyValuePair <uint, Vector4> KV in VtxShader.GeoShaderUniforms) { Params.GeoShaderUniforms.Add(KV.Key, KV.Value); } } } int Index = 1; while (Output.Models.Contains(Mdl.Name)) { Mdl.Name = $"{Mdl.Name}_{Index}"; } Model.AddToH3DLUT(L); Output.Models.Add(Mdl); } Output.LUTs.Add(L); Output.CopyMaterials(); foreach (GFTexture Texture in Textures) { Output.Textures.Add(Texture.ToH3DTexture()); } /*Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(Output, Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonSerializerSettings() * { * ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore * }));*/ return(Output); }
public void MergeH3D(H3D Scene) { foreach (object SourceData in Scene.SourceData) { if (SourceData is GFModelPack) { MergeGFModelPack((GFModelPack)SourceData); } else if (SourceData is GFShader) { GFShader Sha = (GFShader)SourceData; if (Sha.HasVertexShader) { Console.WriteLine("Merging vertex shader: " + Sha.Name); VertexShaders.Add(Sha); } else { Console.WriteLine("Merging material shader: " + Sha.Name); MaterialShaders.Add(Sha); } } } Models.Clear(); Textures.Clear(); Dictionary <uint, GFShader> ShaderHashesOriginal = new Dictionary <uint, GFShader>(); Dictionary <uint, GFShader> ShaderHashes = new Dictionary <uint, GFShader>(); List <string> UsedVertexShaders = new List <string>(); List <string> UsedMaterialShaders = new List <string>(); foreach (GFShader Shader in MaterialShaders) { uint Hash = GetTexEnvConfigHash(Shader); if (!ShaderHashes.ContainsKey(Hash)) { Console.WriteLine("Adding existing shader " + Shader.Name); ShaderHashesOriginal.Add(Hash, Shader); ShaderHashes.Add(Hash, Shader); } } foreach (H3DModel Model in Scene.Models) { GFModel GFM = new GFModel(Model, Scene.LUTs); foreach (H3DMaterial Material in Model.Materials) { bool IsAllowOriginalShader = false; uint Hash = GetTexEnvConfigHash(Material.MaterialParams); H3DMetaDataValue OriginHash = Material.MaterialParams.MetaData.Get("OriginMaterialHash"); if (OriginHash != null) { IsAllowOriginalShader = (int)OriginHash.Values[0] == Hash && ShaderHashesOriginal.ContainsKey(Hash); } if (!IsAllowOriginalShader) { GFShader Shader; if (ShaderHashes.ContainsKey(Hash)) { Shader = ShaderHashes[Hash]; } else { Shader = new GFShader(Material, Material.Name + "_SHA"); Console.WriteLine("Generating shader " + Shader.Name); ShaderHashes.Add(GetTexEnvConfigHash(Shader), Shader); AddUnique(MaterialShaders, Shader); } foreach (GFMaterial GFMat in GFM.Materials) { if (GFMat.Name == Material.Name) { GFMat.ShaderName = Shader.Name; GFMat.FragShaderName = Shader.Name; break; } } } } foreach (GFMaterial Mat in GFM.Materials) { if (!UsedVertexShaders.Contains(Mat.VtxShaderName)) { UsedVertexShaders.Add(Mat.VtxShaderName); } if (!UsedMaterialShaders.Contains(Mat.FragShaderName)) { UsedMaterialShaders.Add(Mat.FragShaderName); } } AddUnique(Models, GFM); } for (int i = 0; i < MaterialShaders.Count; i++) { if (!UsedMaterialShaders.Contains(MaterialShaders[i].Name)) { Console.WriteLine("Removing unused shader " + MaterialShaders[i].Name); MaterialShaders.RemoveAt(i); i--; } } for (int i = 0; i < VertexShaders.Count; i++) { if (!UsedVertexShaders.Contains(VertexShaders[i].Name)) { Console.WriteLine("Removing unused shader " + VertexShaders[i].Name); VertexShaders.RemoveAt(i); i--; } } foreach (H3DTexture Texture in Scene.Textures) { AddUnique(Textures, new GFTexture(Texture)); } }