public MeshGeometry GetGeometry() { var geom = new MeshGeometry(); //var verts = VertexDict.Values.SelectMany(x => x); geom.SetVertices(_Vertices); geom.SetTriangles(_Triangles); return(geom); }
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]); } }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }