예제 #1
0
        public MeshGeometry GetGeometry()
        {
            var geom = new MeshGeometry();

            //var verts = VertexDict.Values.SelectMany(x => x);
            geom.SetVertices(_Vertices);
            geom.SetTriangles(_Triangles);
            return(geom);
        }
예제 #2
0
        public void CombineGeometry(MeshGeometry geometry)
        {
            var triangleIndices = geometry.GetTriangleIndices();
            var addedVertices   = geometry.Vertices.Select(x => x.Clone()).ToList();

            int vertexOffset = VertexCount;

            addedVertices.ForEach(x => AddVertex(x, false));

            for (int i = 0; i < geometry.IndexCount; i += 3)
            {
                var triangle = AddTriangle(
                    triangleIndices[i] + vertexOffset,
                    triangleIndices[i + 1] + vertexOffset,
                    triangleIndices[i + 2] + vertexOffset);

                triangle.CopyIndexData(geometry.Triangles[i / 3]);
            }
        }
예제 #3
0
        public static MeshGeometry Combine(params MeshGeometry[] geometries)
        {
            if (geometries.Length == 1)
            {
                return(geometries[0]);
            }

            var verts     = new List <Vertex>();
            var triangles = new List <Triangle>();

            foreach (var geom in geometries)
            {
                verts.AddRange(geom.Vertices);
                triangles.AddRange(geom.Triangles);
            }

            var newGeom = new MeshGeometry();

            newGeom.SetVertices(verts);
            newGeom.SetTriangles(triangles);
            newGeom.BreakReferences();
            return(newGeom);
        }
예제 #4
0
        public static MeshGeometry Create(Files.MeshStructures.MESH_DATA mesh)
        {
            var  vertices   = new List <Vertex>();
            bool isTextured = mesh.UVs != null && mesh.UVs.Length > 0;
            bool isFlexible = mesh.Bones != null && mesh.Bones.Length > 0;

            for (int i = 0; i < mesh.Positions.Length; i++)
            {
                vertices.Add(new Vertex(
                                 mesh.Positions[i],
                                 mesh.Normals[i],
                                 isTextured ? mesh.UVs[i] : Vector2.Empty
                                 ));

                if (isFlexible)
                {
                    var bones = mesh.Bones[i];
                    for (int j = 0; j < bones.BoneWeights.Length; j++)
                    {
                        vertices[i].BoneWeights.Add(new BoneWeight(bones.BoneWeights[j].BoneID, bones.BoneWeights[j].Weight));
                    }
                }
            }
            var geom = new MeshGeometry();

            geom.SetVertices(vertices);

            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                geom.AddTriangleFromIndices(
                    mesh.Indices[i].VertexIndex,
                    mesh.Indices[i + 1].VertexIndex,
                    mesh.Indices[i + 2].VertexIndex);
            }

            return(geom);
        }
예제 #5
0
        public MeshGeometry Clone()
        {
            var geom = new MeshGeometry();

            geom._Vertices.AddRange(Vertices.Select(x => x.Clone()));

            var triIdx = GetTriangleIndices();

            for (int i = 0; i < triIdx.Length; i += 3)
            {
                geom._Triangles.Add(new Triangle(
                                        geom.Vertices[triIdx[i]],
                                        geom.Vertices[triIdx[i + 1]],
                                        geom.Vertices[triIdx[i + 2]]));
            }

            for (int i = 0; i < Indices.Count; i++)
            {
                geom.Indices[i].AverageNormal = Indices[i].AverageNormal;
                geom.Indices[i].RoundEdgeData = Indices[i].RoundEdgeData.Clone();
            }

            return(geom);
        }
