private Assimp.Mesh ExtractMeshPartGeometry(int meshIndex, int partIndex)
{
// create new assimp mesh
Assimp.Mesh mesh = new Assimp.Mesh();
// Add support for multiple UV layers
var textureCoordinateIndex = 0;
mesh.UVComponentCount[textureCoordinateIndex] = 2;
// prepare vertex extraction
var meshReader = new MeshReader(CacheContext.Version, RenderModel.Geometry.Meshes[meshIndex], RenderModelResourceDefinition);
var vertexCompressor = new VertexCompressor(RenderModel.Geometry.Compression[0]);
var geometryMesh = RenderModel.Geometry.Meshes[meshIndex];
var geometryPart = geometryMesh.Parts[partIndex];
mesh.MaterialIndex = geometryPart.MaterialIndex;
// optimize this part to not load and decompress all mesh vertices everytime
var vertices = ReadVertices(meshReader, RenderModelResourceStream);
DecompressVertices(vertices, vertexCompressor);
// get offset in the list of all vertices for the mesh
var vertexOffset = GetPartVertexOffset(meshIndex, partIndex);
//vertices = vertices.GetRange(vertexOffset, geometryPart.VertexCount);
var indices = ReadIndices(meshReader, geometryPart, RenderModelResourceStream);
var int_indices = indices.Select(b => (int)b).ToArray();
var indexCount = indices.Length;
if (indexCount == 0)
{
Console.WriteLine($"Failed to extract mesh, no indices.");
return(null);
}
// set index list, maybe require adjustment for vertex buffer offset
mesh.SetIndices(int_indices, 3);
// build skeleton for each mesh (meh)
// create a list of all the mesh bones available in the scene
foreach (var node in RenderModel.Nodes)
{
Bone bone = new Bone();
bone.Name = CacheContext.GetString(node.Name);
bone.OffsetMatrix = new Matrix4x4();
mesh.Bones.Add(bone);
}
for (int i = vertexOffset; i < vertexOffset + geometryPart.VertexCount; i++)
{
var vertex = vertices[i];
mesh.Vertices.Add(vertex.Position);
if (vertex.Normal != null)
{
mesh.Normals.Add(vertex.Normal);
}
if (vertex.TexCoords != null)
{
mesh.TextureCoordinateChannels[textureCoordinateIndex].Add(vertex.TexCoords);
}
if (vertex.Tangents != null)
{
mesh.Tangents.Add(vertex.Tangents);
}
if (vertex.Binormals != null)
{
mesh.BiTangents.Add(vertex.Binormals);
}
if (vertex.Indices != null)
{
for (int j = 0; j < vertex.Indices.Length; j++)
{
var index = vertex.Indices[j];
var bone = mesh.Bones[index];
Matrix4x4 inverseTransform = new Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
var currentNode = BoneNodes[index];
while (currentNode != null)
{
Matrix4x4 inverse = (currentNode.Transform.DeepClone());
inverse.Inverse();
inverseTransform = inverse * inverseTransform;
currentNode = currentNode.Parent;
}
bone.OffsetMatrix = inverseTransform;
bone.VertexWeights.Add(new VertexWeight(i - vertexOffset, vertex.Weights[j]));
}
}
// Add skinned mesh support and more
}
// create faces
mesh.Faces.Clear();
GenerateFaces(int_indices, vertexOffset, mesh.Faces);
return(mesh);
}