mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 20:54:16 +01:00
Quick submesh implementation
This commit is contained in:
parent
727fa3c183
commit
f7a2c17415
2 changed files with 25 additions and 13 deletions
|
|
@ -10,7 +10,7 @@ namespace Penumbra.Import.Modules;
|
||||||
|
|
||||||
public sealed class MeshConverter
|
public sealed class MeshConverter
|
||||||
{
|
{
|
||||||
public static IMeshBuilder<MaterialBuilder> ToGltf(MdlFile mdl, byte lod, ushort meshIndex, Dictionary<string, int>? boneNameMap)
|
public static IMeshBuilder<MaterialBuilder>[] ToGltf(MdlFile mdl, byte lod, ushort meshIndex, Dictionary<string, int>? boneNameMap)
|
||||||
{
|
{
|
||||||
var self = new MeshConverter(mdl, lod, meshIndex, boneNameMap);
|
var self = new MeshConverter(mdl, lod, meshIndex, boneNameMap);
|
||||||
return self.BuildMesh();
|
return self.BuildMesh();
|
||||||
|
|
@ -65,12 +65,23 @@ public sealed class MeshConverter
|
||||||
return indexMap;
|
return indexMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider a struct return type
|
private IMeshBuilder<MaterialBuilder>[] BuildMesh()
|
||||||
private IMeshBuilder<MaterialBuilder> BuildMesh()
|
|
||||||
{
|
{
|
||||||
var indices = BuildIndices();
|
|
||||||
var vertices = BuildVertices();
|
var vertices = BuildVertices();
|
||||||
|
|
||||||
|
// TODO: handle submeshCount = 0
|
||||||
|
|
||||||
|
return _mdl.SubMeshes
|
||||||
|
.Skip(Mesh.SubMeshIndex)
|
||||||
|
.Take(Mesh.SubMeshCount)
|
||||||
|
.Select(submesh => BuildSubMesh(submesh, vertices))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IMeshBuilder<MaterialBuilder> BuildSubMesh(MdlStructs.SubmeshStruct submesh, IReadOnlyList<IVertexBuilder> vertices)
|
||||||
|
{
|
||||||
|
var indices = BuildIndices(submesh);
|
||||||
|
|
||||||
var meshBuilderType = typeof(MeshBuilder<,,,>).MakeGenericType(
|
var meshBuilderType = typeof(MeshBuilder<,,,>).MakeGenericType(
|
||||||
typeof(MaterialBuilder),
|
typeof(MaterialBuilder),
|
||||||
_geometryType,
|
_geometryType,
|
||||||
|
|
@ -89,7 +100,7 @@ public sealed class MeshConverter
|
||||||
|
|
||||||
// All XIV meshes use triangle lists.
|
// All XIV meshes use triangle lists.
|
||||||
// TODO: split by submeshes
|
// TODO: split by submeshes
|
||||||
for (var indexOffset = 0; indexOffset < Mesh.IndexCount; indexOffset += 3)
|
for (var indexOffset = 0; indexOffset < submesh.IndexCount; indexOffset += 3)
|
||||||
primitiveBuilder.AddTriangle(
|
primitiveBuilder.AddTriangle(
|
||||||
vertices[indices[indexOffset + 0]],
|
vertices[indices[indexOffset + 0]],
|
||||||
vertices[indices[indexOffset + 1]],
|
vertices[indices[indexOffset + 1]],
|
||||||
|
|
@ -99,11 +110,11 @@ public sealed class MeshConverter
|
||||||
return meshBuilder;
|
return meshBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IReadOnlyList<ushort> BuildIndices()
|
private IReadOnlyList<ushort> BuildIndices(MdlStructs.SubmeshStruct submesh)
|
||||||
{
|
{
|
||||||
var reader = new BinaryReader(new MemoryStream(_mdl.RemainingData));
|
var reader = new BinaryReader(new MemoryStream(_mdl.RemainingData));
|
||||||
reader.Seek(_mdl.IndexOffset[_lod] + Mesh.StartIndex * sizeof(ushort));
|
reader.Seek(_mdl.IndexOffset[_lod] + submesh.IndexOffset * sizeof(ushort));
|
||||||
return reader.ReadStructuresAsArray<ushort>((int)Mesh.IndexCount);
|
return reader.ReadStructuresAsArray<ushort>((int)submesh.IndexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IReadOnlyList<IVertexBuilder> BuildVertices()
|
private IReadOnlyList<IVertexBuilder> BuildVertices()
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,9 @@ public sealed class ModelManager : SingleTaskQueue, IDisposable
|
||||||
// TODO: consider other types of mesh?
|
// TODO: consider other types of mesh?
|
||||||
for (ushort meshOffset = 0; meshOffset < lod.MeshCount; meshOffset++)
|
for (ushort meshOffset = 0; meshOffset < lod.MeshCount; meshOffset++)
|
||||||
{
|
{
|
||||||
var meshBuilder = MeshConverter.ToGltf(_mdl, lodIndex, (ushort)(lod.MeshIndex + meshOffset), skeleton?.Names);
|
var meshBuilders = MeshConverter.ToGltf(_mdl, lodIndex, (ushort)(lod.MeshIndex + meshOffset), skeleton?.Names);
|
||||||
// TODO: use a value from the mesh converter for this check, rather than assuming that it has joints
|
// TODO: use a value from the mesh converter for this check, rather than assuming that it has joints
|
||||||
|
foreach (var meshBuilder in meshBuilders)
|
||||||
if (skeleton == null)
|
if (skeleton == null)
|
||||||
scene.AddRigidMesh(meshBuilder, Matrix4x4.Identity);
|
scene.AddRigidMesh(meshBuilder, Matrix4x4.Identity);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue