Пример #1
0
    public static GridElevations GetVertexHeights(Vector3 position, int seed)
    {
        int v0 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.SW), seed);
        int v1 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.NW), seed);
        int v2 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.NE), seed);
        int v3 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.SE), seed);

        return(new GridElevations(v0, v1, v2, v3));
    }
Пример #2
0
    public static GridElevations GetVertexHeightsFromHeightmap(Vector3 position, Texture2D heightmap)
    {
        int v0 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.SW), heightmap);
        int v1 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.NW), heightmap);
        int v2 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.NE), heightmap);
        int v3 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.SE), heightmap);

        return(new GridElevations(v0, v1, v2, v3));
    }
Пример #3
0
 void OnEnable()
 {
     if (!GridMetrics.noiseSource)
     {
         GridMetrics.noiseSource = noiseSource;
         GridMetrics.InitializeHashGrid(seed);
         GridMetrics.colors = colors;
     }
 }
Пример #4
0
    void MakeCornerBridge(GridMesh mesh, Vector3 v0, GridDirection bridgeDirection)
    {
        Vector3 b0 = GridMetrics.GetBridge(bridgeDirection.Previous());
        Vector3 b1 = GridMetrics.GetBridge(bridgeDirection.Next());

        mesh.AddQuad(v0, v0 + b0, v0 + b0 + b1, v0 + b1);
        if (mesh.useUVCoordinates)
        {
            mesh.AddQuadUV(0f, 0f, 0f, 1f);
        }
    }
Пример #5
0
    void Awake()
    {
        GridMetrics.noiseSource = noiseSource;
        GridMetrics.InitializeHashGrid(seed);
        GridMetrics.colors = colors;

        cellCountX = chunkCountX * GridMetrics.chunkSizeX;
        cellCountZ = chunkCountZ * GridMetrics.chunkSizeZ;

        CreateChunks();
        CreateCells();
    }
Пример #6
0
    void MakeBridge(GridMesh mesh, Vector3 v0, Vector3 v1, GridDirection bridgeDirection)
    {
        Vector3 bridge = GridMetrics.GetBridge(bridgeDirection);
        Vector3 e0     = v0 + bridge;
        Vector3 e1     = v1 + bridge;

        mesh.AddQuad(v0, e0, e1, v1);
        if (mesh.useUVCoordinates)
        {
            mesh.AddQuadUV(0f, 0f, 0f, 1f);
        }
    }
Пример #7
0
    private void Awake()
    {
        gridMaterials = GameObject.Find("EditorCanvas").GetComponent <MapEditor>().materials;
        cellCountX    = chunkCountX * GridMetrics.chunkSizeX;
        cellCountZ    = chunkCountZ * GridMetrics.chunkSizeZ;
        GridMetrics.InitializeHashGrid(seed);
        chunkCuller = new CullingGroup();
        chunkCuller.SetBoundingDistances(new float[] { distanceBand1, distanceBand2, distanceBand3 });
        chunkCuller.onStateChanged = StateChangedMethod;

        CreateChunks();
        CreateCells();
    }
Пример #8
0
 void MoveEditorPointer(SquareCell cell, GridDirection vertex)
 {
     if (activeMode == EditMode.color || activeMode == EditMode.rivers || activeMode == EditMode.roads ||
         activeMode == EditMode.water_level || activeMode == EditMode.building || activeMode == EditMode.trees ||
         activeMode == EditMode.rocks || activeMode == EditMode.mast || activeMode == EditMode.lighthouse || activeMode == EditMode.industry || activeMode == EditMode.town)
     {
         pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + Vector3.up * cell.CentreElevation * GridMetrics.elevationStep;
     }
     if (activeMode == EditMode.elevation)
     {
         pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + GridMetrics.GetEdge(vertex) + Vector3.up * (int)cell.GridElevations[vertex] * GridMetrics.elevationStep;
     }
 }
