From 3cd438bb5dc495e257a9f8731293010b8ea58ad6 Mon Sep 17 00:00:00 2001 From: ackwell Date: Wed, 10 Jan 2024 01:17:47 +1100 Subject: [PATCH] Export material names --- Penumbra/Import/Models/Export/MeshExporter.cs | 18 +++++++------- .../Import/Models/Export/ModelExporter.cs | 24 +++++++++++++++---- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Penumbra/Import/Models/Export/MeshExporter.cs b/Penumbra/Import/Models/Export/MeshExporter.cs index 84628c2c..6e6169ee 100644 --- a/Penumbra/Import/Models/Export/MeshExporter.cs +++ b/Penumbra/Import/Models/Export/MeshExporter.cs @@ -27,9 +27,9 @@ public class MeshExporter } } - public static Mesh Export(MdlFile mdl, byte lod, ushort meshIndex, GltfSkeleton? skeleton) + public static Mesh Export(MdlFile mdl, byte lod, ushort meshIndex, MaterialBuilder[] materials, GltfSkeleton? skeleton) { - var self = new MeshExporter(mdl, lod, meshIndex, skeleton?.Names); + var self = new MeshExporter(mdl, lod, meshIndex, materials, skeleton?.Names); return new Mesh(self.BuildMeshes(), skeleton?.Joints); } @@ -42,18 +42,22 @@ public class MeshExporter private MdlStructs.MeshStruct XivMesh => _mdl.Meshes[_meshIndex]; + private readonly MaterialBuilder _material; + private readonly Dictionary? _boneIndexMap; private readonly Type _geometryType; private readonly Type _materialType; private readonly Type _skinningType; - private MeshExporter(MdlFile mdl, byte lod, ushort meshIndex, IReadOnlyDictionary? boneNameMap) + private MeshExporter(MdlFile mdl, byte lod, ushort meshIndex, MaterialBuilder[] materials, IReadOnlyDictionary? boneNameMap) { _mdl = mdl; _lod = lod; _meshIndex = meshIndex; + _material = materials[XivMesh.MaterialIndex]; + if (boneNameMap != null) _boneIndexMap = BuildBoneIndexMap(boneNameMap); @@ -134,13 +138,7 @@ public class MeshExporter ); var meshBuilder = (IMeshBuilder)Activator.CreateInstance(meshBuilderType, name)!; - // TODO: share materials &c - var materialBuilder = new MaterialBuilder() - .WithDoubleSide(true) - .WithMetallicRoughnessShader() - .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 1, 1, 1)); - - var primitiveBuilder = meshBuilder.UsePrimitive(materialBuilder); + var primitiveBuilder = meshBuilder.UsePrimitive(_material); // Store a list of the glTF indices. The list index will be equivalent to the xiv (submesh) index. var gltfIndices = new List(); diff --git a/Penumbra/Import/Models/Export/ModelExporter.cs b/Penumbra/Import/Models/Export/ModelExporter.cs index 8271f266..6a25af61 100644 --- a/Penumbra/Import/Models/Export/ModelExporter.cs +++ b/Penumbra/Import/Models/Export/ModelExporter.cs @@ -1,4 +1,5 @@ using Penumbra.GameData.Files; +using SharpGLTF.Materials; using SharpGLTF.Scenes; using SharpGLTF.Transforms; @@ -14,7 +15,7 @@ public class ModelExporter var skeletonRoot = skeleton?.Root; if (skeletonRoot != null) scene.AddNode(skeletonRoot); - + // Add all the meshes to the scene. foreach (var mesh in meshes) mesh.AddToScene(scene); @@ -25,12 +26,13 @@ public class ModelExporter public static Model Export(MdlFile mdl, IEnumerable? xivSkeleton) { var gltfSkeleton = xivSkeleton != null ? ConvertSkeleton(xivSkeleton) : null; - var meshes = ConvertMeshes(mdl, gltfSkeleton); + var materials = ConvertMaterials(mdl); + var meshes = ConvertMeshes(mdl, materials, gltfSkeleton); return new Model(meshes, gltfSkeleton); } /// Convert a .mdl to a mesh (group) per LoD. - private static List ConvertMeshes(MdlFile mdl, GltfSkeleton? skeleton) + private static List ConvertMeshes(MdlFile mdl, MaterialBuilder[] materials, GltfSkeleton? skeleton) { var meshes = new List(); @@ -41,7 +43,7 @@ public class ModelExporter // TODO: consider other types of mesh? for (ushort meshOffset = 0; meshOffset < lod.MeshCount; meshOffset++) { - var mesh = MeshExporter.Export(mdl, lodIndex, (ushort)(lod.MeshIndex + meshOffset), skeleton); + var mesh = MeshExporter.Export(mdl, lodIndex, (ushort)(lod.MeshIndex + meshOffset), materials, skeleton); meshes.Add(mesh); } } @@ -49,6 +51,18 @@ public class ModelExporter return meshes; } + // TODO: Compose textures for use with these materials + /// Build placeholder materials for each of the material slots in the .mdl. + private static MaterialBuilder[] ConvertMaterials(MdlFile mdl) + => mdl.Materials + .Select(name => + new MaterialBuilder(name) + .WithMetallicRoughnessShader() + .WithDoubleSide(true) + .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, Vector4.One) + ) + .ToArray(); + /// Convert XIV skeleton data into a glTF-compatible node tree, with mappings. private static GltfSkeleton? ConvertSkeleton(IEnumerable skeletons) { @@ -60,7 +74,7 @@ public class ModelExporter var iterator = skeletons.SelectMany(skeleton => skeleton.Bones.Select(bone => (skeleton, bone))); foreach (var (skeleton, bone) in iterator) { - if (names.ContainsKey(bone.Name)) + if (names.ContainsKey(bone.Name)) continue; var node = new NodeBuilder(bone.Name);