예제 #1
0
 protected static void TriangulateQuad(HexMesh mesh, EdgeVertices e1, EdgeVertices e2, Color c1, Color c2)
 {
     mesh.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
     mesh.AddQuadColor(c1, c1, c2, c2);
     mesh.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
     mesh.AddQuadColor(c1, c1, c2, c2);
     mesh.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
     mesh.AddQuadColor(c1, c1, c2, c2);
     mesh.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
     mesh.AddQuadColor(c1, c1, c2, c2);
 }
예제 #2
0
    void TriangulateCornerTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1);
        Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1);
        Color   c3 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, 1);
        Color   c4 = HexMetrics.TerraceLerp(beginCell.Color, rightCell.Color, 1);

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleColor(beginCell.Color, c3, c4);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   c1 = c3;
            Color   c2 = c4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            c3 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, i);
            c4 = HexMetrics.TerraceLerp(beginCell.Color, rightCell.Color, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(c1, c2, c3, c4);
        }

        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadColor(c3, c4, leftCell.Color, rightCell.Color);
    }
예제 #3
0
    private void TriangulateEdgeStrip(EdgeVertices e1, Color c1, EdgeVertices e2, Color c2, bool hasWall = false)
    {
        _terrain.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
        _terrain.AddQuadColor(c1, c2);
        _terrain.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
        _terrain.AddQuadColor(c1, c2);
        _terrain.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
        _terrain.AddQuadColor(c1, c2);
        _terrain.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
        _terrain.AddQuadColor(c1, c2);

        if (hasWall)
        {
            TriangulateWallSegment(e1.v2, e1.v3, e1.v4, e2.v2, e2.v3, e2.v4);
        }
    }
예제 #4
0
    public override void Triangulate(HexMesh mesh)
    {
        Vector3 v1 = beginCorner;
        Vector3 v2 = beginCorner;
        Color   c1 = beginCell.Color;
        Color   c2 = beginCell.Color;

        for (int step = 1; step < HexMetrics.terraceSteps + 1; ++step)
        {
            Vector3 v3 = HexMetrics.TerraceLerp(beginCorner, leftCorner, step);
            Vector3 v4 = HexMetrics.TerraceLerp(beginCorner, rightCorner, step);

            Color c3 = HexMetrics.ColorLerp(beginCell.Color, leftCell.Color, step);
            Color c4 = HexMetrics.ColorLerp(beginCell.Color, rightCell.Color, step);

            if (step == 1)
            {
                mesh.AddTriangle(v1, v3, v4);
                mesh.AddTriangleColor(c1, c3, c4);
            }
            else
            {
                mesh.AddQuad(v1, v2, v3, v4);
                mesh.AddQuadColor(c1, c2, c3, c4);
            }
            v1 = v3;
            v2 = v4;
            c1 = c3;
            c2 = c4;
        }
    }
예제 #5
0
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            centerL = center;
            centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.kInnerToOuter);
        }
        else
        {
            centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.kInnerToOuter);
            centerR = center;
        }

        center = Vector3.Lerp(centerL, centerR, 0.5f);

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(centerL, e.v1, 0.5f),
            Vector3.Lerp(centerR, e.v5, 0.5f),
            1f / 6f
            );

        m.v3.y = center.y = e.v3.y;
        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);

        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddTriangleColor(cell.Color);
        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuadColor(cell.Color);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddQuadColor(cell.Color);
        terrain.AddTriangle(centerR, m.v4, m.v5);
        terrain.AddTriangleColor(cell.Color);

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f, HexMetrics.kRiverSolidUVStep, reversed);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f + HexMetrics.kRiverSolidUVStep, HexMetrics.kRiverSolidUVStep, reversed);
        }
    }
