예제 #1
0
 /// <summary>
 /// Searches for a halfedge pointing to a vertex from this vertex.
 /// </summary>
 /// <param name="vertex">A vertex pointed to by the halfedge to search for.</param>
 /// <returns>The halfedge from this vertex to the specified vertex. If none exists, returns null.</returns>
 public DXHalfedge FindHalfedgeTo(DXVertex vertex)
 {
     foreach (DXHalfedge h in Halfedges)
     {
         if (h.ToVertex == vertex)
         {
             return(h);
         }
     }
     return(null);
 }
예제 #2
0
        /// <summary>
        /// Triangulates a mesh.
        /// </summary>
        /// <returns>A triangulated copy of the mesh.</returns>
        /// <remarks>
        /// Any edge and halfedge traits are not copied to the new mesh. Face traits are copied
        /// to all faces triangulated from a face.
        /// </remarks>
        public DXMesh <TEdgeTraits, TFaceTraits, THalfedgeTraits, TVertexTraits> TriangularCopy()
        {
            DXMesh <TEdgeTraits, TFaceTraits, THalfedgeTraits, TVertexTraits> triangulatedMesh = new DXMesh <TEdgeTraits, TFaceTraits, THalfedgeTraits, TVertexTraits>();
            Dictionary <DXVertex, DXVertex> newVertices = new Dictionary <DXVertex, DXVertex>();

            foreach (DXVertex v in Vertices)
            {
                newVertices[v] = triangulatedMesh.Vertices.Add(v.Traits);
            }

            foreach (DXFace f in Faces)
            {
                DXVertex[] vertices = new DXVertex[f.VertexCount];
                int        i        = 0;
                foreach (DXVertex v in f.Vertices)
                {
                    vertices[i] = newVertices[v];
                    ++i;
                }
                triangulatedMesh.Faces.AddTriangles(f.Traits, vertices);
            }

            return(triangulatedMesh);
        }
