コード例 #1
0
    public void TriangulateEstuary(EdgeVertices edges1, EdgeVertices edges2, bool incomingRiver, Vector3 indices)
    {
        WaterShore.AddTriangle(edges2.v1, edges1.v2, edges1.v1);
        WaterShore.AddTriangle(edges2.v5, edges1.v5, edges1.v4);
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        WaterShore.AddTriangleCellData(indices, Weights2, Weights1, Weights1);
        WaterShore.AddTriangleCellData(indices, Weights2, Weights1, Weights1);

        Estuaries.AddQuad(edges2.v1, edges1.v2, edges2.v2, edges1.v3);
        Estuaries.AddTriangle(edges1.v3, edges2.v2, edges2.v4);
        Estuaries.AddQuad(edges1.v3, edges1.v4, edges2.v4, edges2.v5);

        Estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f));
        Estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f));
        Estuaries.AddQuadUV(0f, 0f, 0f, 1f);

        Estuaries.AddQuadCellData(indices, Weights2, Weights1, Weights2, Weights1);
        Estuaries.AddTriangleCellData(indices, Weights1, Weights2, Weights2);
        Estuaries.AddQuadCellData(indices, Weights1, Weights2);

        if (incomingRiver)
        {
            Estuaries.AddQuadUV2(new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f), new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f));
            Estuaries.AddTriangleUV2(new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f));
            Estuaries.AddQuadUV2(new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f), new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f));
        }
        else
        {
            Estuaries.AddQuadUV2(new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f), new Vector2(0f, 0f), new Vector2(0.5f, -0.3f));
            Estuaries.AddTriangleUV2(new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f));
            Estuaries.AddQuadUV2(new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f), new Vector2(1f, 0f), new Vector2(1.5f, -0.2f));
        }
    }
コード例 #2
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.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, weights1, cell.Index, e, weights1, cell.Index);

        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);

        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;
        terrain.AddTriangleCellData(indices, weights1);
        terrain.AddQuadCellData(indices, weights1);
        terrain.AddQuadCellData(indices, weights1);
        terrain.AddTriangleCellData(indices, weights1);

        if (!cell.IsUnderWater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed, indices);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices);
        }
    }
コード例 #3
0
 public void TriangulateRoadSegment(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 v5, Vector3 v6, Color w1, Color w2, Vector3 indices)
 {
     Roads.AddQuad(v1, v2, v4, v5);
     Roads.AddQuad(v2, v3, v5, v6);
     Roads.AddQuadUV(0, 1, 0, 0);
     Roads.AddQuadUV(1, 0, 0, 0);
     Roads.AddQuadCellData(indices, w1, w2);
     Roads.AddQuadCellData(indices, w1, w2);
 }
コード例 #4
0
 void TriangulateRoadSegment(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 v5, Vector3 v6, Color w1, Color w2, Vector3 indices)
 {
     roads.AddQuad(v1, v2, v4, v5);
     roads.AddQuad(v2, v3, v5, v6);
     roads.AddQuadUV(0f, 1f, 0f, 0f);
     roads.AddQuadUV(1f, 0f, 0f, 0f);
     roads.AddQuadCellData(indices, w1, w2);
     roads.AddQuadCellData(indices, w1, w2);
 }
