public static List <int> findBorderVerts(List <List <int> > triList, Dictionary <int, BiomeType> vertBiomes, Mesh mesh, BiomeType targetBiome, BiomeType secondTargetBiome) { List <int> borderVerts = new List <int>(); for (int i = 0; i < mesh.vertices.Length; i++) { if (MeshSearching.findVertIndexOfAdjenctVerts(mesh, i, triList, vertBiomes, targetBiome, secondTargetBiome)) { borderVerts.Add(i); } } return(borderVerts); }
public void MakeMesh(int xOffSet, int yOffSet) { //enumerator to conver triangles to array interface for indexing IEnumerator <TriangleNet.Topology.Triangle> triangleEnumerator = mesh.Triangles.GetEnumerator(); // create more than one chunk if necessary for (int chunkStart = 0; chunkStart < mesh.Triangles.Count; chunkStart += trianglesInChunk) { // vertices in unity mesh List <Vector3> vertices = new List <Vector3>(); //per-vertex normals List <Vector3> normals = new List <Vector3>(); //per-vertex uvs List <Vector2> uvs = new List <Vector2>(); // triangles List <int> triangles = new List <int>(); // triangles custom stored in a way I can search to find which verts are part List <List <int> > trisList = new List <List <int> >(); //vertex colours List <Color> vertColors = new List <Color>(); #region convert triangle.Net mesh into Unity Mesh //iterate over all triangles until chunk size int chunkEnd = chunkStart + trianglesInChunk; for (int i = chunkStart; i < chunkEnd; i++) { if (!triangleEnumerator.MoveNext()) { // last triangle break; } // get current triangle Triangle triangle = triangleEnumerator.Current; // triangles need to be wound backwards to be rightways up Vector3 v0 = HelperFunctions.GetPoint3D(triangle.vertices[2].id, mesh, elevations); Vector3 v1 = HelperFunctions.GetPoint3D(triangle.vertices[1].id, mesh, elevations); Vector3 v2 = HelperFunctions.GetPoint3D(triangle.vertices[0].id, mesh, elevations); triangles.Add(vertices.Count); triangles.Add(vertices.Count + 1); triangles.Add(vertices.Count + 2); vertices.Add(v0); vertices.Add(v1); vertices.Add(v2); vertColors.Add(HelperFunctions.getVertColour(v0, maxMeshHeight)); vertColors.Add(HelperFunctions.getVertColour(v1, maxMeshHeight)); vertColors.Add(HelperFunctions.getVertColour(v2, maxMeshHeight)); //custom data structure which will be used later to find adjanced vertices List <int> thisTri = new List <int>(); thisTri.Add(vertices.Count); thisTri.Add(vertices.Count + 1); thisTri.Add(vertices.Count + 2); trisList.Add(thisTri); Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0); normals.Add(normal); normals.Add(normal); normals.Add(normal); ////correctly calulates the UV's based on the position of the triangle within the mesh uvs.Add(new Vector2((float)triangle.vertices[2].x / meshBounds.size.x, (float)triangle.vertices[2].y / meshBounds.size.y)); uvs.Add(new Vector2((float)triangle.vertices[1].x / meshBounds.size.x, (float)triangle.vertices[1].y / meshBounds.size.y)); uvs.Add(new Vector2((float)triangle.vertices[0].x / meshBounds.size.x, (float)triangle.vertices[0].y / meshBounds.size.y)); } UnityEngine.Mesh chunkMesh = new UnityEngine.Mesh(); chunkMesh.vertices = vertices.ToArray(); chunkMesh.triangles = triangles.ToArray(); chunkMesh.uv = uvs.ToArray(); chunkMesh.normals = normals.ToArray(); chunkMesh.colors = vertColors.ToArray(); #endregion #region Mounatains and Rivers if (enabledElevation || enableRivers) { Dictionary <int, BiomeType> vertBiomes = new Dictionary <int, BiomeType>(); vertBiomes = MeshSearching.setVertBiomes(chunkMesh, islandHeight); MeshSearching.VertexConnection[] vertCons = MeshSearching.FindAllOverLappingVert(chunkMesh); List <int> borderVerts = HelperFunctions.findBorderVerts(trisList, vertBiomes, chunkMesh, BiomeType.land, BiomeType.water); int mountainIndex = int.MaxValue; if (enabledElevation) { if (enableSlowElevationGeneration) { mountainIndex = MeshSearching.findCentreOfIsland(chunkMesh, vertBiomes, borderVerts, vertCons, trisList); } else { int mountain = MeshSearching.findCentreOfIslandSimple(chunkMesh, vertBiomes, borderVerts, vertCons, trisList); } } if (enableRivers) { int nRiversMax = Random.Range((int)nRivers.x, (int)nRivers.y); int maxIterationsOfRiverSearch = maximumRiverIterations; int maxIter = maxIterationsOfRiverSearch; List <int> allLandIndexs = new List <int>(); for (int i = 0; i < vertBiomes.Count; i++) { if (vertBiomes[i] == BiomeType.land) { allLandIndexs.Add(i); } } for (int i = (int)nRivers.x; i < nRiversMax; i++) { defineRiversDownwards(chunkMesh, borderVerts, maxIterationsOfRiverSearch, mountainIndex, allLandIndexs); maxIterationsOfRiverSearch -= riverIterationsDecrimentAmount; if (maxIterationsOfRiverSearch <= 0) { maxIterationsOfRiverSearch = maxIter; } } } } #endregion //find tallest point so that it can be passed to the shader float currentMax = 0; for (int i = 0; i < chunkMesh.vertices.Length; i++) { if (chunkMesh.vertices[i].y > currentMax) { currentMax = chunkMesh.vertices[i].y; } } Renderer ShaderRender = chunkPrefab.GetComponent <Renderer>(); ShaderRender.sharedMaterial.SetFloat("MinHeight", 0); ShaderRender.sharedMaterial.SetFloat("MaxHeight", currentMax); //Spawning mesh into world GameObject rotationParent = new GameObject(); GameObject chunk = Instantiate(chunkPrefab, new Vector3(transform.position.x + xOffSet, transform.position.y, transform.position.z + yOffSet), transform.rotation); chunk.GetComponent <MeshFilter>().mesh = chunkMesh; chunk.GetComponent <MeshCollider>().sharedMesh = chunkMesh; chunk.transform.parent = rotationParent.transform; Camera.main.gameObject.transform.position = new Vector3(chunk.transform.position.x + xsize / 2, Camera.main.transform.position.y, chunk.transform.position.z + ysize / 2); rotationParent.transform.parent = transform; } }