예제 #6
0
 void TriangulateEdgeStrip(EdgeVertices e1, Color c1, EdgeVertices e2, Color c2)
 {
     terrain.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
     terrain.AddQuadColor(c1, c2);
     terrain.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
     terrain.AddQuadColor(c1, c2);
     terrain.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
     terrain.AddQuadColor(c1, c2);
     terrain.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
     terrain.AddQuadColor(c1, c2);
 }
예제 #7
0
    void TriangulateCornerTerraces(Vector3 begin, HexCell beginCell,
                                   Vector3 left, HexCell leftCell,
                                   Vector3 right, HexCell rightCell)
    {
        Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1);
        Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1);
        Color   c3 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, 1);
        Color   c4 = HexMetrics.TerraceLerp(beginCell.Color, rightCell.Color, 1);

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleColor(beginCell.Color, c3, c4);

        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadColor(c3, c4, leftCell.Color, rightCell.Color);
    }
예제 #8
0
    /*
     * 连接三角形  针对left right都是梯田的
     */
    void TriangulateCornerTerraces(
        Vector3 begin, HexCell beginCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell)
    {
        //在slope-slope-flat类型中,和平台的插值TriangulateEdgeTerraces方法一样
        Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1);
        Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1);
        Color   c3 = HexMetrics.TerraceLerp(color1, color2, 1);
        Color   c4 = HexMetrics.TerraceLerp(color1, color3, 1);
        //添加地形贴图UV
        Vector3 types;

        types.x = beginCell.TerrainTypeIndex;
        types.y = leftCell.TerrainTypeIndex;
        types.z = rightCell.TerrainTypeIndex;

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleColor(color1, c3, c4);
        terrain.AddTriangleTerrainTypes(types);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   c1 = c3;
            Color   c2 = c4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            c3 = HexMetrics.TerraceLerp(color1, color2, i);
            c4 = HexMetrics.TerraceLerp(color1, color3, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(c1, c2, c3, c4);
            terrain.AddQuadTerrainTypes(types);
        }
        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadColor(c3, c4, color2, color3);
        terrain.AddQuadTerrainTypes(types);
    }
예제 #9
0
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        //outer walls
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            centerL = center +
                      HexMetric.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center +
                      HexMetric.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        // sharp turns
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        // two way turns
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            centerL = center;
            centerR = center + HexMetric.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetric.innerToOuter);
        }
        else
        {
            centerL = center + HexMetric.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetric.innerToOuter);
            centerR = center;
        }

        //mid point of channel
        EdgeVertices m = new EdgeVertices(Vector3.Lerp(centerL, e.v1, 0.5f), Vector3.Lerp(centerR, e.v5, 0.5f), 1f / 6f);

        m.v3.y = center.y = e.v3.y;
        //fill area
        TriangulateEdgeStrip(m, color1, cell.TerrainTypeIndex, e, color1, cell.TerrainTypeIndex);
        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddTriangle(centerR, m.v4, m.v5);

        terrain.AddTriangleColor(color1);
        terrain.AddQuadColor(color1);
        terrain.AddQuadColor(color1);
        terrain.AddTriangleColor(color1);

        Vector3 types;

        types.x = types.y = types.z = cell.TerrainTypeIndex;
        terrain.AddTriangleTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddTriangleTerrainTypes(types);

        //river water quads
        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;

            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed);
        }
    }
예제 #10
0
    void TriangulateConnection(
        HexDirection direction, HexCell cell, Vector3 vert1, Vector3 vert2
        )
    {
        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            return;
        }
        Vector3 bridge = Hexmetrics.GetBridge(direction);
        Vector3 vert3  = vert1 + bridge;
        Vector3 vert4  = vert2 + bridge;

        vert3.y = vert4.y = neighbor.Elevation * Hexmetrics.elevationChange;

        if (cell.GetEdgeType(direction) == HexEdgeType.Slope)
        {
            TriangulateEdgeTerraces(vert1, vert2, cell, vert3, vert4, neighbor);
        }
        else
        {
            terrain.AddQuad(vert1, vert2, vert3, vert4);
            terrain.AddQuadColor(cell.color, neighbor.color);
        }