コード例 #5
0
    void TriangulatePointTerraces(Vector3 begin, HexCell beginCell, Vector3 left,
                                  HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        Vector3 v3 = Hex.TerraceLerp(begin, left, 1);
        Vector3 v4 = Hex.TerraceLerp(begin, right, 1);
        Color   w3 = Hex.TerraceLerp(weights1, weights2, 1);
        Color   w4 = Hex.TerraceLerp(weights1, weights3, 1);
        Vector3 indices;

        indices.x = beginCell.Index;
        indices.y = leftCell.Index;
        indices.z = rightCell.Index;

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleCellData(indices, weights1, w3, w4);

        for (int i = 2; i < Hex.terracesSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   w1 = w3;
            Color   w2 = w4;
            v3 = Hex.TerraceLerp(begin, left, i);
            v4 = Hex.TerraceLerp(begin, right, i);
            w3 = Hex.TerraceLerp(weights1, weights2, i);
            w4 = Hex.TerraceLerp(weights1, weights3, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadCellData(indices, w1, w2, w3, w4);
        }

        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadCellData(indices, w3, w4, weights2, weights3);
    }
コード例 #6
0
    void TriangulateEdgeStrip(EdgeVertices e1,
                              Color w1,
                              float index1,
                              EdgeVertices e2,
                              Color w2,
                              float index2,
                              bool hasRoad = false)
    {
        terrain.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
        terrain.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
        terrain.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
        terrain.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);

        Vector3 indices;

        indices.x = indices.z = index1;
        indices.y = index2;
        terrain.AddQuadCellData(indices, w1, w2);
        terrain.AddQuadCellData(indices, w1, w2);
        terrain.AddQuadCellData(indices, w1, w2);
        terrain.AddQuadCellData(indices, w1, w2);

        if (hasRoad)
        {
            TriangulateRoadSegment(e1.v2, e1.v3, e1.v4, e2.v2, e2.v3, e2.v4, w1, w2, indices);
        }
    }
コード例 #7
0
    public void TriangulateWithRiver(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges)
    {
        Vector3 centerL;
        Vector3 centerR;

        float centerLinePinch = 2.0f / 3.0f;

        if (cell.HasRiverThroughEdge(dir.Opposite()))
        {
            centerL = center + HexMetrics.GetFirstSolidCorner(dir.Previous()) * HexMetrics.SubdivideFraction;
            centerR = center + HexMetrics.GetSecondSolidCorner(dir.Next()) * HexMetrics.SubdivideFraction;
            center  = (centerL + centerR) / 2.0f;
        }
        else if (cell.HasRiverThroughEdge(dir.Next()))
        {
            centerL = center;
            centerR = Vector3.Lerp(center, edges.v5, centerLinePinch);
        }
        else if (cell.HasRiverThroughEdge(dir.Previous()))
        {
            centerL = Vector3.Lerp(center, edges.v1, centerLinePinch);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(dir.Next2()))
        {
            centerL = center;
            centerR = center + HexMetrics.GetSolidEdgeMiddle(dir.Next()) * (0.5f * HexMetrics.InnerToOuter);
        }
        else
        {
            centerL = center + HexMetrics.GetSolidEdgeMiddle(dir.Previous()) * (0.5f * HexMetrics.InnerToOuter);
            centerR = center;
        }

        EdgeVertices modifiedEdges = new EdgeVertices(Vector3.Lerp(centerL, edges.v1, 0.5f), Vector3.Lerp(centerR, edges.v5, 0.5f));

        modifiedEdges.v3.y = center.y = edges.v3.y;

        TriangulateEdgeStrip(modifiedEdges, Weights1, cell.TerrainTypeIndex, edges, Weights1, cell.CellIndex);

        Terrain.AddTriangle(centerL, modifiedEdges.v1, modifiedEdges.v2);
        Terrain.AddQuad(centerL, center, modifiedEdges.v2, modifiedEdges.v3);
        Terrain.AddQuad(center, centerR, modifiedEdges.v3, modifiedEdges.v4);
        Terrain.AddTriangle(centerR, modifiedEdges.v4, modifiedEdges.v5);

        Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex);

        Terrain.AddTriangleCellData(indices, Weights1);
        Terrain.AddQuadCellData(indices, Weights1);
        Terrain.AddQuadCellData(indices, Weights1);
        Terrain.AddTriangleCellData(indices, Weights1);

        if (!cell.IsUnderwater)
        {
            bool reverse = cell.IncomingRiverDirection == dir;

            TriangulateRiverQuad(centerL, centerR, modifiedEdges.v2, modifiedEdges.v4, cell.RiverSurfaceY, 0.4f, reverse, indices);
            TriangulateRiverQuad(modifiedEdges.v2, modifiedEdges.v4, edges.v2, edges.v4, cell.RiverSurfaceY, 0.6f, reverse, indices);
        }
    }