Пример #9
0
    void AddWaterForSquare(SquareCell cell, Vector3 centre)
    {
        centre.y = cell.WaterSurfaceY;
        Vector3 c0 = centre + GridMetrics.GetEdge(GridDirection.SW);
        Vector3 c1 = centre + GridMetrics.GetEdge(GridDirection.NW);
        Vector3 c2 = centre + GridMetrics.GetEdge(GridDirection.NE);
        Vector3 c3 = centre + GridMetrics.GetEdge(GridDirection.SE);

        if (cell.IsFullyUnderwater)
        {
            water.AddQuad(c0, c1, c2, c3);
        }
        else if (cell.IsPartUnderwater)
        {
            float v0 = 0f, v1 = 0f, v2 = 0f, v3 = 0f;
            if (cell.GetNeighbor(GridDirection.N) && !cell.GetNeighbor(GridDirection.N).IsUnderwater)
            {
                v1 = 1f; v2 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.NE) && !cell.GetNeighbor(GridDirection.NE).IsUnderwater)
            {
                v2 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.E) && !cell.GetNeighbor(GridDirection.E).IsUnderwater)
            {
                v2 = 1f; v3 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.SE) && !cell.GetNeighbor(GridDirection.SE).IsUnderwater)
            {
                v3 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.S) && !cell.GetNeighbor(GridDirection.S).IsUnderwater)
            {
                v3 = 1f; v0 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.SW) && !cell.GetNeighbor(GridDirection.SW).IsUnderwater)
            {
                v0 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.W) && !cell.GetNeighbor(GridDirection.W).IsUnderwater)
            {
                v0 = 1f; v1 = 1f;
            }
            if (cell.GetNeighbor(GridDirection.NW) && !cell.GetNeighbor(GridDirection.NW).IsUnderwater)
            {
                v1 = 1f;
            }
            waterShore.AddQuad(c0, c1, c2, c3);
            waterShore.AddQuadV(v0, v1, v2, v3);
        }
    }
Пример #10
0
 void CreateChunks()
 {
     chunks = new GridChunk[chunkCountX * chunkCountZ];
     for (int z = 0, i = 0; z < chunkCountZ; z++)
     {
         for (int x = 0; x < chunkCountX; x++)
         {
             GridChunk chunk = chunks[i++] = Instantiate(chunkPrefab);
             chunk.transform.SetParent(transform);
             chunk.transform.position = new Vector3(x * GridMetrics.chunkSizeX, 0, z * GridMetrics.chunkSizeZ);
             chunk.chunkTypes         = GridMetrics.GenerateChunkType();
         }
     }
 }
Пример #11
0
    void AddCliffEdge(SquareCell cell, GridDirection direction)
    {
        GridDirection prev     = direction.Previous();
        GridDirection next     = direction.Next();
        GridDirection prevN    = prev.Previous2();
        GridDirection nextN    = next.Next2();
        SquareCell    neighbor = cell.GetNeighbor(direction);

        if (neighbor != null)
        {
            Vector3 c0 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(prev) + Vector3.up * (int)cell.GridElevations[prev] * GridMetrics.elevationStep;
            Vector3 c1 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(next) + Vector3.up * (int)cell.GridElevations[next] * GridMetrics.elevationStep;
            Vector3 n0 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(prevN) + Vector3.up * (int)neighbor.GridElevations[prevN] * GridMetrics.elevationStep;
            Vector3 n1 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(nextN) + Vector3.up * (int)neighbor.GridElevations[nextN] * GridMetrics.elevationStep;
            if (c0 != n0 && c1 != n1)
            {
                if (c0.y > n0.y && n1.y > c1.y) // if edges cross heights along edge X
                {
                    Vector2 cross      = CrossingPoint(c1.y - c0.y, n1.y - n0.y, c0.y, n0.y);
                    Vector3 worldCross = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z)
                                         + GridMetrics.GetEdge(direction.Previous())
                                         + (cross.x * 2 * GridMetrics.GetEdge(direction.Next2()))
                                         + new Vector3(0, cross.y, 0);
                    terrain.AddTriangle(worldCross, c0, n0);
                    terrain.AddTriangleColor(Color.cyan);
                    terrain.AddTriangle(worldCross, n1, c1);
                    terrain.AddTriangleColor(Color.green);
                }
                else if (c0.y > n0.y && c1.y > n1.y) // if one edge is always above the other
                {
                    terrain.AddQuad(c0, n0, n1, c1);
                    terrain.AddQuadColor(retainingWallColor);
                }
            }
            else if (c0.y > n0.y)
            {
                terrain.AddTriangle(c0, n0, c1);
                terrain.AddTriangleColor(retainingWallColor);
            }
            else if (c1.y > n1.y)
            {
                terrain.AddTriangle(c0, n1, c1);
                terrain.AddTriangleColor(retainingWallColor);
            }
        }
    }