//		for (int i = 2; i < Hexmetrics.terraceSteps; i++) {
//			Vector3 v1 = vert3;
//			Vector3 v2 = vert4;
//			Color c1 = c2;
//			vert3 = Hexmetrics.TerraceLerp(beginLeft, endLeft, i);
//			vert4 = Hexmetrics.TerraceLerp(beginRight, endRight, i);
//			c2 = Hexmetrics.TerraceLerp(beginCell.color, endCell.color, i);
//			terrain.AddQuad(v1, v2, v3, v4);
//			terrain.AddQuadColor(c1, c2);
//		}
//
//		terrain.AddQuad(vert3, vert4, endLeft, endRight);
//		terrain.AddQuadColor(c2, endCell.color);


        HexCell nextNeighbor = cell.GetNeighbor(direction.Next());

        if (direction <= HexDirection.E && nextNeighbor != null)
        {
            Vector3 vert5 = vert2 + Hexmetrics.GetBridge(direction.Next());
            vert5.y = nextNeighbor.Elevation * Hexmetrics.elevationChange;


            if (cell.Elevation <= neighbor.Elevation)
            {
                if (cell.Elevation <= nextNeighbor.Elevation)
                {
                    TriangulateCorner(vert2, cell, vert4, neighbor, vert5, nextNeighbor);
                }
                else
                {
                    TriangulateCorner(vert5, nextNeighbor, vert2, cell, vert4, neighbor);
                }
            }
            else if (neighbor.Elevation <= nextNeighbor.Elevation)
            {
                TriangulateCorner(vert4, neighbor, vert5, nextNeighbor, vert2, cell);
            }
            else
            {
                TriangulateCorner(vert5, nextNeighbor, vert2, cell, vert4, neighbor);
            }

            terrain.AddTriangle(vert2, vert4, vert5);
            terrain.AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color);
        }
    }
    void TriangulateWithRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e
        )
    {
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            centerL = center +
                      HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center +
                      HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            centerL = center;
            centerR = center +
                      HexMetrics.GetSolidEdgeMiddle(direction.Next()) *
                      (0.5f * HexMetrics.innerToOuter);
        }
        else
        {
            centerL = center +
                      HexMetrics.GetSolidEdgeMiddle(direction.Previous()) *
                      (0.5f * HexMetrics.innerToOuter);
            centerR = center;
        }
        center = Vector3.Lerp(centerL, centerR, 0.5f);


        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(centerL, e.v1, 0.5f),
            Vector3.Lerp(centerR, e.v5, 0.5f),
            1f / 6f
            );

        m.v3.y = center.y = e.v3.y;
        TriangulateEdgeStrip(m, color1, (int)cell.TerrainType, e, color1, (int)cell.TerrainType);

        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddTriangle(centerR, m.v4, m.v5);

        terrain.AddTriangleColor(color1);
        terrain.AddQuadColor(color1);
        terrain.AddQuadColor(color1);
        terrain.AddTriangleColor(color1);

        Vector3 types;

        types.x = types.y = types.z = (float)cell.TerrainType;
        terrain.AddTriangleTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddTriangleTerrainTypes(types);

        bool reversed = cell.IncomingRiver == direction;

        TriangulateRiverQuad(
            centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed
            );
        TriangulateRiverQuad(
            m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed
            );
    }
