示例#1
0
文件: MeshGenerator.cs 项目: GDxU/pb
    public MapMesh generateTerrain(Map map, List <List <Vector2> > riverPoints, TriangleNet.Mesh mapTriangulation)
    {
        MapMesh terrain = new MapMesh();

        List <Vector3> landVertices       = new List <Vector3>();
        List <Vector3> oceanVertices      = new List <Vector3>();
        List <Vector3> innerWaterVertices = new List <Vector3>();
        Dictionary <Vector2, float> mapVerticesHeights = new Dictionary <Vector2, float>();

        foreach (Triangle triangle in mapTriangulation.Triangles)
        {
            List <MapVertex> mapVertices = triangle.vertices
                                           .Select(vertex => vertex is MapVertex ? (MapVertex)vertex : convertToMapVertex(vertex))
                                           .Reverse()
                                           .ToList();

            List <Vector3> underWaterShifts = new List <Vector3>(new Vector3[3]);

            List <bool> needsShoreAdjustments = new List <bool>(new bool[3]);

            if (mapVertices.Any(mapVertice => mapVertice.hex == null))
            {
                for (int i = 0; i < mapVertices.Count; i++)
                {
                    if (mapVertices[i].hex != null)
                    {
                        needsShoreAdjustments[i] = true;
                    }
                }
            }

            MapVertex shoreMapVertex = mapVertices.FirstOrDefault(mapVertex => mapVertex.hex != null && (mapVertex.hex.biome == null || mapVertex.hex.biome.name != "Fresh lake"));
            if (shoreMapVertex != null)
            {
                Vector2 shoreCenter = HexMathHelper.hexToWorldCoords(new Vector2(shoreMapVertex.hex.x, shoreMapVertex.hex.y), this.hexSize);
                //if shore triangle push it underwater to create shore slope
                for (int i = 0; i < mapVertices.Count; i++)
                {
                    if (mapVertices[i].hex == null)
                    {
                        underWaterShifts[i]  = (new Vector2((float)mapVertices[i].x, (float)mapVertices[i].y) - shoreCenter).normalized * 0.3f;
                        underWaterShifts[i] += new Vector3(0, 0, 0.03f);
                    }
                }
            }

            List <Vector3> triangleVertices = new List <Vector3>();
            for (int i = 0; i < mapVertices.Count; i++)
            {
                float   height    = TerrainHelper.getHeight(heightSeed, mapVertices[i], this.hexSize, elevatedHeightmap, mountainHeightmap);
                Vector3 newVertex = mapVertices[i].toVector3() + underWaterShifts[i] + new Vector3(0, 0, height);

                if (!mapVerticesHeights.ContainsKey(newVertex) && needsShoreAdjustments[i])
                {
                    newVertex.z = Random.Range(0.08f, 0.13f);
                    mapVerticesHeights[newVertex] = newVertex.z;
                }

                if (mapVertices[i].isRiver && (mapVertices[i].hex == null || !mapVertices[i].hex.hasTag(RiverHelper.FRESH_LAKE_TAG)))
                {
                    newVertex += TerrainHelper.getRiverHeightAdjustment(newVertex);
                }

                triangleVertices.Add(newVertex);
            }

            if (mapVertices.All(mapVertex => mapVertex.hex == null))
            {
                oceanVertices.AddRange(triangleVertices);
            }
            else if (mapVertices.All(mapVertex => mapVertex.isRiver))
            {
                innerWaterVertices.AddRange(triangleVertices);
            }
            else if (mapVertices.All(mapVertex => mapVertex.hex != null && mapVertex.hex.hasTag(RiverHelper.FRESH_LAKE_TAG)))
            {
                innerWaterVertices.AddRange(triangleVertices);
            }
            else
            {
                landVertices.AddRange(triangleVertices);
            }
        }

        //smooth shore
        for (int i = 0; i < landVertices.Count; i++)
        {
            Vector3 vertex = landVertices[i];
            if (mapVerticesHeights.ContainsKey(vertex))
            {
                vertex.z        = mapVerticesHeights[landVertices[i]];
                landVertices[i] = vertex;
            }
        }

        terrain.landMesh       = this.createMesh("Land", landVertices);
        terrain.oceanMesh      = this.createMesh("Ocean", oceanVertices);
        terrain.innerWaterMesh = this.createMesh("Lakes and Rivers", innerWaterVertices);

        return(terrain);
    }