예제 #3
0
파일: DirectX.cs 프로젝트: hejob/SB3Utility
            private void ImportMesh(Section section, ImportedMesh meshList, SortedDictionary<string, byte> boneDic, List<bool> hasBonesList)
            {
                int vertIdxOffset = 0;
                foreach (ImportedSubmesh submesh in meshList.SubmeshList)
                {
                    vertIdxOffset += submesh.VertexList.Count;
                }

                LinkedListNode<object> node = section.data.First;
                int numVertices = ConvertInt32(node.Value);
                node = node.Next;
                DXVertex[] vertices = new DXVertex[numVertices];
                for (int i = 0; i < numVertices; i++)
                {
                    vertices[i] = new DXVertex();
                    float[] pos = new float[3];
                    for (int j = 0; j < pos.Length; j++)
                    {
                        pos[j] = ConvertFloat(node.Value);
                        node = node.Next;
                    }
                    pos[2] = -pos[2];
                    vertices[i].position = pos;
                }

                int numFaces = ConvertInt32(node.Value);
                node = node.Next;
                DXFace[] faces = new DXFace[numFaces];
                for (int i = 0; i < numFaces; i++)
                {
                    int numFaceVerts = ConvertInt32(node.Value);
                    node = node.Next;
                    if (numFaceVerts != 3)
                    {
                        throw new Exception("Meshes must be triangulated");
                    }

                    faces[i] = new DXFace();
                    faces[i].vertexIndices[0] = ConvertUInt16(node.Value);
                    node = node.Next;
                    faces[i].vertexIndices[2] = ConvertUInt16(node.Value);
                    node = node.Next;
                    faces[i].vertexIndices[1] = ConvertUInt16(node.Value);
                    node = node.Next;
                }

                string[] materials = new string[] { String.Empty };
                bool hasNormals = false;
                bool hasBones = false;
                bool hasUVs = false;
                List<KeyValuePair<byte, float>>[] boneAssignments = new List<KeyValuePair<byte, float>>[numVertices];
                for (int i = 0; i < boneAssignments.Length; i++)
                {
                    boneAssignments[i] = new List<KeyValuePair<byte, float>>();
                }
                foreach (Section child in section.children)
                {
                    if (child.type == "VertexDuplicationIndices")
                    {
                    }
                    else if (child.type == "MeshNormals")
                    {
                        hasNormals = true;
                        LinkedListNode<object> childNode = child.data.First;
                        int numNormals = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        if (numNormals != numVertices)
                        {
                            throw new Exception("Number of normals doesn't match the number of vertices");
                        }
                        foreach (DXVertex vert in vertices)
                        {
                            float[] norm = new float[3];
                            for (int i = 0; i < norm.Length; i++)
                            {
                                norm[i] = ConvertFloat(childNode.Value);
                                childNode = childNode.Next;
                            }
                            norm[2] = -norm[2];
                            vert.normal = norm;
                        }
                    }
                    else if (child.type == "MeshTextureCoords")
                    {
                        hasUVs = true;
                        LinkedListNode<object> childNode = child.data.First;
                        int numTexCoords = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        if (numTexCoords != numVertices)
                        {
                            throw new Exception("Number of texture coordinates doesn't match the number of vertices");
                        }
                        foreach (DXVertex vert in vertices)
                        {
                            float[] uv = new float[2];
                            for (int i = 0; i < uv.Length; i++)
                            {
                                uv[i] = ConvertFloat(childNode.Value);
                                childNode = childNode.Next;
                            }
                            vert.uv = uv;
                        }
                    }
                    else if (child.type == "MeshMaterialList")
                    {
                        materials = ImportMaterials(child, faces);
                    }
                    else if (child.type == "XSkinMeshHeader")
                    {
                        hasBones = true;
                    }
                    else if (child.type == "SkinWeights")
                    {
                        LinkedListNode<object> childNode = child.data.First;
                        string boneName = ConvertString(childNode.Value);
                        childNode = childNode.Next;
                        int numWeights = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        int[] vertIndices = new int[numWeights];
                        for (int i = 0; i < numWeights; i++)
                        {
                            vertIndices[i] = ConvertInt32(childNode.Value);
                            childNode = childNode.Next;
                        }
                        float[] weights = new float[numWeights];
                        for (int i = 0; i < numWeights; i++)
                        {
                            weights[i] = ConvertFloat(childNode.Value);
                            childNode = childNode.Next;
                        }

                        byte boneIdx;
                        if (!boneDic.TryGetValue(boneName, out boneIdx))
                        {
                            boneIdx = (byte)boneDic.Count;
                            boneDic.Add(boneName, boneIdx);

                            ImportedBone boneInfo = new ImportedBone();
                            meshList.BoneList.Add(boneInfo);
                            boneInfo.Name = boneName;

                            Matrix matrix = new Matrix();
                            for (int i = 0; i < 4; i++)
                            {
                                for (int j = 0; j < 4; j++)
                                {
                                    matrix[i, j] = ConvertFloat(childNode.Value);
                                    childNode = childNode.Next;
                                }
                            }
                            boneInfo.Matrix = RHToLHMatrix(matrix);
                        }

                        for (int i = 0; i < numWeights; i++)
                        {
                            boneAssignments[vertIndices[i]].Add(new KeyValuePair<byte, float>(boneIdx, weights[i]));
                        }
                    }
                    else
                    {
                        Report.ReportLog("Warning: unexpected section " + child.type);
                    }
                }

                if (hasBones)
                {
                    for (int i = 0; i < boneAssignments.Length; i++)
                    {
                        byte[] boneIndices = new byte[4];
                        float[] weights4 = new float[4];
                        for (int j = 0; (j < 4) && (j < boneAssignments[i].Count); j++)
                        {
                            boneIndices[j] = boneAssignments[i][j].Key;
                            weights4[j] = boneAssignments[i][j].Value;
                        }
                        for (int j = boneAssignments[i].Count; j < 4; j++)
                        {
                            boneIndices[j] = 0xFF;
                            weights4[j] = 0;
                        }

                        vertices[i].boneIndices = boneIndices;
                        vertices[i].weights = new float[] { weights4[0], weights4[1], weights4[2], weights4[3] };
                    }
                }

                SortedDictionary<ushort, ushort>[] vertexMaps = new SortedDictionary<ushort, ushort>[materials.Length];
                ImportedSubmesh[] submeshes = new ImportedSubmesh[materials.Length];
                for (int i = 0; i < materials.Length; i++)
                {
                    submeshes[i] = new ImportedSubmesh();
                    submeshes[i].Material = materials[i];
                    submeshes[i].VertexList = new List<ImportedVertex>(vertices.Length);
                    submeshes[i].FaceList = new List<ImportedFace>(faces.Length);
                    vertexMaps[i] = new SortedDictionary<ushort, ushort>();
                }

                foreach (DXFace dxFace in faces)
                {
                    ImportedSubmesh submesh = submeshes[dxFace.materialIndex];
                    ImportedFace face = new ImportedFace();
                    submesh.FaceList.Add(face);

                    ushort[] foundVertexIndices = new ushort[3];
                    for (int i = 0; i < dxFace.vertexIndices.Length; i++)
                    {
                        ushort dxVertIdx = dxFace.vertexIndices[i];
                        SortedDictionary<ushort, ushort> vertexMap = vertexMaps[dxFace.materialIndex];
                        if (!vertexMap.TryGetValue(dxVertIdx, out foundVertexIndices[i]))
                        {
                            DXVertex dxVert = vertices[dxVertIdx];
                            ImportedVertex vert = new ImportedVertex();
                            submesh.VertexList.Add(vert);
                            if (hasNormals)
                            {
                                vert.Normal = new Vector3(dxVert.normal[0], dxVert.normal[1], dxVert.normal[2]);
                            }
                            if (hasUVs)
                            {
                                vert.UV = (float[])dxVert.uv.Clone();
                            }
                            if (hasBones)
                            {
                                vert.BoneIndices = (byte[])dxVert.boneIndices.Clone();
                                vert.Weights = (float[])dxVert.weights.Clone();
                            }
                            vert.Position = new Vector3(dxVert.position[0], dxVert.position[1], dxVert.position[2]);
                            vertIdxOffset++;

                            foundVertexIndices[i] = (ushort)vertexMap.Count;
                            vertexMap.Add(dxVertIdx, foundVertexIndices[i]);
                        }
                    }

                    face.VertexIndices = new int[] { foundVertexIndices[0], foundVertexIndices[1], foundVertexIndices[2] };
                }

                foreach (ImportedSubmesh submesh in submeshes)
                {
                    if (submesh.VertexList.Count > 0)
                    {
                        submesh.VertexList.TrimExcess();
                        submesh.FaceList.TrimExcess();
                        submesh.Index = meshList.SubmeshList.Count;
                        meshList.SubmeshList.Add(submesh);
                        hasBonesList.Add(hasBones);

                        if (!hasNormals)
                        {
                            for (int i = 0; i < submesh.VertexList.Count; i++)
                            {
                                submesh.VertexList[i].Normal = new Vector3();
                            }
                        }
                    }
                }
            }
예제 #4
0
 /// <summary>
 /// Adds a vertex to the vertex list.
 /// </summary>
 /// <param name="vertex">The vertex to add.</param>
 protected void AppendToVertexList(DXVertex vertex)
 {
     vertex.Index = vertices.Count;
     vertex.Mesh  = this;
     vertices.Add(vertex);
 }