예제 #12
0
    /// <summary>
    /// 细胞中心河流河道的绘制方法
    /// 有流入和有流出的情况
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="cell"></param>
    /// <param name="center"></param>
    /// <param name="e"></param>
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            //通过前一个方向得到中心点往左偏移的位置
            centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            //通过下一个方向得到中心点往右偏移的位置
            centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            //同一个细胞中,如果当前方向相邻1个单位方向上有河道,那么相连处河道拓宽,让河流能通过
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            //同一个细胞中,如果当前方向相邻1个单位方向上有河道,那么相连处河道拓宽,让河流能通过
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            //同一个细胞中,如果当前方向相邻2个单位方向上有河道
            centerL = center;
            centerR = center + HexMetrics.GetSoliEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.innerToOuter);
        }
        else
        {
            //同一个细胞中,如果当前方向相邻2个单位方向上有河道
            centerL = center + HexMetrics.GetSoliEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.innerToOuter);
            centerR = center;
        }

        center = Vector3.Lerp(centerL, centerR, 0.5f);

        //得到偏移后的左右两点与细胞的边界顶点做差值,得到中间位置的点
        EdgeVertices m = new EdgeVertices(Vector3.Lerp(centerL, e.v1, 0.5f), Vector3.Lerp(centerR, e.v5, 0.5f), 1f / 6f);

        //将细胞顶面中的河道中心线的高度设为一样
        m.v3.y = center.y = e.v3.y;

        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);

        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddTriangleColor(cell.Color);
        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuadColor(cell.Color);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddQuadColor(cell.Color);
        terrain.AddTriangle(centerR, m.v4, m.v5);
        terrain.AddTriangleColor(cell.Color);

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed);
        }
    }
    void Triangulate(HexDirection direction, HexCell cell)
    {
        bool    isDeep = cell.Elevation == ElevationLevel.Deep ? true : false;
        Vector3 center = cell.transform.localPosition;
        Vector3 v1     = center + HexMetrics.GetFirstSolidCorner(direction, isDeep);
        Vector3 v2     = center + HexMetrics.GetSecondSolidCorner(direction, isDeep);

        //Center Tris
        terrain.AddTriangle(center, v1, v2);
        terrain.AddTriangleColor(cell.Color);

        Vector3 edge   = HexMetrics.GetEdge(direction, isDeep);
        Vector3 tempV3 = center + HexMetrics.GetFirstEdgeCorner(direction, isDeep);
        Vector3 tempV4 = center + HexMetrics.GetSecondEdgeCorner(direction, isDeep);
        Vector3 v3     = tempV3 + edge;
        Vector3 v4     = tempV4 + edge;

        HexCell prevNeighbor = cell.GetNeighbor(direction.Previous()) ?? cell;
        HexCell neighbor     = cell.GetNeighbor(direction) ?? cell;
        HexCell nextNeighbor = cell.GetNeighbor(direction.Next()) ?? cell;

        //Edge Elevation
        if (cell.Elevation < neighbor.Elevation)
        {
            v3.y = v4.y = neighbor.Position.y;
        }

        //Edge Terrace Quads & Quads
        if (isDeep && neighbor.Elevation == ElevationLevel.Flat)
        {
            TriangulateEdgeTerraces(v1, v2, cell, v3, v4, neighbor);
        }
        else if (isDeep && neighbor.Elevation != ElevationLevel.Flat &&
                 cell.Elevation < neighbor.Elevation)
        {
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(neighbor.Color);
        }
        else
        {
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(cell.Color);
        }

        Vector3 v5 = center + HexMetrics.GetFirstCorner(direction);
        Vector3 v6 = center + HexMetrics.GetSecondCorner(direction);

        //Vertice Elevation Change
        if (cell.Elevation < neighbor.Elevation)
        {
            v5.y = v6.y = neighbor.Position.y;
        }
        if (cell.Elevation < nextNeighbor.Elevation)
        {
            if (nextNeighbor.Elevation < neighbor.Elevation)
            {
                v6.y = neighbor.Position.y;
            }
            else
            {
                v6.y = nextNeighbor.Position.y;
            }
        }
        if (cell.Elevation < prevNeighbor.Elevation)
        {
            if (prevNeighbor.Elevation < neighbor.Elevation)
            {
                v5.y = neighbor.Position.y;
            }
            else
            {
                v5.y = prevNeighbor.Position.y;
            }
        }

        //Corner Tris & Corner Terrace Tris
        if (isDeep)
        {
            if (neighbor.Elevation == ElevationLevel.Flat)
            {
                TriangulateCornerTerraces(v1, cell, v5, v3, neighbor);
                TriangulateCornerTerraces(v2, cell, v4, v6, neighbor);
            }
            else if (cell.Elevation == neighbor.Elevation)
            {
                if (nextNeighbor.Elevation == ElevationLevel.Flat &&
                    prevNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulateOuterCornerTerraces(v5, cell, v3, v1, prevNeighbor);
                    TriangulateOuterCornerTerraces(v6, cell, v2, v4, nextNeighbor);
                }
                else if (nextNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulateOuterCornerTerraces(v6, cell, v2, v4, nextNeighbor);
                    terrain.AddTriangle(v1, v5, v3);
                    if (cell.Elevation < prevNeighbor.Elevation)
                    {
                        terrain.AddTriangleColor(prevNeighbor.Color);
                    }
                    else
                    {
                        terrain.AddTriangleColor(cell.Color);
                    }
                }
                else if (prevNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulateOuterCornerTerraces(v5, cell, v3, v1, prevNeighbor);
                    terrain.AddTriangle(v2, v4, v6);
                    if (cell.Elevation < nextNeighbor.Elevation)
                    {
                        terrain.AddTriangleColor(nextNeighbor.Color);
                    }
                    else
                    {
                        terrain.AddTriangleColor(cell.Color);
                    }
                }
                else if (cell.Elevation < nextNeighbor.Elevation &&
                         cell.Elevation < prevNeighbor.Elevation)
                {
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(prevNeighbor.Color);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(nextNeighbor.Color);
                }
                else if (cell.Elevation < nextNeighbor.Elevation)
                {
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(cell.Color);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(nextNeighbor.Color);
                }
                else if (cell.Elevation < prevNeighbor.Elevation)
                {
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(prevNeighbor.Color);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(cell.Color);
                }
                else
                {
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(cell.Color);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(cell.Color);
                }
            }
            else
            {
                if (nextNeighbor.Elevation == ElevationLevel.Flat &&
                    prevNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulateNextCornerTerracesCliff(v6, cell, v2, v4, neighbor, nextNeighbor);
                    TriangulatePrevCornerTerracesCliff(v5, cell, v3, v1, neighbor, prevNeighbor);
                }
                else if (nextNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulateNextCornerTerracesCliff(v6, cell, v2, v4, neighbor, nextNeighbor);
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(neighbor.Color);
                }
                else if (prevNeighbor.Elevation == ElevationLevel.Flat)
                {
                    TriangulatePrevCornerTerracesCliff(v5, cell, v3, v1, neighbor, prevNeighbor);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(neighbor.Color);
                }
                else
                {
                    terrain.AddTriangle(v1, v5, v3);
                    terrain.AddTriangleColor(neighbor.Color);
                    terrain.AddTriangle(v2, v4, v6);
                    terrain.AddTriangleColor(neighbor.Color);
                }
            }
        }
        else
        {
            terrain.AddTriangle(v1, v5, v3);
            terrain.AddTriangleColor(cell.Color);
            terrain.AddTriangle(v2, v4, v6);
            terrain.AddTriangleColor(cell.Color);
        }

        //Features
        if (cell.Elevation == ElevationLevel.Flat)
        {
            features.AddFeature(cell, (center + v1 + v5) * (1f / 3f));
        }
    }
