/// <summary>
        /// Build final model using immutable parts and given matrices.
        /// </summary>
        /// <returns></returns>
        public Kkdf2MdlxBuiltModel ProcessVerticesAndBuildModel(Matrix[] matrices)
        {
            var models = new SortedDictionary <Tuple <int, bool>, Model>();

            var exportedMesh = new ExportedMesh();

            {
                int         vertexBaseIndex = 0;
                int         uvBaseIndex     = 0;
                VertexRef[] ringBuffer      = new VertexRef[4];
                int         ringIndex       = 0;
                int[]       triangleOrder   = new int[] { 1, 3, 2 };
                foreach (ImmutableMesh mesh in immultableMeshList)
                {
                    for (int x = 0; x < mesh.indexAssignmentList.Length; x++)
                    {
                        var indexAssign = mesh.indexAssignmentList[x];

                        VertexRef vertexRef = new VertexRef(
                            vertexBaseIndex + indexAssign.indexToVertexAssignment,
                            uvBaseIndex + x
                            );
                        ringBuffer[ringIndex] = vertexRef;
                        ringIndex             = (ringIndex + 1) & 3;
                        int flag = indexAssign.vertexFlag;
                        if (flag == 0x20 || flag == 0x00)
                        {
                            var triRef = new TriangleRef(mesh.textureIndex, mesh.isOpaque,
                                                         ringBuffer[(ringIndex - triangleOrder[0]) & 3],
                                                         ringBuffer[(ringIndex - triangleOrder[1]) & 3],
                                                         ringBuffer[(ringIndex - triangleOrder[2]) & 3]
                                                         );
                            exportedMesh.triangleRefList.Add(triRef);
                        }
                        if (flag == 0x30 || flag == 0x00)
                        {
                            var triRef = new TriangleRef(mesh.textureIndex, mesh.isOpaque,
                                                         ringBuffer[(ringIndex - triangleOrder[0]) & 3],
                                                         ringBuffer[(ringIndex - triangleOrder[2]) & 3],
                                                         ringBuffer[(ringIndex - triangleOrder[1]) & 3]
                                                         );
                            exportedMesh.triangleRefList.Add(triRef);
                        }
                    }

                    exportedMesh.positionList.AddRange(
                        mesh.vertexAssignmentsList.Select(
                            vertexAssigns =>
                    {
                        Vector3 finalPos = Vector3.Zero;
                        if (vertexAssigns.Length == 1)
                        {
                            // single joint
                            finalPos = TransformCoordinate(
                                VCUt.V4To3(
                                    vertexAssigns[0].rawPos
                                    ),
                                matrices[vertexAssigns[0].matrixIndex]
                                );
                        }
                        else
                        {
                            // multiple joints, using rawPos.W as blend weights
                            foreach (VertexAssignment vertexAssign in vertexAssigns)
                            {
                                finalPos += VCUt.V4To3(
                                    Transform(
                                        vertexAssign.rawPos,
                                        matrices[vertexAssign.matrixIndex]
                                        )
                                    );
                            }
                        }
                        return(finalPos);
                    }
                            )
                        );

                    exportedMesh.uvList.AddRange(
                        mesh.indexAssignmentList
                        .Select(indexAssign => indexAssign.uv)
                        );

                    vertexBaseIndex += mesh.vertexAssignmentsList.Length;
                    uvBaseIndex     += mesh.indexAssignmentList.Length;
                }
            }

            {
                int triangleRefCount = exportedMesh.triangleRefList.Count;
                for (int triIndex = 0; triIndex < triangleRefCount; triIndex++)
                {
                    TriangleRef       triRef   = exportedMesh.triangleRefList[triIndex];
                    Tuple <int, bool> modelKey = new Tuple <int, bool>(triRef.textureIndex, triRef.isOpaque);
                    Model             model;
                    if (models.TryGetValue(modelKey, out model) == false)
                    {
                        models[modelKey] = model = new Model();
                    }
                    for (int i = 0; i < triRef.list.Length; i++)
                    {
                        VertexRef vertRef = triRef.list[i];
                        Vector3   pos     = exportedMesh.positionList[vertRef.vertexIndex];
                        Vector2   uv      = exportedMesh.uvList[vertRef.uvIndex];
                        model.Vertices.Add(new CustomVertex.PositionColoredTextured(pos, -1, uv.X, uv.Y));
                    }
                }
            }

            return(new Kkdf2MdlxBuiltModel
            {
                textureIndexBasedModelDict = models,
                parser = this,
            });
        }