예제 #6
0
        public void SeparateDistinctSurfaces()
        {
            var uniqueEdges = Triangles.SelectMany(t => t.Edges).EqualsDistinct().ToList();

            Edge.CompareByPosition = false;
            var edgeFaces = new Dictionary <Edge, List <Triangle> >();

            foreach (var tri in Triangles)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (edgeFaces.TryGetValue(tri.Edges[i], out List <Triangle> faces))
                    {
                        if (!faces.Contains(tri))
                        {
                            faces.Add(tri);
                        }
                    }
                    else
                    {
                        edgeFaces.Add(tri.Edges[i], new List <Triangle>()
                        {
                            tri
                        });
                    }
                }
            }

            var triList = Triangles.ToList();

            void AddConnectedFaces(Triangle tria, List <Triangle> remainingFaces, List <Triangle> currentFaces)
            {
                if (!currentFaces.Any())
                {
                    remainingFaces.Remove(tria);
                    currentFaces.Add(tria);
                }

                var connectedFaces = tria.Edges.SelectMany(x => edgeFaces[x]).Where(y => y != tria);
                var facesToAdd     = connectedFaces.Intersect(remainingFaces).ToList();

                foreach (var face in facesToAdd)
                {
                    remainingFaces.Remove(face);
                    currentFaces.Add(face);
                }

                foreach (var face in facesToAdd)
                {
                    AddConnectedFaces(face, remainingFaces, currentFaces);
                }
            }

            var geomList = new List <MeshGeometry>();

            while (triList.Any())
            {
                var curTri     = triList[0];
                var curTriList = new List <Triangle>();
                AddConnectedFaces(curTri, triList, curTriList);
                var curGeom = new MeshGeometry();
                curGeom.SetTriangles(curTriList, true);
                curGeom.BreakReferences();
                geomList.Add(curGeom);
            }
        }
예제 #7
0
        public static MeshGeometry FromXml(XDocument document)
        {
            var geomElem = document.Element("LddGeometry");

            if (geomElem == null)
            {
                return(null);
            }

            if (geomElem.HasElement("Positions", out XElement posElem) &&
                geomElem.HasElement("Normals", out XElement normElem) &&
                geomElem.HasElement("Indices", out XElement indElem))
            {
                var            positions = ParseVector3Array(posElem.Value);
                var            normals   = ParseVector3Array(normElem.Value);
                List <Vector2> uvs       = null;
                if (geomElem.HasElement("UVs", out XElement uvElem))
                {
                    uvs = ParseVector2Array(uvElem.Value);
                }

                var indices = indElem.Value.Split(' ').Select(v => int.Parse(v)).ToList();

                var vertices  = new List <Vertex>();
                var triangles = new List <Triangle>();
                var reCoords  = new List <RoundEdgeData>();

                for (int i = 0; i < positions.Count; i++)
                {
                    vertices.Add(new Vertex(
                                     positions[i],
                                     normals[i],
                                     uvs?[i] ?? Vector2.Empty
                                     ));
                }

                if (geomElem.HasElement("BoneWeights", out XElement boneWeights))
                {
                    var bwValues = boneWeights.Value.Split(' ');
                    for (int i = 0; i < bwValues.Length; i += 3)
                    {
                        int   vIdx   = int.Parse(bwValues[i]);
                        int   bID    = int.Parse(bwValues[i + 1]);
                        float weight = float.Parse(bwValues[i + 2], CultureInfo.InvariantCulture);
                        vertices[vIdx].BoneWeights.Add(new BoneWeight(bID, weight));
                    }
                }

                if (geomElem.HasElement("Outlines", out XElement outlineElem))
                {
                    var outlineUVs = ParseVector2Array(outlineElem.Value);
                    if (outlineUVs.Count % 6 != 0)
                    {
                        //problem
                    }

                    for (int i = 0; i < outlineUVs.Count; i += 6)
                    {
                        var reData = new RoundEdgeData();
                        for (int j = 0; j < 6; j++)
                        {
                            reData.Coords[j] = outlineUVs[i + j];
                        }

                        reCoords.Add(reData);
                    }
                }

                for (int i = 0; i < indices.Count; i += 3)
                {
                    var tri = new Triangle(
                        vertices[indices[i]],
                        vertices[indices[i + 1]],
                        vertices[indices[i + 2]]);
                    triangles.Add(tri);

                    for (int j = 0; j < 3; j++)
                    {
                        if (i + j >= reCoords.Count)
                        {
                            break;
                        }
                        tri.Indices[j].RoundEdgeData = reCoords[i + j];
                    }
                }

                var geom = new MeshGeometry();
                geom.SetVertices(vertices);
                geom.SetTriangles(triangles);

                return(geom);
            }

            return(null);
        }