예제 #14
0
    /// <summary>
    /// 生成有河流的三角网格
    /// </summary>
    /// <param name="direction">处理的对应方向</param>
    /// <param name="cell">六边形对象引用</param>
    /// <param name="center">中心点坐标</param>
    /// <param name="e">边界中值插值对象</param>
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            // 河道拓宽为直线的左边界点,后续逻辑以此类推
            // 总之向转弯内侧进行网格拼接
            centerL = center +
                      HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center +
                      HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            centerL = center;
            centerR = center +
                      HexMetrics.GetSolidEdgeMiddle(direction.Next()) *
                      (0.5f * HexMetrics.innerToOuter);
        }
        else
        {
            centerL = center +
                      HexMetrics.GetSolidEdgeMiddle(direction.Previous()) *
                      (0.5f * HexMetrics.innerToOuter);
            centerR = center;
        }
        center = Vector3.Lerp(centerL, centerR, 0.5f);

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(centerL, e.v1, 0.5f),
            Vector3.Lerp(centerR, e.v5, 0.5f),
            1f / 6f
            );

        // 同步河道底部高度
        m.v3.y = center.y = e.v3.y;
        // 填充插值中间点与边界间的平面
        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);

        // 根据计算进行网格拼接
        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddTriangleColor(cell.Color);
        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuadColor(cell.Color);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddQuadColor(cell.Color);
        terrain.AddTriangle(centerR, m.v4, m.v5);
        terrain.AddTriangleColor(cell.Color);

        // 排除河流在水面下显示
        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(
                centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed
                );
            TriangulateRiverQuad(
                m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed
                );
        }
    }
