Example #1
0
    void TriangulateWithRiver(
        GridDirection direction, SquareCell cell, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float v
        )
    {
        GridDirection flowDirection;
        bool          reversed = cell.HasIncomingRiver[(int)direction];

        if (cell.HasOutgoingRiver[(int)direction])
        {
            flowDirection = direction;
        }
        else if (reversed)
        {
            flowDirection = direction.Opposite();
        }
        else
        {
            if (cell.HasIncomingRiver[(int)direction.Next2()] && cell.HasOutgoingRiver[(int)direction.Previous2()])
            {
                flowDirection = direction.Previous2();
            }
            else if (cell.HasOutgoingRiver[(int)direction.Next2()] && cell.HasIncomingRiver[(int)direction.Previous2()])
            {
                flowDirection = direction.Next2();
            }
            else
            {
                flowDirection = direction.Opposite();
            }
        }
        TriangulateRiverTri(centre, v0, v3, cell.RiverSurfaceY, reversed, direction, flowDirection);
        SquareCell neighbor = cell.GetNeighbor(direction);

        if (neighbor && cell.HasRiverThroughEdge(direction))
        {
            TriangulateRiverQuad(v3, v0, v1, v2, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f, reversed);
        }
    }
Example #2
0
    void AddColors(SquareCell cell, GridDirection direction)
    {
        SquareCell prevNeighbor  = cell.GetNeighbor(direction.Previous()) ?? cell;
        SquareCell neighbor      = cell.GetNeighbor(direction) ?? cell;
        SquareCell nextNeighbor  = cell.GetNeighbor(direction.Next()) ?? cell;
        SquareCell next2Neighbor = cell.GetNeighbor(direction.Next2()) ?? cell;
        SquareCell next3Neighbor = cell.GetNeighbor(direction.Next3()) ?? cell;

        Color previousMix     = (GetColor(prevNeighbor, cell) + cell.Color) / 2f;
        Color neighborMix     = (GetColor(neighbor, cell) + cell.Color + GetColor(prevNeighbor, cell) + GetColor(nextNeighbor, cell)) / 4f;
        Color nextMix         = (GetColor(nextNeighbor, cell) + cell.Color) / 2f;
        Color nextNeighborMix = (GetColor(nextNeighbor, cell) + cell.Color + GetColor(next2Neighbor, cell) + GetColor(next3Neighbor, cell)) / 4f;
        Color next2Mix        = (GetColor(next3Neighbor, cell) + cell.Color) / 2f;

        if (cell.HasRiver)
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                terrain.AddTriangleColor(cell.Color);
            }
            if (cell.HasRiverThroughEdge(direction.Next()))
            {
                terrain.AddTriangleColor(cell.Color);
            }
            terrain.AddTriangleColor(cell.Color);
            terrain.AddTriangleColor(cell.Color);
        }
        else
        {
            terrain.AddTriangleColor(cell.Color);
        }
        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color);
            terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color);
        }
        else
        {
            terrain.AddQuadColor(cell.Color, nextMix, nextMix, cell.Color);
        }                                                                   // next Edge
        if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix);
            terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix);
        }
        else
        {
            terrain.AddQuadColor(cell.Color, cell.Color, previousMix, previousMix);
        }                                                                            // previous Edge
        if (cell.HasRiverThroughEdge(direction))
        {
        }
        else
        {
            terrain.AddQuadColor(cell.Color, previousMix, neighborMix, nextMix);
        }                                                                        // direction Corner
        if (cell.HasRiverThroughEdge(direction.Next2()))
        {
        }
        else
        {
            terrain.AddQuadColor(cell.Color, nextMix, nextNeighborMix, next2Mix);
        }                                                                        // next Corner
    }
Example #3
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);
        }
    }
Example #4
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);
        }
    }