public void Start() { //Go get points from Road Curve dualGraph = new DualGraph(volume); cellNumber = (int)volume.x / density; StartCoroutine("GeneratePoints"); }
void GeneratePoints(Vector3[] points, DualGraph dualGraph) { //set up cells dualGraph.DefineCells(points, rootTriMultiplier); // computeTime = Time.realtimeSinceStartup; //compute if (useSortedGeneration) { dualGraph.ComputeForAllSortedCells(); } else { dualGraph.ComputeForAllCells(); } // yield return new WaitForEndOfFrame(); // Debug.Log("coroutine"); }
/// <summary> /// Generates the mesh. /// </summary> void GenerateMesh(DualGraph dualGraph) { // Debug.Log("prepare cells for mesh start"); dualGraph.PrepareCellsForMesh(); //yield return new WaitForEndOfFrame(); // Debug.Log("prepare cells for mesh end"); if (graphMesh == null) { graphMesh = new Mesh(); graphMesh.name = "Graph Mesh"; } else { //For the love of god, why are you calling this twice?!?! graphMesh.Clear(); } meshVerts.Clear(); meshTris.Clear(); // List<Vector3> vert= new List<Vector3>(); // List<Vector2> uvs= new List<Vector2>(); // List<int> tris= new List<int>(); // int vertCount=0; // foreach(Cell c in dualGraph.cells) // { for (int i = 0; i < dualGraph.cells.Count; i++) { //bottleneck protection // if(i!=0 && i % 100 == 0) // yield return new WaitForEndOfFrame(); List <Vector3> vert = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> tris = new List <int>(); int vertCount = 0; if (!dualGraph.cells[i].root && !dualGraph.cells[i].IsOpenEdge()) //use only interior until faux edges are added { if (dualGraph.cells[i].IsOpenEdge()) { Debug.Log("open edge"); } for (int a = 0; a < dualGraph.cells[i].mesh.verts.Length; a++) { //Debug.Log("in verts"); vert.Add(dualGraph.cells[i].mesh.verts[a] + transform.position); // GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); // c.transform.position= dualGraph.cells[i].mesh.verts[a]; // c.name = a.ToString(); } foreach (Vector2 v in dualGraph.cells[i].mesh.uv) { uvs.Add(v); // Debug.Log("in uv"); } for (int j = 2; j < dualGraph.cells[i].mesh.verts.Length; j++) { tris.Add(vertCount); tris.Add(vertCount + j - 1); tris.Add(vertCount + j); } //finishing the loop tris.Add(vertCount); tris.Add(vertCount + dualGraph.cells[i].mesh.verts.Length - 1); tris.Add(vertCount + 1); vertCount = vert.Count; } //Check for empty meshes and skip if (vert.Count == 0) { continue; } ///Export to individual GameObject // GameObject cell = new GameObject(); //add mesh info to lists to crate mesh in a coroutine and drip feed in to unity //Mesh mesh = new Mesh(); // mesh.vertices = vert.ToArray(); // mesh.triangles = tris.ToArray(); meshVerts.Add(vert.ToArray()); meshTris.Add(tris.ToArray()); } //StartCoroutine("AddToCells"); }
float FindShortestEdgeDistance(DualGraph dualGraph) { float shortestDistance = Mathf.Infinity; Vector3 p0; Vector3 p1; int shortestIndexI = 0; int shortestIndexJa = 0; int shortestIndexJb = 0; for (int i = 0; i < dualGraph.cells.Count; i++) { if (!dualGraph.cells[i].root && !dualGraph.cells[i].IsOpenEdge()) { for (int j = 0; j < dualGraph.cells[i].mesh.verts.Length; j++) { if (j == 0) { continue; } int nextIndex = j + 1; //looping but skipping 0 central point if (nextIndex > dualGraph.cells[i].mesh.verts.Length - 1) { nextIndex = 1; } p0 = (dualGraph.cells[i].mesh.verts[j]); p1 = (dualGraph.cells[i].mesh.verts[nextIndex]); /* * GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); * c.transform.position = p0;// dualGraph.cells[shortestIndexI].mesh.verts[shortestIndexJa]; * c.name = i.ToString() +" "+ j.ToString();// "shortest A"; * * c = GameObject.CreatePrimitive(PrimitiveType.Cube); * c.transform.position = p1;//dualGraph.cells[shortestIndexI].mesh.verts[shortestIndexJb]; * c.name = c.name = i.ToString()+" " + nextIndex.ToString(); */ float d = Vector2.Distance(p0, p1); if (d < shortestDistance) { shortestIndexI = i; shortestIndexJa = j; shortestIndexJb = nextIndex; shortestDistance = d; } } } } /* * GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); * c.transform.position = dualGraph.cells[shortestIndexI].mesh.verts[shortestIndexJa]; * c.name = shortestIndexI.ToString() + " " + shortestIndexJa.ToString();// "shortest A"; * * c = GameObject.CreatePrimitive(PrimitiveType.Cube); * c.transform.position = dualGraph.cells[shortestIndexI].mesh.verts[shortestIndexJb]; * c.name = shortestIndexI.ToString() + " " + shortestIndexJb.ToString();// */ return(shortestDistance); }
void Lloyds() { //for (int x = 0; x < lloydIterations; x++) //we will keep relaxing until all our edges are at least bool edgeShortEnough = false; //int maxCounts = 50; int count = 0; List <Vector3> borderPoints = new List <Vector3>(); while (!edgeShortEnough && count < lloydIterations) { // Debug.Log("LastIteration =" + count); //destroy old cells (if any), we will create new ones on this iteration for (int i = 0; i < cells.Count; i++) { //extruded cell is not parented if (cells[i].GetComponent <ExtrudeCell>() != null) { Destroy(cells[i].GetComponent <ExtrudeCell>().extrudedCell); } Destroy(cells[i].gameObject); } //Go get points from Road Curve DualGraph dualGraph = new DualGraph(volume); //Debug.Log("cells count before split = " + cells.Count); cells.Clear(); cellNumber = (int)volume.x / density; Vector3[] points = new Vector3[cellNumber]; //Debug.Log(points.Length); if (count > 0) { points = new Vector3[centroids.Count]; } if (count > 0) { fillWithPoints = true; fillWithRandom = false; } GenSortedRandCells(ref points); // if (count == 1) { for (int i = 0; i < points.Length; i++) { // GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); // c.transform.position = points[i]; // c.name = count.ToString() + " " + i.ToString(); } } centroids.Clear(); dualGraph.DefineCells(points, rootTriMultiplier); dualGraph.ComputeForAllSortedCells(); // dualGraph.ComputeForAllCells(); dualGraph.PrepareCellsForMesh(); //work out centroids for next iteration for (int i = 0; i < dualGraph.cells.Count; i++) { if (!dualGraph.cells[i].root && !dualGraph.cells[i].IsOpenEdge()) { //use only interior until faux edges are added if (dualGraph.cells[i].IsOpenEdge()) { Debug.Log("open edge"); } Vector3 avg = Vector3.zero; for (int a = 0; a < dualGraph.cells[i].mesh.verts.Length; a++) { if (a != 0) { avg += dualGraph.cells[i].mesh.verts[a];//make temp [] } } avg /= dualGraph.cells[i].mesh.verts.Length - 1; centroids.Add(avg); } else { //saving outside border points, if we dont the graph will get smaller and smaller with each lloyd iteration if ((dualGraph.cells[i].IsOpenEdge() && !dualGraph.cells[i].root)) { centroids.Add(dualGraph.cells[i].point); // GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); //c.transform.position = dualGraph.cells[i].point; } } } if (count == 0) { for (int i = 0; i < centroids.Count; i++) { // GameObject c = GameObject.CreatePrimitive(PrimitiveType.Cube); // c.transform.position = centroids[i]; // c.name = "c";// x.ToString() + " " + i.ToString(); } } bool doShortestEdge = false; if (doShortestEdge) { //work out if we have relaxed enough float shortestEdgeDistance = FindShortestEdgeDistance(dualGraph); if (shortestEdgeDistance >= minEdgeSize) { Debug.Log("min edge distance reached "); edgeShortEnough = true; } else { Debug.Log("shortest distance = " + shortestEdgeDistance); } } count++; //cells = new List<GameObject>(); GenerateMesh(dualGraph); CellMeshes(); // yield return new WaitForSeconds(.5f); } //take small corners out to simplify the shape Edges(); CalculateAdjacents(); // Edges(); SplitCells(); RemoveSmallEdges();//testing early in pipeline ReMesh(true); //create a list of edges for each polygon and save on Adjacent Edges script added to each cell Edges(); CalculateAdjacents(); //prob not necessary ^^ MergeCells(); //choose colours for each cell SetPalletes(); //add ... AddToCells(); // yield break; }