bool ConvertCountries() { List <CNode> foundNodes = new List <CNode> (); ConnectedNodes(nodes [0], foundNodes); if (foundNodes.Count == nodes.Count && nodes.FindAll(x => x.links.Count < 2).Count == 0) { //Debug.Log ("All nodes are connected by two links"); List <List <CNode> > nodeShapes = new List <List <CNode> > (); List <CNode> multiNodes = nodes.FindAll(x => x.links.Count > 2); /*if(multiNodes.Count == 0) { * nodeShapes.Add(nodes); * }*/ List <CNode[]> doneNodes = new List <CNode[]> (); foreach (CNode junction in multiNodes) //we loop through each junction to catch all the shapes { List <CNode> cwNodes = junction.CClockwiseConnected(); foreach (CNode node in cwNodes) //we go around each node, looking for its clockwise next point { if (doneNodes.Find(x => x [0] == node && x [1] == junction) != null) { continue; } float angleSum = 0f; doneNodes.Add(new CNode[2] { node, junction }); //we start by adding the node so we don't go around it clockwise again CNode currentNode = junction; CNode lastNode = node; //Debug.Log ("Started from " + lastNode.gameObject.name + " and " + currentNode.gameObject.name); List <CNode> currentShape = new List <CNode> (); currentShape.Add(node); do { CNode temp = currentNode; currentShape.Add(currentNode); currentNode = currentNode.CClockwiseFrom(lastNode); float addAngle = MeshMaker.GetCWAngle(temp.gameObject.transform.position, lastNode.gameObject.transform.position, currentNode.gameObject.transform.position) - Mathf.PI; //we look at the exterior angle, which is why we subtract Pi //Debug.Log ("Angle between " + lastNode.gameObject.name + " and " + currentNode.gameObject.name + " is " + addAngle.ToString()); angleSum += addAngle; lastNode = temp; //Debug.Log ("Added " + currentNode.gameObject.name); if (currentNode.links.Count > 2) //if it's a node before a junction, we might loop through it in the future and want to avoid it now { doneNodes.Add(new CNode[2] { lastNode, currentNode }); } } while(currentNode != node); //Debug.Log (angleSum.ToString()); if (angleSum < 0) //This is true for shapes we've gone around the inside of - otherwise, we can include a negative shape { nodeShapes.Add(currentShape); } } } for (int nodeIndex = 0; nodeIndex < nodeShapes.Count; nodeIndex++) //we generate the shapes out of the list of CNodes { List <CNode> nodeList = nodeShapes [nodeIndex]; Vector3[] vertices = new Vector3[nodeList.Count]; Vector3 averageVert = new Vector3(); for (int i = 0; i < nodeList.Count; i++) { averageVert += nodeList [i].gameObject.transform.position; } averageVert /= nodeList.Count; for (int i = 0; i < nodeList.Count; i++) { vertices[i] = nodeList [i].gameObject.transform.position - averageVert; } Triangulator triangulator = new Triangulator(vertices); triangulator.Triangulate(); GameObject newObject = new GameObject(); MeshFilter newFilter = newObject.AddComponent <MeshFilter> (); newFilter.mesh.vertices = vertices; newFilter.mesh.triangles = triangulator.Triangulate(); newFilter.mesh.RecalculateBounds(); newFilter.mesh.RecalculateNormals(); MeshRenderer newRenderer = newObject.AddComponent <MeshRenderer> (); newRenderer.material.shader = Shader.Find("UI/Default"); float colorFraction = nodeIndex / (nodeShapes.Count * 1.0f); //Debug.Log ("Coloring at " + colorFraction.ToString ()); newRenderer.material.color = new Color(colorFraction, colorFraction, colorFraction, 1f); newObject.AddComponent <MeshCollider>(); newObject.AddComponent <CountryObject>(); newObject.transform.Translate(averageVert + new Vector3(0f, 0f, 1f)); MeshMaker.GenerateOutline(newObject); } return(true); } return(false); }