Esempio n. 1
0
 /// <summary>
 /// Searches for the halfedge pointing to the specified face from this vertex.
 /// </summary>
 /// <param name="face">The face the halfedge to find points to.</param>
 /// <returns>The halfedge if it is found, otherwise null.</returns>
 public DXHalfedge FindHalfedgeTo(DXFace face)
 {
     foreach (DXHalfedge h in Halfedges)
     {
         if (h.Face == face)
         {
             return(h);
         }
     }
     return(null);
 }
Esempio n. 2
0
        /// <summary>
        /// Determines if two faces are adjacent.
        /// </summary>
        /// <param name="faceA">One of the faces to search for.</param>
        /// <param name="faceB">The other face to search for.</param>
        /// <returns>True if the faces are adjacent, false if they are not.</returns>
        public static bool FacesShareEdge(DXFace faceA, DXFace faceB)
        {
            foreach (DXFace f in faceA.Faces)
            {
                if (f == faceB)
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 3
0
            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();
                            }
                        }
                    }
                }
            }
Esempio n. 4
0
            private string[] ImportMaterials(Section section, DXFace[] faces)
            {
                LinkedListNode<object> node = section.data.First;

                int numMaterials = ConvertInt32(node.Value);
                node = node.Next;
                if (numMaterials != section.children.Count)
                {
                    throw new Exception("number of materials doesn't match number of children");
                }

                int numFaces = ConvertInt32(node.Value);
                node = node.Next;
                if (numFaces != faces.Length)
                {
                    throw new Exception("number of faces doesn't match with material");
                }
                for (int i = 0; i < numFaces; i++)
                {
                    faces[i].materialIndex = ConvertInt32(node.Value);
                    node = node.Next;
                }

                string[] materialNames = new string[numMaterials];
                for (int i = 0; i < numMaterials; i++)
                {
                    Section matSection = section.children[i];
                    if (matSection.type == "Material")
                    {
                        string texName = String.Empty;
                        foreach (Section texSection in matSection.children)
                        {
                            if (texSection.type == "TextureFilename")
                            {
                                texName = ImportTexture(texSection);
                                break;
                            }
                            else
                            {
                                Report.ReportLog("Warning: unexpected section " + matSection.type);
                            }
                        }

                        if (matSection.name == null)
                        {
                            if (texName == String.Empty)
                            {
                                materialNames[i] = "no_name_" + noNameCount;
                            }
                            else
                            {
                                materialNames[i] = Path.GetFileNameWithoutExtension(texName) + "_" + noNameCount;
                            }
                            noNameCount++;
                        }
                        else
                        {
                            materialNames[i] = matSection.name;
                        }

                        if (matList.Add(materialNames[i]))
                        {
                            LinkedListNode<object> dataNode = section.children[i].data.First;
                            ImportedMaterial matInfo = new ImportedMaterial();
                            matInfo.Name = materialNames[i];
                            matInfo.Diffuse = new Color4(1, 1, 1, 1);

                            float[] ambient = new float[4];
                            for (int j = 0; j < ambient.Length; j++)
                            {
                                ambient[j] = ConvertFloat(dataNode.Value);
                                dataNode = dataNode.Next;
                            }
                            matInfo.Ambient = new Color4(ambient[3], ambient[0], ambient[1], ambient[2]);

                            matInfo.Power = ConvertFloat(dataNode.Value);
                            dataNode = dataNode.Next;

                            float[] specular = new float[4];
                            for (int j = 0; j < 3; j++)
                            {
                                specular[j] = ConvertFloat(dataNode.Value);
                                dataNode = dataNode.Next;
                            }
                            specular[3] = 1;
                            matInfo.Specular = new Color4(specular[3], specular[0], specular[1], specular[2]);

                            float[] emissive = new float[4];
                            for (int j = 0; j < 3; j++)
                            {
                                emissive[j] = ConvertFloat(dataNode.Value);
                                dataNode = dataNode.Next;
                            }
                            emissive[3] = 1;
                            matInfo.Emissive = new Color4(emissive[3], emissive[0], emissive[1], emissive[2]);

                            if (texName != String.Empty)
                            {
                                matInfo.Textures = new string[] { texName };
                            }

                            MaterialList.Add(matInfo);
                        }
                    }
                    else if (matSection.type == "ref")
                    {
                        if (matSection.name != null)
                        {
                            materialNames[i] = matSection.name;
                        }
                    }
                    else
                    {
                        Report.ReportLog("Warning: unexpected section " + matSection.type);
                    }
                }

                return materialNames;
            }
Esempio n. 5
0
 /// <summary>
 /// Adds a face to the face list.
 /// </summary>
 /// <param name="face">The face to add.</param>
 protected void AppendToFaceList(DXFace face)
 {
     face.Index = faces.Count;
     faces.Add(face);
 }