示例#2
0
        /// <summary>
        /// Build final model using immutable parts and given matrices.
        /// </summary>
        /// <returns></returns>
        public List <MeshDescriptor> ProcessVerticesAndBuildModel(Matrix4x4[] matrices)
        {
            var exportedMesh = new ExportedMesh();

            {
                int         vertexBaseIndex = 0;
                int         uvBaseIndex     = 0;
                VertexRef[] ringBuffer      = new VertexRef[4];
                int         ringIndex       = 0;
                int[]       triangleOrder   = new int[] { 1, 3, 2 };
                foreach (ImmutableMesh mesh in immultableMeshList)
                {
                    var part = new ExportedMesh.Part
                    {
                        meshRef = mesh,
                    };

                    for (int x = 0; x < mesh.indexAssignmentList.Length; x++)
                    {
                        var indexAssign = mesh.indexAssignmentList[x];

                        VertexRef vertexRef = new VertexRef(
                            vertexBaseIndex + indexAssign.indexToVertexAssignment,
                            uvBaseIndex + x
                            );
                        ringBuffer[ringIndex] = vertexRef;
                        ringIndex             = (ringIndex + 1) & 3;
                        int flag = indexAssign.vertexFlag;
                        if (flag == 0x20 || flag == 0x00)
                        {
                            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 == 0x30 || flag == 0x00)
                        {
                            var triRef = new TriangleRef(
                                ringBuffer[(ringIndex - triangleOrder[0]) & 3],
                                ringBuffer[(ringIndex - triangleOrder[2]) & 3],
                                ringBuffer[(ringIndex - triangleOrder[1]) & 3]
                                );
                            part.triangleRefList.Add(triRef);
                        }
                    }

                    exportedMesh.positionList.AddRange(
                        mesh.vertexAssignmentsList.Select(
                            vertexAssigns =>
                    {
                        Vector3 finalPos = Vector3.Zero;
                        if (vertexAssigns.Length == 1)
                        {
                            // single joint
                            finalPos = Vector3.Transform(
                                VCUt.V4To3(
                                    vertexAssigns[0].rawPos
                                    ),
                                matrices[vertexAssigns[0].matrixIndex]
                                );
                        }
                        else
                        {
                            // multiple joints, using rawPos.W as blend weights
                            foreach (VertexAssignment vertexAssign in vertexAssigns)
                            {
                                finalPos += VCUt.V4To3(
                                    Vector4.Transform(
                                        vertexAssign.rawPos,
                                        matrices[vertexAssign.matrixIndex]
                                        )
                                    );
                            }
                        }
                        return(finalPos);
                    }
                            )
                        );

                    exportedMesh.uvList.AddRange(
                        mesh.indexAssignmentList
                        .Select(indexAssign => indexAssign.uv)
                        );

                    exportedMesh.partList.Add(part);

                    vertexBaseIndex += mesh.vertexAssignmentsList.Length;
                    uvBaseIndex     += mesh.indexAssignmentList.Length;
                }
            }

            var newList = new List <MeshDescriptor>();

            foreach (var part in exportedMesh.partList)
            {
                var vertices = new List <CustomVertex.PositionColoredTextured>();
                var indices  = new List <int>();

                int triangleRefCount = part.triangleRefList.Count;
                for (int triIndex = 0; triIndex < triangleRefCount; triIndex++)
                {
                    TriangleRef triRef = part.triangleRefList[triIndex];
                    for (int i = 0; i < triRef.list.Length; i++)
                    {
                        VertexRef vertRef = triRef.list[i];
                        Vector3   pos     = exportedMesh.positionList[vertRef.vertexIndex];
                        Vector2   uv      = exportedMesh.uvList[vertRef.uvIndex];
                        indices.Add(vertices.Count);
                        vertices.Add(new CustomVertex.PositionColoredTextured(pos, -1, uv.X, uv.Y));
                    }
                }

                newList.Add(
                    new MeshDescriptor
                {
                    IsOpaque     = part.meshRef.isOpaque,
                    TextureIndex = part.meshRef.textureIndex,
                    Vertices     = vertices.ToArray(),
                    Indices      = indices.ToArray(),
                }
                    );
            }

            return(newList);
        }