コード例 #8
0
 void TriangulateRiverQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float v, bool reversed, Vector3 indices)
 {
     v1.y = v2.y = y1;
     v3.y = v4.y = y2;
     rivers.AddQuad(v1, v2, v3, v4);
     if (reversed)
     {
         rivers.AddQuadUV(1f, 0f, 0.8f - v, 0.6f - v);
     }
     else
     {
         rivers.AddQuadUV(0f, 1f, v, v + 0.2f);
     }
     rivers.AddQuadCellData(indices, weights1, weights2);
 }
コード例 #9
0
    void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
    {
        Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction);
        Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction);

        water.AddTriangle(center, c1, c2);
        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;
        water.AddTriangleCellData(indices, weights1);

        if (direction <= HexDirection.SE && neighbor != null)
        {
            Vector3 bridge = HexMetrics.GetWaterBridge(direction);
            Vector3 e1     = c1 + bridge;
            Vector3 e2     = c2 + bridge;
            water.AddQuad(c1, c2, e1, e2);
            indices.y = neighbor.Index;
            water.AddQuadCellData(indices, weights1, weights2);

            if (direction <= HexDirection.E)
            {
                HexCell nextNeighbor = cell.GetNeighbor(direction.Next());
                if (nextNeighbor == null || !nextNeighbor.IsUnderWater)
                {
                    return;
                }
                water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next()));
                indices.z = nextNeighbor.Index;
                water.AddTriangleCellData(indices, weights1, weights2, weights3);
            }
        }
    }
コード例 #10
0
    public void TriangulateOpenWater(HexDirection dir, HexCell cell, HexCell neighbour, Vector3 center)
    {
        Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(dir);
        Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(dir);

        Water.AddTriangle(center, c1, c2);

        Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex);

        Water.AddTriangleCellData(indices, Weights1);

        if (dir <= HexDirection.SE && neighbour != null)
        {
            Vector3 bridge = HexMetrics.GetWaterBridge(dir);
            Vector3 e1     = c1 + bridge;
            Vector3 e2     = c2 + bridge;

            Water.AddQuad(c1, c2, e1, e2);
            indices.y = neighbour.CellIndex;
            Water.AddQuadCellData(indices, Weights1, Weights2);

            if (dir <= HexDirection.E)
            {
                HexCell nextNeightbour = cell.GetNeighbour(dir.Next());
                if (nextNeightbour == null || !nextNeightbour.IsUnderwater)
                {
                    return;
                }
                Water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(dir.Next()));
                indices.z = nextNeightbour.CellIndex;
                Water.AddTriangleCellData(indices, Weights1, Weights2, Weights3);
            }
        }
    }
コード例 #11
0
ファイル: HexGridChunk.cs プロジェクト: JackeyZ/HexMap
    /// <summary>
    /// 三角化角落阶梯,用于三角化三边分别是:平、阶、阶的角落
    /// </summary>
    /// <param name="begin"></param>
    /// <param name="beginCell">三角形阶梯所在六边形</param>
    /// <param name="left"></param>
    /// <param name="leftCell"></param>
    /// <param name="right"></param>
    /// <param name="rightCell"></param>
    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(weights1, weights2, 1);
        Color   c4 = HexMetrics.TerraceLerp(weights1, weights3, 1);

        Vector3 indices;

        indices.x = beginCell.Index;
        indices.y = leftCell.Index;
        indices.z = rightCell.Index;

        // 先生成第一个三角形
        terrain.AddTriangle(begin, v3, v4);                     // 顶点和三角索引
        terrain.AddTriangleCellData(indices, weights1, c3, c4); // 地形类型和splat颜色

        // 后面的阶梯生成四边形
        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(weights1, weights2, i);
            c4 = HexMetrics.TerraceLerp(weights1, weights3, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadCellData(indices, c1, c2, c3, c4);
        }
    }
