Import material names

This commit is contained in:
ackwell 2024-01-10 20:33:24 +11:00
parent 3cd438bb5d
commit d2f93f8562
3 changed files with 44 additions and 4 deletions

View file

@ -10,6 +10,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
public MdlStructs.MeshStruct MeshStruct; public MdlStructs.MeshStruct MeshStruct;
public List<MdlStructs.SubmeshStruct> SubMeshStructs; public List<MdlStructs.SubmeshStruct> SubMeshStructs;
public string? Material;
public MdlStructs.VertexDeclarationStruct VertexDeclaration; public MdlStructs.VertexDeclarationStruct VertexDeclaration;
public IEnumerable<byte> VertexBuffer; public IEnumerable<byte> VertexBuffer;
@ -35,6 +37,8 @@ public class MeshImporter(IEnumerable<Node> nodes)
private readonly List<MdlStructs.SubmeshStruct> _subMeshes = []; private readonly List<MdlStructs.SubmeshStruct> _subMeshes = [];
private string? _material;
private MdlStructs.VertexDeclarationStruct? _vertexDeclaration; private MdlStructs.VertexDeclarationStruct? _vertexDeclaration;
private byte[]? _strides; private byte[]? _strides;
private ushort _vertexCount; private ushort _vertexCount;
@ -74,6 +78,7 @@ public class MeshImporter(IEnumerable<Node> nodes)
BoneTableIndex = 0, BoneTableIndex = 0,
}, },
SubMeshStructs = _subMeshes, SubMeshStructs = _subMeshes,
Material = _material,
VertexDeclaration = _vertexDeclaration.Value, VertexDeclaration = _vertexDeclaration.Value,
VertexBuffer = _streams[0].Concat(_streams[1]).Concat(_streams[2]), VertexBuffer = _streams[0].Concat(_streams[1]).Concat(_streams[2]),
Indices = _indices, Indices = _indices,
@ -105,6 +110,9 @@ public class MeshImporter(IEnumerable<Node> nodes)
var subMeshName = node.Name ?? node.Mesh.Name; var subMeshName = node.Name ?? node.Mesh.Name;
// TODO: Record a warning if there's a mismatch between current and incoming, as we can't support multiple materials per mesh.
_material ??= subMesh.Material;
// Check that vertex declarations match - we need to combine the buffers, so a mismatch would take a whole load of resolution. // Check that vertex declarations match - we need to combine the buffers, so a mismatch would take a whole load of resolution.
if (_vertexDeclaration == null) if (_vertexDeclaration == null)
_vertexDeclaration = subMesh.VertexDeclaration; _vertexDeclaration = subMesh.VertexDeclaration;

View file