예제 #8
0
        public static MeshGeometry FromStream(Stream stream)
        {
            var geom = new MeshGeometry();

            using (var br = new BinaryReaderEx(stream))
            {
                int  vertCount  = br.ReadInt32();
                int  idxCount   = br.ReadInt32();
                bool isTexured  = br.ReadBoolean();
                bool isFlexible = br.ReadBoolean();

                var positions = new List <Vector3>();
                var normals   = new List <Vector3>();
                var texCoords = new List <Vector2>();

                for (int i = 0; i < vertCount; i++)
                {
                    positions.Add(new Vector3(br.ReadSingles(3)));
                }

                for (int i = 0; i < vertCount; i++)
                {
                    normals.Add(new Vector3(br.ReadSingles(3)));
                }

                if (isTexured)
                {
                    for (int i = 0; i < vertCount; i++)
                    {
                        texCoords.Add(new Vector2(br.ReadSingles(2)));
                    }
                }

                var verts = new List <Vertex>();
                for (int i = 0; i < vertCount; i++)
                {
                    verts.Add(new Vertex(
                                  positions[i],
                                  normals[i],
                                  isTexured ? texCoords[i] : Vector2.Empty
                                  ));
                }

                var triIndices = new List <int>();
                var avgNormals = new List <Vector3>();
                var reCoords   = new List <RoundEdgeData>();

                for (int i = 0; i < idxCount; i++)
                {
                    triIndices.Add(br.ReadInt32());
                }

                for (int i = 0; i < idxCount; i++)
                {
                    avgNormals.Add(new Vector3(br.ReadSingles(3)));
                }

                for (int i = 0; i < idxCount; i++)
                {
                    var reData = new RoundEdgeData(br.ReadSingles(12));
                    if (!geom.HasRoundEdgeData && !reData.IsEmpty)
                    {
                        geom.HasRoundEdgeData = true;
                    }
                    reCoords.Add(reData);
                }

                var triangles = new List <Triangle>();

                for (int i = 0; i < idxCount; i += 3)
                {
                    var tri = new Triangle(
                        verts[triIndices[i]],
                        verts[triIndices[i + 1]],
                        verts[triIndices[i + 2]]);
                    triangles.Add(tri);

                    for (int j = 0; j < 3; j++)
                    {
                        tri.Indices[j].AverageNormal = avgNormals[i + j];
                        tri.Indices[j].RoundEdgeData = reCoords[i + j];
                    }
                }

                if (isFlexible)
                {
                    for (int i = 0; i < vertCount; i++)
                    {
                        int boneCount = br.ReadInt32();
                        for (int j = 0; j < boneCount; j++)
                        {
                            verts[i].BoneWeights.Add(new BoneWeight(br.ReadInt32(), br.ReadSingle()));
                        }
                    }
                }

                geom.SetVertices(verts);
                geom.SetTriangles(triangles);
            }
            return(geom);
        }
예제 #9
0
        public static List <MeshGeometry> SplitSurfaces(MeshGeometry mesh)
        {
            var currentMesh        = new GeometryBuilder();
            var remainingTriangles = mesh.Triangles.ToList();
            var resultingMeshes    = new List <MeshGeometry>();

            var edgeTriangleDic = new Dictionary <Edge, List <Triangle> >();

            //var allEdges = remainingTriangles.SelectMany(x => x.Edges).Distinct();

            foreach (var tri in remainingTriangles)
            {
                foreach (var edge in tri.Edges)
                {
                    if (!edgeTriangleDic.ContainsKey(edge))
                    {
                        edgeTriangleDic.Add(edge, new List <Triangle>());
                    }
                    edgeTriangleDic[edge].Add(tri);
                }
            }

            Triangle TakeTriangle(int index)
            {
                var result = remainingTriangles[index];

                remainingTriangles.RemoveAt(index);
                return(result);
            }

            IEnumerable <Triangle> GetNeighboringTriangles(Triangle triangle)
            {
                var neighbors = triangle.Edges.SelectMany(e =>
                                                          edgeTriangleDic[e]).Intersect(remainingTriangles).ToList();


                foreach (var tri in neighbors)
                {
                    remainingTriangles.Remove(tri);
                }

                foreach (var tri in neighbors.ToArray())
                {
                    neighbors.AddRange(GetNeighboringTriangles(tri));
                }

                return(neighbors);
                //for (int i = 0; i < remainingTriangles.Count; i++)
                //{
                //    if (triangle.ShareEdge(remainingTriangles[i], false))
                //    {
                //        yield return TakeTriangle(i);
                //        i--;
                //    }
                //}
            }

            while (remainingTriangles.Count > 0)
            {
                var curTri = TakeTriangle(0);
                currentMesh.AddTriangle(curTri);
                var neighbors = GetNeighboringTriangles(curTri);
                foreach (var tri in neighbors)
                {
                    currentMesh.AddTriangle(tri);
                }

                resultingMeshes.Add(currentMesh.GetGeometry());

                currentMesh.Reset();
            }

            return(resultingMeshes);
        }