/// <summary> /// Imports information into this scene from an IO Model /// </summary> public override void FromIOModel(IOModel iomodel) { // copy skeleton Skeleton = iomodel.Skeleton; // make temp material UltimateMaterial material = new UltimateMaterial(); material.Name = "SFX_PBS_0100080008008269_opaque"; material.Label = "skin_sonic_001"; //TODO more elegant material management Materials.Add(material); // convert meshes SBUltimateModel model = new SBUltimateModel(); foreach (var iomesh in iomodel.Meshes) { SBUltimateMesh <UltimateVertex> mesh = new SBUltimateMesh <UltimateVertex>(); mesh.Name = iomesh.Name; mesh.ParentBone = ""; mesh.Material = material; model.Meshes.Add(mesh); mesh.Indices = iomesh.Indices; iomesh.GenerateTangentsAndBitangents(); foreach (var vertex in iomesh.Vertices) { mesh.Vertices.Add(IOToUltimateVertex(vertex)); } //TODO: make more customizable through import settings mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Position0); mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Normal0); mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Tangent0); mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.map1); mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.colorSet1); } Model = model; }
/// <summary> /// Load an ultimate mesh from file to the given scene /// </summary> /// <param name="FileName"></param> /// <param name="Scene"></param> public static void Open(string FileName, SBScene Scene) { SsbhFile File; if (Ssbh.TryParseSsbhFile(FileName, out File)) { if (File is Matl matl) { if (matl.MajorVersion != 1 && matl.MinorVersion != 6) { SBConsole.WriteLine($"Warning: Mesh Version {matl.MajorVersion}.{matl.MinorVersion} not supported"); } var MaterialProps = typeof(UltimateMaterial).GetProperties(); // use dictionary for faster lookup Dictionary <string, PropertyInfo> NameToProperty = new Dictionary <string, PropertyInfo>(); foreach (var prop in MaterialProps) { var attrName = prop.Name; if (attrName != null) { NameToProperty.Add(attrName, prop); } } foreach (var entry in matl.Entries) { UltimateMaterial material = new UltimateMaterial(); material.Name = entry.ShaderLabel; material.Label = entry.MaterialLabel; Scene.Materials.Add(material); foreach (var attr in entry.Attributes) { if (NameToProperty.ContainsKey(attr.ParamId.ToString())) { var prop = NameToProperty[attr.ParamId.ToString()]; if (prop.PropertyType == typeof(SBMatAttrib <string>)) { material.SetProperty(attr.ParamId.ToString(), attr.DataObject.ToString()); } else if (prop.PropertyType == typeof(SBMatAttrib <Vector4>)) { material.SetProperty(attr.ParamId.ToString(), MATLVectorToGLVector((MatlAttribute.MatlVector4)attr.DataObject)); } else { material.SetProperty(attr.ParamId.ToString(), attr.DataObject); } } else { switch (attr.ParamId) { case MatlEnums.ParamId.RasterizerState0: material.RasterizerState = (MatlAttribute.MatlRasterizerState)attr.DataObject; break; case MatlEnums.ParamId.BlendState0: material.BlendState = (MatlAttribute.MatlBlendState)attr.DataObject; break; default: //SBConsole.WriteLine("Extra Param: " + attr.ParamID.ToString() + " = " + attr.DataObject.ToString()); material.extraParams.Add(attr.ParamId, attr.DataObject); break; } } } } } } }
/// <summary> /// Loads the scene from a NUMDLB file /// </summary> /// <param name="FileName"></param> public override void LoadFromFile(string FileName) { string folderPath = Path.GetDirectoryName(FileName); ISSBH_File File; if (!SSBH.TryParseSSBHFile(FileName, out File)) { return; } MODL modl = (MODL)File; string meshPath = ""; string skelPath = ""; string matlPath = ""; foreach (string file in Directory.EnumerateFiles(folderPath)) { // load textures if (file.EndsWith(".nutexb")) { NUTEX_Loader.Open(file, this); } string fileName = Path.GetFileName(file); if (fileName.Equals(modl.SkeletonFileName)) { skelPath = file; } if (fileName.Equals(modl.MeshString)) { meshPath = file; } if (fileName.Equals(modl.MaterialFileNames[0].MaterialFileName)) { matlPath = file; } } // import order Skeleton+Textures->Materials->Mesh // mesh needs to be loaded after skeleton if (skelPath != "") { SBConsole.WriteLine($"Importing skeleton: {Path.GetFileName(skelPath)}"); SKEL_Loader.Open(skelPath, this); } if (matlPath != "") { SBConsole.WriteLine($"Importing materials: {Path.GetFileName(matlPath)}"); MATL_Loader.Open(matlPath, this); } if (meshPath != "") { SBConsole.WriteLine($"Importing mesh: {Path.GetFileName(meshPath)}"); MESH_Loader.Open(meshPath, this); // set materials foreach (var entry in modl.ModelEntries) { UltimateMaterial currentMaterial = null; foreach (UltimateMaterial matentry in Materials) { if (matentry.Label.Equals(entry.MaterialName)) { currentMaterial = matentry; break; } } if (currentMaterial == null) { continue; } int subindex = 0; string prevMesh = ""; if (Model != null) { foreach (var mesh in Model.Meshes) { if (prevMesh.Equals(mesh.Name)) { subindex++; } else { subindex = 0; } prevMesh = mesh.Name; if (subindex == entry.SubIndex && mesh.Name.Equals(entry.MeshName)) { mesh.Material = currentMaterial; break; } } } } } }
/// <summary> /// Load an ultimate mesh from file to the given scene /// </summary> /// <param name="FileName"></param> /// <param name="Scene"></param> public static void Open(string FileName, SBScene Scene) { ISSBH_File File; if (SSBH.TryParseSSBHFile(FileName, out File)) { if (File is MATL matl) { if (matl.MajorVersion != 1 && matl.MinorVersion != 6) { SBConsole.WriteLine($"Warning: Mesh Version {matl.MajorVersion}.{matl.MinorVersion} not supported"); } var MaterialProps = typeof(UltimateMaterial).GetProperties(); // use dictionary for faster lookup Dictionary <string, PropertyInfo> NameToProperty = new Dictionary <string, PropertyInfo>(); foreach (var prop in MaterialProps) { var attrName = (MATLLoaderAttributeName)prop.GetCustomAttribute(typeof(MATLLoaderAttributeName)); if (attrName != null) { NameToProperty.Add(attrName.Name, prop); } } foreach (var entry in matl.Entries) { UltimateMaterial material = new UltimateMaterial(); material.Name = entry.MaterialName; material.Label = entry.MaterialLabel; Scene.Materials.Add(material); foreach (var attr in entry.Attributes) { if (NameToProperty.ContainsKey(attr.ParamID.ToString())) { var prop = NameToProperty[attr.ParamID.ToString()]; if (prop.PropertyType == typeof(SBMatAttrib <string>)) { ((SBMatAttrib <string>)prop.GetValue(material)).Value = attr.DataObject.ToString(); //foreach (var surface in Scene.Surfaces) // if (surface.Name == attr.DataObject.ToString()) // prop.SetValue(material, surface); } if (prop.PropertyType == typeof(SBMatAttrib <Vector4>)) { ((SBMatAttrib <Vector4>)prop.GetValue(material)).Value = MATLVectorToGLVector((MatlAttribute.MatlVector4)attr.DataObject); } if (prop.PropertyType == typeof(SBMatAttrib <float>)) { ((SBMatAttrib <float>)prop.GetValue(material)).Value = (float)attr.DataObject; } if (prop.PropertyType == typeof(SBMatAttrib <bool>)) { ((SBMatAttrib <bool>)prop.GetValue(material)).Value = (bool)attr.DataObject; } } else { switch (attr.ParamID) { case MatlEnums.ParamId.RasterizerState0: material.RasterizerState = (MatlAttribute.MatlRasterizerState)attr.DataObject; break; case MatlEnums.ParamId.BlendState0: material.BlendState = (MatlAttribute.MatlBlendState)attr.DataObject; break; default: SBConsole.WriteLine("Extra Param: " + attr.ParamID.ToString() + " = " + attr.DataObject.ToString()); material.extraParams.Add(attr.ParamID, attr.DataObject); break; } } } } } } }