@ -19,6 +19,8 @@ public partial class ModelImporter(ModelRoot _model)
private readonly List<MdlStructs.MeshStruct> _meshes = []; private readonly List<MdlStructs.MeshStruct> _meshes = [];
private readonly List<MdlStructs.SubmeshStruct> _subMeshes = []; private readonly List<MdlStructs.SubmeshStruct> _subMeshes = [];
private readonly List<string> _materials = [];
private readonly List<MdlStructs.VertexDeclarationStruct> _vertexDeclarations = []; private readonly List<MdlStructs.VertexDeclarationStruct> _vertexDeclarations = [];
private readonly List<byte> _vertexBuffer = []; private readonly List<byte> _vertexBuffer = [];
@ -37,6 +39,8 @@ public partial class ModelImporter(ModelRoot _model)
BuildMeshForGroup(subMeshNodes); BuildMeshForGroup(subMeshNodes);
// Now that all the meshes have been built, we can build some of the model-wide metadata. // Now that all the meshes have been built, we can build some of the model-wide metadata.
var materials = _materials.Count > 0 ? _materials : ["/NO_MATERIAL"];
var shapes = new List<MdlFile.Shape>(); var shapes = new List<MdlFile.Shape>();
var shapeMeshes = new List<MdlStructs.ShapeMeshStruct>(); var shapeMeshes = new List<MdlStructs.ShapeMeshStruct>();
foreach (var (keyName, keyMeshes) in _shapeMeshes) foreach (var (keyName, keyMeshes) in _shapeMeshes)
@ -86,8 +90,7 @@ public partial class ModelImporter(ModelRoot _model)
}, },
], ],
// TODO: Would be good to populate from gltf material names. Materials = [.. materials],
Materials = ["/NO_MATERIAL"],
// TODO: Would be good to calculate all of this up the tree. // TODO: Would be good to calculate all of this up the tree.
Radius = 1, Radius = 1,
@ -130,15 +133,20 @@ public partial class ModelImporter(ModelRoot _model)
var mesh = MeshImporter.Import(subMeshNodes); var mesh = MeshImporter.Import(subMeshNodes);
var meshStartIndex = (uint)(mesh.MeshStruct.StartIndex + indexOffset); var meshStartIndex = (uint)(mesh.MeshStruct.StartIndex + indexOffset);
ushort materialIndex = 0;
if (mesh.Material != null)
materialIndex = GetMaterialIndex(mesh.Material);
// If no bone table is used for a mesh, the index is set to 255. // If no bone table is used for a mesh, the index is set to 255.
var boneTableIndex = 255; ushort boneTableIndex = 255;
if (mesh.Bones != null) if (mesh.Bones != null)
boneTableIndex = BuildBoneTable(mesh.Bones); boneTableIndex = BuildBoneTable(mesh.Bones);
_meshes.Add(mesh.MeshStruct with _meshes.Add(mesh.MeshStruct with
{ {
MaterialIndex = materialIndex,
SubMeshIndex = (ushort)(mesh.MeshStruct.SubMeshIndex + subMeshOffset), SubMeshIndex = (ushort)(mesh.MeshStruct.SubMeshIndex + subMeshOffset),
BoneTableIndex = (ushort)boneTableIndex, BoneTableIndex = boneTableIndex,
StartIndex = meshStartIndex, StartIndex = meshStartIndex,
VertexBufferOffset = mesh.MeshStruct.VertexBufferOffset VertexBufferOffset = mesh.MeshStruct.VertexBufferOffset
.Select(offset => (uint)(offset + vertexOffset)) .Select(offset => (uint)(offset + vertexOffset))
@ -173,6 +181,23 @@ public partial class ModelImporter(ModelRoot _model)
} }
} }
private ushort GetMaterialIndex(string materialName)
{
// If we already have this material, grab the current one
var index = _materials.IndexOf(materialName);
if (index >= 0)
return (ushort)index;
// If there's already 4 materials, we can't add any more.
// TODO: permit, with a warning to reduce, and validation in MdlTab.
var count = _materials.Count;
if (count >= 4)
return 0;
_materials.Add(materialName);
return (ushort)count;
}
private ushort BuildBoneTable(List<string> boneNames) private ushort BuildBoneTable(List<string> boneNames)
{ {
var boneIndices = new List<ushort>(); var boneIndices = new List<ushort>();

View file

@ -10,6 +10,8 @@ public class SubMeshImporter
{ {
public MdlStructs.SubmeshStruct SubMeshStruct; public MdlStructs.SubmeshStruct SubMeshStruct;
public string? Material;
public MdlStructs.VertexDeclarationStruct VertexDeclaration; public MdlStructs.VertexDeclarationStruct VertexDeclaration;
public ushort VertexCount; public ushort VertexCount;
@ -81,6 +83,10 @@ public class SubMeshImporter
ArgumentNullException.ThrowIfNull(_attributes); ArgumentNullException.ThrowIfNull(_attributes);
ArgumentNullException.ThrowIfNull(_shapeValues); ArgumentNullException.ThrowIfNull(_shapeValues);
var material = _primitive.Material.Name;
if (material == "")
material = null;
return new SubMesh() return new SubMesh()
{ {
SubMeshStruct = new MdlStructs.SubmeshStruct() SubMeshStruct = new MdlStructs.SubmeshStruct()
@ -93,6 +99,7 @@ public class SubMeshImporter
BoneStartIndex = 0, BoneStartIndex = 0,
BoneCount = 0, BoneCount = 0,
}, },
Material = material,
VertexDeclaration = new MdlStructs.VertexDeclarationStruct() VertexDeclaration = new MdlStructs.VertexDeclarationStruct()
{ {
VertexElements = _attributes.Select(attribute => attribute.Element).ToArray(), VertexElements = _attributes.Select(attribute => attribute.Element).ToArray(),