コード例 #12
0
ファイル: HexGridChunk.cs プロジェクト: JackeyZ/HexMap
    /// <summary>
    /// 三角化河口
    /// </summary>
    /// <param name="e1">自身纯色区扇形边(弧)</param>
    /// <param name="e2">邻居纯色区扇形边(弧)</param>
    /// <param name="incomingRiver">是否是流入河</param>
    /// <param name="indices">临近六边形</param>
    void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices)
    {
        waterShore.AddTriangle(e2.v1, e1.v2, e1.v1);
        waterShore.AddTriangle(e2.v5, e1.v5, e1.v4);
        waterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        waterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        waterShore.AddTriangleCellData(indices, weights2, weights1, weights1);                      // 第一个顶点位于邻居六边形内所以用weights2,第二三个顶点位于自身六边形所以用weights1
        waterShore.AddTriangleCellData(indices, weights2, weights1, weights1);

        // 河口顶点 : e2:     v1----v5
        //            e1:      v2--v4
        //
        estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3);
        estuaries.AddTriangle(e1.v3, e2.v2, e2.v4);
        estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5);

        // 该UV的v用于判断离岸远近,u用于匹配瀑布水流消失插值(瀑布下方为1,扩散外围为0)
        estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f));
        estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(1f, 1f));
        estuaries.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f));

        // 六边形格子数据
        estuaries.AddQuadCellData(indices, weights2, weights1, weights2, weights1);
        estuaries.AddTriangleCellData(indices, weights1, weights2, weights2);
        estuaries.AddQuadCellData(indices, weights1, weights2);

        // 如果是流入河流的河口
        if (incomingRiver)
        {
            // uv2 用于匹配河水流动, v为河水流动方向
            // 由于是河口位于桥的下面,所以v坐标是0.8~1,
            // 由于水平面纯色区占比只有0.6,陆地水面交接处的桥是0.2+0.4,比陆地与陆地交接处的桥(0.2+0.2)大了50%,所以v坐标扩大50%,变成0.8~1.1
            estuaries.AddQuadUV2(new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f), new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f));
            estuaries.AddTriangleUV2(new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f));
            estuaries.AddQuadUV2(new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f), new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f));
        }
        // 如果是流出河流的河口(翻转uv)
        else
        {
            estuaries.AddQuadUV2(new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f), new Vector2(0f, 0f), new Vector2(0.5f, -0.3f));
            estuaries.AddTriangleUV2(new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f));
            estuaries.AddQuadUV2(new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f), new Vector2(1f, 0f), new Vector2(1.5f, -0.2f));
        }
    }
コード例 #13
0
ファイル: HexGridChunk.cs プロジェクト: JackeyZ/HexMap
    /// <summary>
    /// 三角化河流四边形
    /// </summary>
    /// <param name="v1">自身六边形内的顶点</param>
    /// <param name="v2">自身六边形内的顶点</param>
    /// <param name="v3">邻居六边形内的顶点</param>
    /// <param name="v4">邻居六边形内的顶点</param>
    /// <param name="y1">自身高度(河水平面)</param>
    /// <param name="y2">邻居高度(河水平面)</param>
    /// <param name="v">UV坐标的V</param>
    /// <param name="reversed"></param>
    void TriangulateRiverQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float v, bool reversed, Vector3 indices)
    {
        v1.y = v2.y = y1;
        v3.y = v4.y = y2;
        // 添加顶点
        rivers.AddQuad(v1, v2, v3, v4);

        // 添加UV坐标(把一个六边形内的河水(六边形内四个四边形,加上桥,总共五个四边形)
        // UV坐标的v分为五等分:0~0.2, 0.2~0.4, 0.4~0.6, 0.6~0.8, 0.8~1)
        if (reversed)
        {
            rivers.AddQuadUV(1f, 0f, 0.8f - v, 0.6f - v);   // 流入河流
        }
        else
        {
            rivers.AddQuadUV(0f, 1f, v, v + 0.2f);          // 流出河流
        }

        rivers.AddQuadCellData(indices, weights1, weights2);
    }