예제 #15
0
    private void TriangulateWithRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

        // Two cases:
        // If the cell has a river going through the opposite direction as well as the direction
        // that we are working with, the cell holds a straight river.
        if (cell.HasRiverThroughEdge(direction.Opposite()))
        {
            // Stretch the center into a line. Move 25% from the center to the first corner of the previous
            // direction, and 25% from the center to the second corner of the second direction.
            // One simple way of visualizing this is having a top-down view of the HexMesh and imagining
            // a triangulation in the eastern direction.
            centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;

            // Otherwise, the river does not flow in a straight line, check special cases:
            // Detect sharp turns by checking whether the cell has a rive going through the next
            // or previous cell part.
            // When there is a sharp turn, align the center line with the edge between this and the adjacent part.
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f /* Increased center line width from 1/2 to 2/3 */);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f /* Increased center line width from 1/2 to 2/3 */);
            centerR = center;

            // 2 step rotations, these produce gently curving rivers.
            // A river is going through two directions after this one.
            // Expand the center towards the center of the next direction's edge.
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))
        {
            centerL = center;
            // Note that the edge middle point is closer that the vertex itself (it's within the inner radius)
            // which is why extending the center towards that edge will end up with a pinched section.
            // We extend the center edge towards the middle edge times innerToOuter radius to keep
            // the channel width constant.
            centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next())
                      * (0.5f * HexMetrics.innerToOuter);
            // 2 step rotation, a river is going through two directions before this one.
        }
        else
        {
            centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous())
                      * (0.5f * HexMetrics.innerToOuter);
            centerR = center;
        }

        // Determine the final center by averaging the Left and Right centers
        center = Vector3.Lerp(centerL, centerR, 0.5f);

        // We lerp the second and fourth vertices using 1/6 instead of the usual 1/4 as the
        // length from the edges is 1/8 instead of 1/4. This is because the channel has a
        // the same width along the river, so the relative edge length of the outer edges
        // will be 1/6 relative to the edge's middle length. (1/8 of 3/4)
        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(centerL, e.v1, 0.5f),
            Vector3.Lerp(centerR, e.v5, 0.5f),
            1f / 6f);

        m.v3.y = center.y = e.v3.y;
        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);

        // Add the triangles and quads that reached the center.
        terrain.AddTriangle(centerL, m.v1, m.v2);
        terrain.AddTriangleColor(cell.Color);

        terrain.AddQuad(centerL, center, m.v2, m.v3);
        terrain.AddQuadColor(cell.Color);
        terrain.AddQuad(center, centerR, m.v3, m.v4);
        terrain.AddQuadColor(cell.Color);

        terrain.AddTriangle(centerR, m.v4, m.v5);
        terrain.AddTriangleColor(cell.Color);

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed);
        }
    }