/// <summary> /// Build immutable parts from a submodel. /// </summary> /// <param name="submodel"></param> public Kkdf2MdlxParser(Mdlx.SubModel submodel) { immultableMeshList = submodel.DmaChains .Select(x => new ImmutableMesh(x)) .ToList(); immutableExportedMesh = PreProcessVerticesAndBuildModel(); }
private ExportedMesh PreProcessVerticesAndBuildModel() { var exportedMesh = new ExportedMesh(); exportedMesh.vertexAssignments = new List <VertexIndexWeighted[][]>(); exportedMesh.vertices = new List <Vector4[]>(); int vertexBaseIndex = 0; int uvBaseIndex = 0; VertexRef[] ringBuffer = new VertexRef[4]; int ringIndex = 0; int[] triangleOrder = new int[] { 1, 3, 2 }; foreach (ImmutableMesh meshRoot in immultableMeshList) { for (int i = 0; i < meshRoot.VpuPackets.Count; i++) { VpuPacket mesh = meshRoot.VpuPackets[i]; var part = new ExportedMesh.Part { TextureIndex = meshRoot.TextureIndex, IsOpaque = meshRoot.IsOpaque, }; for (int x = 0; x < mesh.Indices.Length; x++) { var indexAssign = mesh.Indices[x]; VertexRef vertexRef = new VertexRef( vertexBaseIndex + indexAssign.Index, uvBaseIndex + x ); ringBuffer[ringIndex] = vertexRef; ringIndex = (ringIndex + 1) & 3; var flag = indexAssign.Function; if (flag == VpuPacket.VertexFunction.DrawTriangle || flag == VpuPacket.VertexFunction.DrawTriangleDoubleSided) { var triRef = new TriangleRef( ringBuffer[(ringIndex - triangleOrder[0]) & 3], ringBuffer[(ringIndex - triangleOrder[1]) & 3], ringBuffer[(ringIndex - triangleOrder[2]) & 3] ); part.triangleRefList.Add(triRef); } if (flag == VpuPacket.VertexFunction.DrawTriangleInverse || flag == VpuPacket.VertexFunction.DrawTriangleDoubleSided) { var triRef = new TriangleRef( ringBuffer[(ringIndex - triangleOrder[0]) & 3], ringBuffer[(ringIndex - triangleOrder[2]) & 3], ringBuffer[(ringIndex - triangleOrder[1]) & 3] ); part.triangleRefList.Add(triRef); } } var vertices = mesh.Vertices .Select(vertex => new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W)) .ToArray(); exportedMesh.vertices.Add(vertices); var matrixIndexList = meshRoot.DmaChain.DmaVifs[i].Alaxi; var vertexAssignmentsList = mesh.GetWeightedVertices(mesh.GetFromMatrixIndices(matrixIndexList)); exportedMesh.vertexAssignments.Add(vertexAssignmentsList); exportedMesh.uvList.AddRange( mesh.Indices.Select(x => new Vector2(x.U / 16 / 256.0f, x.V / 16 / 256.0f)) ); exportedMesh.partList.Add(part); vertexBaseIndex += vertexAssignmentsList.Length; uvBaseIndex += mesh.Indices.Length; } } return(exportedMesh); }