コード例 #14
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center      = cell.Position;
        Vector3 v1          = center + HexMetrics.GetFirstInnerCorner(direction);
        Vector3 v2          = center + HexMetrics.GetSecondInnerCorner(direction);
        Vector3 v1OuterBump = center + HexMetrics.GetFirstBumpOuterCorner(direction);
        Vector3 v2OuterBump = center + HexMetrics.GetSecondBumpOuterCorner(direction);

        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;

        terrain.AddTriangle(center, v1, v2);
        terrain.AddTriangleCellData(indices, weights1);

        terrain.AddQuad(v1, v2, v1OuterBump, v2OuterBump);
        if (cell.IsUnderwater)
        {
            terrain.AddQuadCellData(indices, weights1, weights1);
        }
        else
        {
            terrain.AddQuadCellData(indices, terrainColorBump, terrainColorBump);
        }

        if (direction <= HexDirection.SE)
        {
            TriangulateConnection(direction, cell, v1OuterBump, v2OuterBump);
        }

        if (cell.IsUnderwater)
        {
            TriangulateWater(direction, cell, center);
        }

        if (!cell.IsUnderwater)
        {
            features.AddFeature(cell, (center + v1 + v2) * (1f / 3f));
        }
    }
コード例 #15
0
    void AddWallSegment(
        Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight,
        bool addTower = false
        )
    {
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftThicknessOffset =
            HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOffset =
            HexMetrics.WallThicknessOffset(nearRight, farRight);

        float leftTop  = left.y + HexMetrics.wallHeight;
        float rightTop = right.y + HexMetrics.wallHeight;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);
        Vector3 t1 = v3, t2 = v4;

        v1   = v3 = left + leftThicknessOffset;
        v2   = v4 = right + rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1f), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);

        walls.AddQuadUnperturbed(t1, t2, v3, v4);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1f), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);

        if (addTower)
        {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;
            foreach (MeshRenderer renderer in towerInstance.GetComponentsInChildren <MeshRenderer>())
            {
                renderer.material.color = secondaryColor;
            }
            towerInstance.SetParent(container, false);
        }
    }
コード例 #16
0
    /// <summary>
    /// 三角化角部连接,当角部三角形的边是两个斜坡与一个平地时
    /// </summary>
    /// <param name="begin"></param>
    /// <param name="beginCell"></param>
    /// <param name="left"></param>
    /// <param name="leftCell"></param>
    /// <param name="right"></param>
    /// <param name="rightCell"></param>
    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   w3 = HexMetrics.TerraceLerp(weights1, weights2, 1);
        Color   w4 = HexMetrics.TerraceLerp(weights1, weights3, 1);

        Vector3 indices;

        indices.x = beginCell.Index;
        indices.y = leftCell.Index;
        indices.z = rightCell.Index;

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleCellData(indices, weights1, w3, w4);
        //terrain.AddTriangleColor(color1, c3, c4);
        //terrain.AddTriangulateTerrainType(types);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   w1 = w3;
            Color   w2 = w4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            w3 = HexMetrics.TerraceLerp(weights1, weights2, i);
            w4 = HexMetrics.TerraceLerp(weights1, weights3, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadCellData(indices, w1, w2, w3, w4);
            //terrain.AddQuadColor(c1, c2, c3, c4);
            //terrain.AddQuadTerrainType(types);
        }

        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadCellData(indices, w3, w4, weights2, weights3);
        //terrain.AddQuadColor(c3, c4, color2, color3);
        //terrain.AddQuadTerrainType(types);
    }
