Export material names

This commit is contained in:
ackwell 2024-01-10 01:17:47 +11:00
parent 36cbca4684
commit 3cd438bb5d
2 changed files with 27 additions and 15 deletions

View file

@ -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<ushort, int>? _boneIndexMap;
private readonly Type _geometryType;
private readonly Type _materialType;
private readonly Type _skinningType;
private MeshExporter(MdlFile mdl, byte lod, ushort meshIndex, IReadOnlyDictionary<string, int>? boneNameMap)
private MeshExporter(MdlFile mdl, byte lod, ushort meshIndex, MaterialBuilder[] materials, IReadOnlyDictionary<string, int>? 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<MaterialBuilder>)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<int>();

View file

@ -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>? 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);
}
/// <summary> Convert a .mdl to a mesh (group) per LoD. </summary>
private static List<MeshExporter.Mesh> ConvertMeshes(MdlFile mdl, GltfSkeleton? skeleton)
private static List<MeshExporter.Mesh> ConvertMeshes(MdlFile mdl, MaterialBuilder[] materials, GltfSkeleton? skeleton)
{
var meshes = new List<MeshExporter.Mesh>();
@ -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
/// <summary> Build placeholder materials for each of the material slots in the .mdl. </summary>
private static MaterialBuilder[] ConvertMaterials(MdlFile mdl)
=> mdl.Materials
.Select(name =>
new MaterialBuilder(name)
.WithMetallicRoughnessShader()
.WithDoubleSide(true)
.WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, Vector4.One)
)
.ToArray();
/// <summary> Convert XIV skeleton data into a glTF-compatible node tree, with mappings. </summary>
private static GltfSkeleton? ConvertSkeleton(IEnumerable<XivSkeleton> 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);