Пример #12
0
    public void AddFeature(SquareCell cell, Vector3 position)
    {
        GridHash hash = GridMetrics.SampleHashGrid(position);

        if (cell.UrbanLevel != 0 && cell.BuildingOnSquare == null)
        {
            int buildingIndex = Random.Range(0, townBuildings.Length);
            cell.BuildingOnSquare = Instantiate(townBuildings[buildingIndex]);
            cell.BuildingOnSquare.Construct(cell, position, hash);
            cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false);
        }
        else if (cell.Industry != 0 && cell.BuildingOnSquare == null)
        {
            cell.BuildingOnSquare = Instantiate(industryBuildings[cell.Industry - 1]);
            cell.BuildingOnSquare.Construct(cell, position, hash);
            cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false);
        }
        else if (cell.FarmLevel != 0)
        {
        }
        else if (cell.PlantLevel != 0)
        {
            for (int i = 0; i < cell.PlantLevel; i++)
            {
                float     selectFeature = Mathf.Clamp(Mathf.PerlinNoise((position.x + i / 6f) * 100, (position.z + i / 6f) * 100), 0f, 1f);
                int       randomFeature = (int)Mathf.Floor((treePrefabs[0].Length - 1) * selectFeature);
                Transform instance      = Instantiate(treePrefabs[0][randomFeature]);
                instance.localPosition = position + (Quaternion.Euler(0, i / (float)cell.PlantLevel * 360f, 0) * new Vector3(hash.a * 0.3f + 0.2f, 0, 0));
                instance.localRotation = Quaternion.Euler(0f, 360f * hash.a, 0f);
                instance.SetParent(container, false);
            }
        }
        else if (cell.ScenaryObject != 0 && cell.BuildingOnSquare == null)
        {
            cell.BuildingOnSquare = Instantiate(scenaryBuildings[cell.ScenaryObject - 1]);
            cell.BuildingOnSquare.Construct(cell, position, hash);
            cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false);
        }
    }
Пример #13
0
 void OnEnable()
 {
     GridMetrics.InitializeHashGrid(seed);
 }