コード例 #17
0
    public void TriangulateWaterShore(HexDirection dir, HexCell hexCell, HexCell neighbour, Vector3 center)
    {
        EdgeVertices edges1 = new EdgeVertices(center + HexMetrics.GetFirstWaterCorner(dir), center + HexMetrics.GetSecondWaterCorner(dir));

        Water.AddTriangle(center, edges1.v1, edges1.v2);
        Water.AddTriangle(center, edges1.v2, edges1.v3);
        Water.AddTriangle(center, edges1.v3, edges1.v4);
        Water.AddTriangle(center, edges1.v4, edges1.v5);

        Vector3 indices = new Vector3(hexCell.CellIndex, hexCell.CellIndex, hexCell.CellIndex);

        Water.AddTriangleCellData(indices, Weights1);
        Water.AddTriangleCellData(indices, Weights1);
        Water.AddTriangleCellData(indices, Weights1);
        Water.AddTriangleCellData(indices, Weights1);

        Vector3 center2 = neighbour.Position;

        center2.y = center.y;
        if (neighbour.ColumnIndex < hexCell.ColumnIndex - 1)
        {
            center2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
        }
        else if (neighbour.ColumnIndex > hexCell.ColumnIndex + 1)
        {
            center2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
        }


        Vector3      bridge = HexMetrics.GetWaterBridge(dir);
        EdgeVertices edges2 = new EdgeVertices(center2 + HexMetrics.GetSecondSolidCorner(dir.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(dir.Opposite()));

        if (hexCell.HasRiverThroughEdge(dir))
        {
            TriangulateEstuary(edges1, edges2, hexCell.IncomingRiverDirection == dir, indices);
        }
        else
        {
            WaterShore.AddQuad(edges1.v1, edges1.v2, edges2.v1, edges2.v2);
            WaterShore.AddQuad(edges1.v2, edges1.v3, edges2.v2, edges2.v3);
            WaterShore.AddQuad(edges1.v3, edges1.v4, edges2.v3, edges2.v4);
            WaterShore.AddQuad(edges1.v4, edges1.v5, edges2.v4, edges2.v5);

            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);

            WaterShore.AddQuadCellData(indices, Weights1, Weights2);
            WaterShore.AddQuadCellData(indices, Weights1, Weights2);
            WaterShore.AddQuadCellData(indices, Weights1, Weights2);
            WaterShore.AddQuadCellData(indices, Weights1, Weights2);



            HexCell nextNeighbour = hexCell.GetNeighbour(dir.Next());
            if (nextNeighbour != null)
            {
                Vector3 center3 = nextNeighbour.Position;
                if (nextNeighbour.ColumnIndex < hexCell.ColumnIndex - 1)
                {
                    center3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
                }
                else if (nextNeighbour.ColumnIndex > hexCell.ColumnIndex + 1)
                {
                    center3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
                }

                Vector3 v3 = center3 + (nextNeighbour.IsUnderwater ? HexMetrics.GetFirstWaterCorner(dir.Previous()) : HexMetrics.GetFirstSolidCorner(dir.Previous()));
                v3.y = center.y;


                WaterShore.AddTriangle(edges1.v5, edges2.v5, v3);
                WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f));
                WaterShore.AddTriangleCellData(indices, Weights1, Weights2, Weights3);
            }
        }
    }
コード例 #18
0
    void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices)
    {
        waterShore.AddTriangle(e2.v1, e1.v2, e1.v1);
        waterShore.AddTriangle(e2.v5, e1.v5, e1.v4);
        waterShore.AddTriangleUV(
            new Vector2(0f, 1f),
            new Vector2(0f, 0f),
            new Vector2(0f, 0f)
            );
        waterShore.AddTriangleUV(
            new Vector2(0f, 1f),
            new Vector2(0f, 0f),
            new Vector2(0f, 0f)
            );
        waterShore.AddTriangleCellData(indices, weights2, weights1, weights1);
        waterShore.AddTriangleCellData(indices, weights2, weights1, weights1);

        estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3);
        estuaries.AddTriangle(e1.v3, e2.v2, e2.v4);
        estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5);
        estuaries.AddQuadUV(
            new Vector2(0f, 1f),
            new Vector2(0f, 0f),
            new Vector2(1f, 1f),
            new Vector2(0f, 0f)
            );
        estuaries.AddTriangleUV(
            new Vector2(0f, 0f),
            new Vector2(1f, 1f),
            new Vector2(1f, 1f)
            );
        estuaries.AddQuadUV(
            new Vector2(0f, 0f),
            new Vector2(0f, 0f),
            new Vector2(1f, 1f),
            new Vector2(0f, 1f)
            );
        estuaries.AddQuadCellData(indices, weights2, weights1, weights2, weights1);
        estuaries.AddTriangleCellData(indices, weights2, weights1, weights2);
        estuaries.AddQuadCellData(indices, weights1, weights2);

        if (incomingRiver)
        {
            estuaries.AddQuadUV2(
                new Vector2(1.5f, 1f),
                new Vector2(0.7f, 1.15f),
                new Vector2(1f, 0.8f),
                new Vector2(0.5f, 1.1f)
                );
            estuaries.AddTriangleUV2(
                new Vector2(0.5f, 1.1f),
                new Vector2(1f, 0.8f),
                new Vector2(0f, 0.8f)
                );
            estuaries.AddQuadUV2(
                new Vector2(0.5f, 1.1f),
                new Vector2(0.3f, 1.15f),
                new Vector2(0f, 0.8f),
                new Vector2(-0.5f, 1f)
                );
        }
        else
        {
            estuaries.AddQuadUV2(
                new Vector2(-0.5f, -0.3f),
                new Vector2(0.3f, -0.35f),
                new Vector2(0f, 0f),
                new Vector2(0.5f, -0.3f)
                );
            estuaries.AddTriangleUV2(
                new Vector2(0.5f, -0.3f),
                new Vector2(0f, 0f),
                new Vector2(1f, 0f)
                );
            estuaries.AddQuadUV2(
                new Vector2(0.5f, -0.3f),
                new Vector2(0.7f, -0.35f),
                new Vector2(1f, 0f),
                new Vector2(1.5f, -0.2f)
                );
        }
    }
