public UnityEngine.Mesh ConvertTNetMesh(TriangleNet.Meshing.IMesh tnetMesh) { List <Vector3> outVertices = new List <Vector3>(); List <int> outIndices = new List <int>(); foreach (ITriangle t in tnetMesh.Triangles) { for (int i = 2; i >= 0; i--) { bool found = false; for (int j = 0; j < outVertices.Count; j++) { if ((outVertices[j].x == t.GetVertex(i).X) && (outVertices[j].z == t.GetVertex(i).Y) && (outVertices[j].y == t.GetVertex(i).Z)) { outIndices.Add(j); found = true; break; } } if (!found) { float x = (float)t.GetVertex(i).X; float y = (float)t.GetVertex(i).Y; float z = (float)t.GetVertex(i).Z; outVertices.Add(new Vector3(x, y, z)); outIndices.Add(outVertices.Count - 1); } } } List <Vector2> uv = new List <Vector2>(); for (int i = 0; i < outVertices.Count; i++) { uv.Add(new Vector2(outVertices[i].x, outVertices[i].z)); } UnityEngine.Mesh result = new UnityEngine.Mesh(); result.SetVertices(outVertices); outIndices.Reverse(); result.SetTriangles(outIndices, 0); result.SetUVs(0, uv); result.RecalculateBounds(); result.RecalculateNormals(); return(result); }
public static Mesh convertTriangleNETMesh(TriangleNet.Meshing.IMesh tMesh) { List <Vector3> outVertices = new List <Vector3>(); List <int> outIndices = new List <int>(); foreach (ITriangle t in tMesh.Triangles) { for (int j = 2; j >= 0; j--) { bool found = false; for (int k = 0; k < outVertices.Count; k++) { if ((outVertices[k].x == t.GetVertex(j).x) && (outVertices[k].z == t.GetVertex(j).y) && (outVertices[k].y == t.GetVertex(j).z)) { outIndices.Add(k); found = true; break; } } if (!found) { outVertices.Add(new Vector3((float)t.GetVertex(j).x, (float)t.GetVertex(j).z, (float)t.GetVertex(j).y)); outIndices.Add(outVertices.Count - 1); } } } List <Vector2> uvs = new List <Vector2>(); for (int i = 0; i < outVertices.Count; i++) { uvs.Add(new Vector2(outVertices[i].x, outVertices[i].z)); } Mesh resultMesh = new Mesh(); resultMesh.SetVertices(outVertices); resultMesh.SetTriangles(outIndices, 0); resultMesh.SetUVs(0, uvs); resultMesh.RecalculateBounds(); resultMesh.RecalculateNormals(); return(resultMesh); }
public override List <SubdividableEdgeLoop <CityEdge> > GetChildren(SubdividableEdgeLoop <CityEdge> parent) { Vector2[] parentPoints = parent.GetPoints(); Polygon parentPoly = parent.GetPolygon(); //generate points of interest List <RoadDestination> pointsOfInterest = new List <RoadDestination>(); Vector2 centroid = parent.GetCenter(); //parent.EnumerateEdges((EdgeLoopEdge edge) => //{ // pointsOfInterest.Add(new RoadDestination(Vector2.Lerp(edge.a.pt, edge.b.pt, Random.Range(0.2f, 0.8f)), 1, false, true)); //}); Rect bounds = parent.GetBounds(); bounds.width = bounds.width * 2; bounds.height = bounds.height * 2; int potentialRoadPointsRt = Mathf.CeilToInt(Mathf.Sqrt(potentialRoadPoints)); float approxDiameter = Mathf.Sqrt(parentPoly.area); float minimumPerimeterDistance = approxDiameter / 4f; for (int x = 0; x < potentialRoadPointsRt; x++) { for (int y = 0; y < potentialRoadPointsRt; y++) { Vector2 point = new Vector2((x / (float)potentialRoadPointsRt) * bounds.width + bounds.xMin, (y / (float)potentialRoadPointsRt) * bounds.height + bounds.yMin); float distBtwnPts = (bounds.width + bounds.height) / (potentialRoadPoints * 2); point = point + new Vector2(Random.Range(-1f, 1f), Random.Range(-1, 1f)) * distBtwnPts * 3f; if (parentPoly.ContainsPoint(point)) // && parent.DistToPerimeter(point) > minimumPerimeterDistance) { pointsOfInterest.Add(new RoadDestination(point, 0, false, false)); } } } pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(bounds.width * 100, bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(bounds.width * 100, -bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(-bounds.width * 100, -bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(-bounds.width * 100, bounds.height * 100), 0, false, false)); //triangulate points of interest to get potential road segments TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon(); Dictionary <TriangleNet.Geometry.Vertex, RoadDestination> vertexDestMap = new Dictionary <TriangleNet.Geometry.Vertex, RoadDestination>(); foreach (RoadDestination dest in pointsOfInterest) { TriangleNet.Geometry.Vertex vert = new TriangleNet.Geometry.Vertex(dest.point.x, dest.point.y); vertexDestMap.Add(vert, dest); polygon.Add(vert); } TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; TriangleNet.Meshing.GenericMesher mesher = new TriangleNet.Meshing.GenericMesher(); TriangleNet.Meshing.IMesh mesh = mesher.Triangulate(polygon); TriangleNet.Voronoi.StandardVoronoi voronoi = new TriangleNet.Voronoi.StandardVoronoi((TriangleNet.Mesh)mesh); IEnumerable <TriangleNet.Geometry.IEdge> voronoiEdges = voronoi.Edges; List <TriangleNet.Topology.DCEL.Vertex> voronoiVerts = voronoi.Vertices; List <DividingEdge> dividingEdges = new List <DividingEdge>(); ILinkedGraphEdgeFactory <CityEdge> factory = new CityEdgeFactory(); foreach (TriangleNet.Geometry.IEdge edge in voronoiEdges) { Vector2 a = new Vector2((float)voronoiVerts[edge.P0].X, (float)voronoiVerts[edge.P0].Y); Vector2 b = new Vector2((float)voronoiVerts[edge.P1].X, (float)voronoiVerts[edge.P1].Y); dividingEdges.Add(new DividingEdge(a, b, factory, factoryParams)); } //get vertices as list //ICollection<TriangleNet.Geometry.Vertex> vertices = mesh.Vertices; //TriangleNet.Geometry.Vertex[] vertexList = new TriangleNet.Geometry.Vertex[vertices.Count]; //vertices.CopyTo(vertexList, 0); //IEnumerable<TriangleNet.Geometry.Edge> meshEdges = mesh.Edges; //build a list of dividing edges and pass it to the child collector //foreach (TriangleNet.Geometry.Edge edge in meshEdges) { // //if (vertConnections[edge.P0] > 4) // //{ // // vertConnections[edge.P0]--; // // continue; // //} // //if (vertConnections[edge.P1] > 4) // //{ // // vertConnections[edge.P1]--; // // continue; // //} // Vector2 a = new Vector2((float)vertexList[edge.P0].X, (float)vertexList[edge.P0].Y); // Vector2 b = new Vector2((float)vertexList[edge.P1].X, (float)vertexList[edge.P1].Y); // dividingEdges.Add(new DividingEdge(a, b, factory, CityEdgeType.LandPath)); //} return(CollectChildren(parent, dividingEdges)); }
public static Mesh GetTriangulationMesh(Vector3[] verts, HashSet <int> borderVerts, Polygon boundary) { TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon(); //Dictionary<TriangleNet.Geometry.Vertex, float> vertexElevMap = new Dictionary<TriangleNet.Geometry.Vertex, float>(); foreach (Vector3 vert in verts) { TriangleNet.Geometry.Vertex triangulationVert = new TriangleNet.Geometry.Vertex(vert.x, vert.z); //vertexElevMap.Add(triangulationVert, vert.y); polygon.Add(triangulationVert); } TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; TriangleNet.Meshing.GenericMesher mesher = new TriangleNet.Meshing.GenericMesher(); TriangleNet.Meshing.IMesh mesh = mesher.Triangulate(polygon); Vector3[] meshVerts = new Vector3[mesh.Vertices.Count]; List <int> meshTriangles = new List <int>(); Dictionary <TriangleNet.Geometry.Vertex, int> vertexIndexMap = new Dictionary <TriangleNet.Geometry.Vertex, int>(); int v = 0; foreach (TriangleNet.Geometry.Vertex triangulatorVert in mesh.Vertices) { meshVerts[v] = new Vector3((float)triangulatorVert.X, verts[v].y, (float)triangulatorVert.Y); vertexIndexMap[triangulatorVert] = v; v++; } //for (int i = 0; i < vertexList.Length; i ++) //{ // TriangleNet.Geometry.Vertex triangulatorVert = vertexList[i]; // meshVerts[i] = new Vector3((float)triangulatorVert.X, vertexElevMap[triangulatorVert], (float)triangulatorVert.Y); // vertexIndexMap[triangulatorVert] = i; //} foreach (TriangleNet.Topology.Triangle tri in mesh.Triangles) { int ind1 = vertexIndexMap[tri.GetVertex(0)]; int ind2 = vertexIndexMap[tri.GetVertex(2)]; int ind3 = vertexIndexMap[tri.GetVertex(1)]; Vector2 center = new Vector2((float)(tri.GetVertex(0).X + tri.GetVertex(1).X + tri.GetVertex(2).X) / 3f, (float)(tri.GetVertex(0).Y + tri.GetVertex(1).Y + tri.GetVertex(2).Y) / 3f); if (!(borderVerts.Contains(ind1) && borderVerts.Contains(ind2) && borderVerts.Contains(ind3)) || (boundary.ContainsPoint(center) && !boundary.PermiterContainsPoint(center))) { meshTriangles.Add(ind1); meshTriangles.Add(ind2); meshTriangles.Add(ind3); } } Mesh unityMesh = new Mesh(); unityMesh.vertices = meshVerts; unityMesh.triangles = meshTriangles.ToArray(); unityMesh.RecalculateBounds(); unityMesh.RecalculateNormals(); return(unityMesh); }