예제 #1
0
    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;
        }
    }