コード例 #19
0
    void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
    {
        EdgeVertices e1 = new EdgeVertices(
            center + HexMetrics.GetFirstWaterCorner(direction),
            center + HexMetrics.GetSecondWaterCorner(direction));

        water.AddTriangle(center, e1.v1, e1.v2);
        water.AddTriangle(center, e1.v2, e1.v3);
        water.AddTriangle(center, e1.v3, e1.v4);
        water.AddTriangle(center, e1.v4, e1.v5);
        Vector3 indices;

        indices.x = indices.z = cell.Index;
        indices.y = neighbor.Index;
        for (int i = 0; i < 4; i++)
        {
            water.AddTriangleCellData(indices, weights1);
        }

        Vector3 center2 = neighbor.Position;

        center2.y = center.y;
        EdgeVertices e2 = new EdgeVertices(
            center2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()),
            center2 + HexMetrics.GetFirstSolidCorner(direction.Opposite()));

        if (cell.HasRiverThroughEdge(direction))
        {
            TriangulateEstuary(e1, e2, cell.IncomingRiver == direction, indices);
        }
        else
        {
            waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
            waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
            waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
            waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            for (int i = 0; i < 4; i++)
            {
                waterShore.AddQuadCellData(indices, weights1, weights2);
            }
        }

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

        if (nextNeighbor != null)
        {
            Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderWater ?
                                                  HexMetrics.GetFirstWaterCorner(direction.Previous()) :
                                                  HexMetrics.GetFirstSolidCorner(direction.Previous()));
            v3.y = center.y;
            waterShore.AddTriangle(e1.v5, e2.v5, v3);
            waterShore.AddTriangleUV(
                new Vector2(0f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, nextNeighbor.IsUnderWater ? 0f : 1f)
                );
            indices.z = nextNeighbor.Index;
            waterShore.AddTriangleCellData(indices, weights1, weights2, weights3);
        }
    }
コード例 #20
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.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, weights1, cell.Index,
            e, weights1, cell.Index
            );

        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);

        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;
        terrain.AddTriangleCellData(indices, weights1);
        terrain.AddQuadCellData(indices, weights1);
        terrain.AddQuadCellData(indices, weights1);
        terrain.AddTriangleCellData(indices, weights1);

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(
                centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed, indices
                );
            TriangulateRiverQuad(
                m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices
                );
        }
    }
コード例 #21
0
    /// <summary>
    /// Creates the triangles for a side of the hexagon, with river passing through (incoming and outgoing river) at this side.
    /// </summary>
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

        if (cell.HasRiverThroughEdge(direction.Opposite()))           // If river flows forward through the cell
        // Extend center into line
        {
            centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
            centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        }
        else if (cell.HasRiverThroughEdge(direction.Next()))           // If river bends sharply in next dir
        {
            centerL = center;
            centerR = Vector3.Lerp(center, e.v5, 2f / 3f);
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()))           // If river bends sharply in prev dir
        {
            centerL = Vector3.Lerp(center, e.v1, 2f / 3f);
            centerR = center;
        }
        else if (cell.HasRiverThroughEdge(direction.Next2()))           //  River bends smoothly to next.next dir
        {
            centerL = center;
            centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.InnerToOuter);
        }
        else           //  River bends smoothly to previous.previous dir
        {
            centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.InnerToOuter);
            centerR = center;
        }

        center = Vector3.Lerp(centerL, centerR, 0.5f);         // Average center to serve all cases

        // Edge 1/2 the way from edge and cell center
        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;         // Lower middle edge and center to river bed

        TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index);

        // Final gap between the middle edge and the center
        // Geo
        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);

        // Splat + Terrain Types
        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;
        Terrain.AddTriangleCellData(indices, weights1);
        Terrain.AddQuadCellData(indices, weights1);
        Terrain.AddQuadCellData(indices, weights1);
        Terrain.AddTriangleCellData(indices, weights1);

        if (!cell.IsUnderwater)             // No river water surface when underwater, river bed allowed
        // River water surface
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed, indices);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices);
        }
    }