Пример #14
0
    void AddHalfCell(SquareCell cell, GridDirection direction, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd, Vector3 vx, Vector3 vy, Vector3 vz)
    {
        Vector3    riverbed         = centre + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep;
        Vector3    midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep;
        Vector3    midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep;
        SquareCell neighborPrev     = cell.GetNeighbor(direction.Previous()) ?? cell;
        SquareCell neighborNext     = cell.GetNeighbor(direction.Next()) ?? cell;
        Vector3    midEdgePrev      = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((cell.CentreElevation + neighborPrev.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep;
        Vector3    midEdgeNext      = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((cell.CentreElevation + neighborNext.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep;

        if (cell.HasRiver)
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                terrain.AddTriangle(v0, midSolidEdgePrev, riverbed); // split tri into two tris
                terrain.AddTriangle(midSolidEdgePrev, v1, riverbed);
            }
            else
            {
                terrain.AddTriangle(v0, v1, riverbed);
            }                                          // edge with no river
            if (cell.HasRiverThroughEdge(direction.Next()))
            {
                terrain.AddTriangle(v1, midSolidEdgeNext, riverbed); // split tri into two tris
                terrain.AddTriangle(midSolidEdgeNext, v2, riverbed);
            }
            else
            {
                terrain.AddTriangle(v1, v2, riverbed);
            }                                          // edge with no river
        }
        else
        {
            terrain.AddTriangle(v0, v1, v2);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            terrain.AddQuad(v1, va, midEdgeNext, midSolidEdgeNext);
            terrain.AddQuad(midSolidEdgeNext, midEdgeNext, vb, v2);
        }
        else
        {
            terrain.AddQuad(v1, va, vb, v2);
        }                                    // top Edge
        if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            terrain.AddQuad(v1, midSolidEdgePrev, midEdgePrev, vd);
            terrain.AddQuad(midSolidEdgePrev, v0, vc, midEdgePrev);
        }
        else
        {
            terrain.AddQuad(v1, v0, vc, vd);
        }                                     // left Edge
        if (cell.HasRiverThroughEdge(direction))
        {
        }
        else
        {
            terrain.AddQuad(v1, vd, vx, va);
        }                                    // direction edge
        if (cell.HasRiverThroughEdge(direction.Next2()))
        {
        }
        else
        {
            terrain.AddQuad(v2, vb, vy, vz);
        }                                   // clockwise edge
        AddColors(cell, direction);

        if (cell.HasRoadThroughEdge(direction.Next()))
        {
            midEdgeNext      = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep;
            midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep;
            TriangulateRoadSegment(v1, midSolidEdgeNext, v2, va, midEdgeNext, vb);
        }
        if (cell.HasRoadThroughEdge(direction.Previous()))
        {
            midEdgePrev      = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep;
            midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep;
            TriangulateRoadSegment(v0, midSolidEdgePrev, v1, vc, midEdgePrev, vd);
        }
    }
Пример #15
0
    void AddMeshForSquare(SquareCell cell)
    {
        Vector3 centre         = cell.transform.localPosition;
        Vector3 verticleCentre = centre + Vector3.up * cell.CentreElevation * GridMetrics.elevationStep;
        Vector3 vb0            = centre + GridMetrics.GetEdge(GridDirection.SW);
        Vector3 vb1            = centre + GridMetrics.GetEdge(GridDirection.NW);
        Vector3 vb2            = centre + GridMetrics.GetEdge(GridDirection.NE);
        Vector3 vb3            = centre + GridMetrics.GetEdge(GridDirection.SE);

        vb0 = vb0 + Vector3.up * (cell.GridElevations.Y0) * GridMetrics.elevationStep;
        vb1 = vb1 + Vector3.up * (cell.GridElevations.Y1) * GridMetrics.elevationStep;
        vb2 = vb2 + Vector3.up * (cell.GridElevations.Y2) * GridMetrics.elevationStep;
        vb3 = vb3 + Vector3.up * (cell.GridElevations.Y3) * GridMetrics.elevationStep;

        Vector3 vs0 = centre + GridMetrics.GetSolidEdge(GridDirection.SW);
        Vector3 vs1 = centre + GridMetrics.GetSolidEdge(GridDirection.NW);
        Vector3 vs2 = centre + GridMetrics.GetSolidEdge(GridDirection.NE);
        Vector3 vs3 = centre + GridMetrics.GetSolidEdge(GridDirection.SE);


        Vector3 bridgeW = GridMetrics.GetBridge(GridDirection.W);
        Vector3 bridgeN = GridMetrics.GetBridge(GridDirection.N);
        Vector3 bridgeE = GridMetrics.GetBridge(GridDirection.E);
        Vector3 bridgeS = GridMetrics.GetBridge(GridDirection.S);

        Vector3 vS0 = vs0 + bridgeS + GetVertexBlendElevation(cell.GridElevations, GridDirection.SW, GridDirection.S);
        Vector3 vW0 = vs0 + bridgeW + GetVertexBlendElevation(cell.GridElevations, GridDirection.SW, GridDirection.W);
        Vector3 vN1 = vs1 + bridgeN + GetVertexBlendElevation(cell.GridElevations, GridDirection.NW, GridDirection.N);
        Vector3 vW1 = vs1 + bridgeW + GetVertexBlendElevation(cell.GridElevations, GridDirection.NW, GridDirection.W);
        Vector3 vN2 = vs2 + bridgeN + GetVertexBlendElevation(cell.GridElevations, GridDirection.NE, GridDirection.N);
        Vector3 vE2 = vs2 + bridgeE + GetVertexBlendElevation(cell.GridElevations, GridDirection.NE, GridDirection.E);
        Vector3 vE3 = vs3 + bridgeE + GetVertexBlendElevation(cell.GridElevations, GridDirection.SE, GridDirection.E);
        Vector3 vS3 = vs3 + bridgeS + GetVertexBlendElevation(cell.GridElevations, GridDirection.SE, GridDirection.S);

        if (cell.GridElevations.Y0 == cell.GridElevations.Y2)  // keep diagonals level
        {
            vs0 += Vector3.up * (cell.GridElevations.Y0) * GridMetrics.elevationStep;
            vs1 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NW);
            vs2 += Vector3.up * (cell.GridElevations.Y2) * GridMetrics.elevationStep;
            vs3 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SE);
        }
        else if (cell.GridElevations.Y1 == cell.GridElevations.Y3)
        {
            vs0 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SW);
            vs1 += Vector3.up * (cell.GridElevations.Y1) * GridMetrics.elevationStep;
            vs2 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NE);
            vs3 += Vector3.up * (cell.GridElevations.Y3) * GridMetrics.elevationStep;
        }
        else
        {
            vs0 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SW);
            vs1 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NW);
            vs2 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NE);
            vs3 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SE);
        }

        // Works out which diagonal to add
        if (cell.GridElevations.Y0 == cell.GridElevations.Y2 || Mathf.Abs(cell.GridElevations.Y0 - cell.GridElevations.Y2) < Mathf.Abs(cell.GridElevations.Y1 - cell.GridElevations.Y3))  // sets direction of the triangle pairs in the quad
        {
            AddHalfCell(cell, GridDirection.NW, centre, vs0, vs1, vs2, vN1, vN2, vW0, vW1, vb1, vb2, vE2);
            AddHalfCell(cell, GridDirection.SE, centre, vs2, vs3, vs0, vS3, vS0, vE2, vE3, vb3, vb0, vW0);
        }
        else
        {
            AddHalfCell(cell, GridDirection.SW, centre, vs3, vs0, vs1, vW0, vW1, vS3, vS0, vb0, vb1, vN1);
            AddHalfCell(cell, GridDirection.NE, centre, vs1, vs2, vs3, vE2, vE3, vN1, vN2, vb2, vb3, vS3);
        }
        if (cell.HasRoads)
        {
            TriangulateRoadCentre(cell, verticleCentre, vs0, vs1, vs2, vs3);
        }
        if (cell.HasRiver)
        {
            if (cell.HasRiverThroughEdge(GridDirection.N))
            {
                TriangulateWithRiver(GridDirection.N, cell, centre, vs1, vb1, vb2, vs2, 0f);
            }
            else
            {
                TriangulateWithRiver(GridDirection.N, cell, centre, vs1, vb1, vb2, vs2, 0f);
            }
            if (cell.HasRiverThroughEdge(GridDirection.E))
            {
                TriangulateWithRiver(GridDirection.E, cell, centre, vs2, vb2, vb3, vs3, 0.5f);
            }
            else
            {
                TriangulateWithRiver(GridDirection.E, cell, centre, vs2, vb2, vb3, vs3, 0.5f);
            }
            if (cell.HasRiverThroughEdge(GridDirection.S))
            {
                TriangulateWithRiver(GridDirection.S, cell, centre, vs3, vb3, vb0, vs0, 1f);
            }
            else
            {
                TriangulateWithRiver(GridDirection.S, cell, centre, vs3, vb3, vb0, vs0, 1f);
            }
            if (cell.HasRiverThroughEdge(GridDirection.W))
            {
                TriangulateWithRiver(GridDirection.W, cell, centre, vs0, vb0, vb1, vs1, 0.5f);
            }
            else
            {
                TriangulateWithRiver(GridDirection.W, cell, centre, vs0, vb0, vb1, vs1, 0.5f);
            }
        }
        if (cell.IsUnderwater)
        {
            AddWaterForSquare(cell, centre);
        }
        if (!cell.IsUnderwater && !cell.HasRoads)
        {
            features.AddFeature(cell, verticleCentre);
        }
    }