コード例 #22
0
ファイル: HexGridChunk.cs プロジェクト: JackeyZ/HexMap
    /// <summary>
    /// 三角化沿岸水面扇形
    /// </summary>
    /// <param name="direction">当前处理的扇形方向</param>
    /// <param name="cell">自身六边形</param>
    /// <param name="neighbor">邻居六边形</param>
    /// <param name="center">自身六边形中点</param>
    void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
    {
        center.y = cell.WaterSurfaceY;
        Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction);
        Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction);

        EdgeVertices e1 = new EdgeVertices(c1, c2);

        // 三角化沿岸扇形
        water.AddTriangle(center, e1.v1, e1.v2);
        water.AddTriangle(center, e1.v2, e1.v3);
        water.AddTriangle(center, e1.v3, e1.v4);
        water.AddTriangle(center, e1.v4, e1.v5);

        Vector3 indices;

        indices.x = indices.z = cell.Index;
        indices.y = neighbor.Index;
        water.AddTriangleCellData(indices, weights1);
        water.AddTriangleCellData(indices, weights1);
        water.AddTriangleCellData(indices, weights1);
        water.AddTriangleCellData(indices, weights1);

        // 三角化沿岸水平面桥
        Vector3 neighbor_center = neighbor.Position;

        neighbor_center.y = center.y;                   // 保持y与自身等高
        // 得到邻居纯色区的弧(边)
        EdgeVertices e2 = new EdgeVertices(neighbor_center + HexMetrics.GetSecondSolidCorner(direction.Opposite()),
                                           neighbor_center + HexMetrics.GetFirstSolidCorner(direction.Opposite()));

        if (cell.HasRiverThroughEdge(direction))
        {
            TriangulateEstuary(e1, e2, cell.HasIncomingRiver && cell.IncomingRiver == direction, indices);
        }
        else
        {
            waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
            waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
            waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
            waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
            waterShore.AddQuadUV(0, 0, 0, 1);                           // 陆地一侧v坐标为1
            waterShore.AddQuadUV(0, 0, 0, 1);
            waterShore.AddQuadUV(0, 0, 0, 1);
            waterShore.AddQuadUV(0, 0, 0, 1);

            waterShore.AddQuadCellData(indices, weights1, weights2);
            waterShore.AddQuadCellData(indices, weights1, weights2);
            waterShore.AddQuadCellData(indices, weights1, weights2);
            waterShore.AddQuadCellData(indices, weights1, weights2);
        }

        // 三角化角落
        HexCell nextNeighbor = cell.GetNeighbor(direction.Next());  // 岸边一定是一个桥一个角落的,所以不会重复创建角落

        if (nextNeighbor != null)
        {
            Vector3 v3 = nextNeighbor.Position +
                         (nextNeighbor.IsUnderwater ? HexMetrics.GetFirstWaterCorner(direction.Previous()) : HexMetrics.GetFirstSolidCorner(direction.Previous())); // 判断是水面还是陆地,二者纯色区域占比不一样
            v3.y = center.y;                                                                                                                                        // 保持y与自身等高

            waterShore.AddTriangle(e1.v5, e2.v5, v3);
            waterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)); // 第三个顶点需要判断是在水面还是陆地,水面v为0,陆地用v为1

            indices.z = nextNeighbor.Index;
            waterShore.AddTriangleCellData(indices, weights1, weights2, weights3);
        }
    }