예제 #1
0
    void TriangulateWithRiverBeginOrEnd(HexDirection dir, HexCell hexCell, Vector3 center, EdgeVertices e)
    {
        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f),
            Vector3.Lerp(center, e.v5, 0.5f), 1f / 6f
            );

        m.v3.y = e.v3.y;

        TriangulateEdgeStrip(m, /*hexCell.Color*/ weights1, hexCell.Index, e, /*hexCell.Color*/ weights1, hexCell.Index);
        TriangulateEdgeFan(center, m, hexCell.Index);

        if (!hexCell.IsUnderwater)
        {
            bool reversed = hexCell.HasIncomingRiver;

            Vector3 indices;
            indices.x = indices.y = indices.z = hexCell.Index;

            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, hexCell.RiverSurfaceY, 0.6f, reversed, indices);

            center.y = m.v2.y = m.v4.y = hexCell.RiverSurfaceY;
            rivers.AddTriangle(center, m.v2, m.v4);
            if (reversed)
            {
                rivers.AddTriangleUV(
                    new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f)
                    );
            }
            else
            {
                rivers.AddTriangleUV(
                    new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f)
                    );
            }

            rivers.AddTriangleCellData(indices, weights1);
        }
    }
예제 #2
0
 void TriangulateRoad(
     Vector3 center, Vector3 mL, Vector3 mR,
     EdgeVertices e, bool hasRoadThroughCellEdge, float index)
 {
     if (hasRoadThroughCellEdge)
     {
         Vector3 indices;
         indices.x = indices.y = indices.z = index;
         Vector3 mC = Vector3.Lerp(mL, mR, 0.5f);
         TriangulateRoadSegment(mL, mC, mR, e.v2, e.v3, e.v4, weights1, weights1, indices);
         roads.AddTriangle(center, mL, mC);
         roads.AddTriangle(center, mC, mR);
         roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(1f, 0f));
         roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 0f));
         roads.AddTriangleCellData(indices, weights1);
         roads.AddTriangleCellData(indices, weights1);
     }
     else
     {
         TriangulateRoadEdge(center, mL, mR, index);
     }
 }
예제 #3
0
    void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell,
                                 EdgeVertices end, HexCell endCell,
                                 bool hasRoad)
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        w2 = HexMetrics.TerraceLerp(weights1, weights2, 1);
        float        i1 = beginCell.Index;
        float        i2 = endCell.Index;

        TriangulateEdgeStrip(begin, weights1, i1, e2, w2, i2, hasRoad);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        w1 = w2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            w2 = HexMetrics.TerraceLerp(weights1, weights2, i);
            TriangulateEdgeStrip(e1, w1, i1, e2, w2, i2, hasRoad);
        }

        TriangulateEdgeStrip(e2, w2, i1, end, weights2, i2, hasRoad);
    }
예제 #4
0
 //
 void TriangulateRoad(
     Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e,
     bool hasRoadThroughCellEdge)
 {
     if (hasRoadThroughCellEdge)
     {
         //靠近边界的矩形
         Vector3 mC = Vector3.Lerp(mL, mR, 0.5f);
         TriangulateRoadSegment(mL, mC, mR, e.v2, e.v3, e.v4);
         //靠近中心的三角形
         roads.AddTriangle(center, mL, mC);
         roads.AddTriangle(center, mC, mR);
         roads.AddTriangleUV(
             new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(1f, 0f));
         roads.AddTriangleUV(
             new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 0f));
     }
     else
     {
         TriangulateRoadEdge(center, mL, mR);
     }
 }
예제 #5
0
    void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f));

        m.v3.y = e.v3.y;
        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);
        TriangulateEdgeFan(center, m, cell.Color);
        bool reversed = cell.HasIncomingRiver;

        TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed);
        center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY;
        rivers.AddTriangle(center, m.v2, m.v4);

        if (reversed)
        {
            rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f));
        }
        else
        {
            rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f));
        }
    }
예제 #6
0
        public void edgeVerticiesTerraceLerpTest()
        {
            int          step = 1;
            EdgeVertices a    = new EdgeVertices(corner1, corner2);
            EdgeVertices b    = new EdgeVertices(corner1, corner2);

            expected.Add(HexMetrics.TerraceLerp(a.v1, b.v1, step));
            expected.Add(HexMetrics.TerraceLerp(a.v2, b.v2, step));
            expected.Add(HexMetrics.TerraceLerp(a.v3, b.v3, step));
            expected.Add(HexMetrics.TerraceLerp(a.v4, b.v4, step));
            expected.Add(HexMetrics.TerraceLerp(a.v5, b.v5, step));

            EdgeVertices vert = EdgeVertices.TerraceLerp(a, b, step);

            actual.Add(v1);
            actual.Add(v2);
            actual.Add(v3);
            actual.Add(v4);
            actual.Add(v5);

            CollectionAssert.AreEqual(expected, actual);
        }
    /// <summary>
    /// cell中有河流,但是不是自己的扇形
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="cell"></param>
    /// <param name="center"></param>
    /// <param name="e"></param>
    private void TriangulateAdjacentToRiver(HexDirection direction
                                            , HexCell cell, Vector3 center, EdgeVertices e)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction)
                          * 0.5f * HexMetrics.innerToOuter;
            }
            else if (cell.HasRiverThroughEdge(direction.Previous2()))
            {
                center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()) &&
                 cell.HasRiverThroughEdge(direction.Next2()))
        {
            center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f;
        }

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f)
            , Vector3.Lerp(center, e.v5, 0.5f));

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

        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
예제 #8
0
    void TriangulateEdgeTerraces(
        EdgeVertices begin, HexCell beginCell,
        EdgeVertices end, HexCell endCell)
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetrics.TerraceLerp(color1, color2, 1);
        float        t1 = beginCell.TerrainTypeIndex;
        float        t2 = endCell.TerrainTypeIndex;

        TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(color1, color2, i);
            TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2);
        }

        TriangulateEdgeStrip(e2, c2, t1, end, color2, t2);
    }
예제 #9
0
    void TriangulateEdgeTerraces(
        EdgeVertices begin, HexCell beginCell,
        EdgeVertices end, HexCell endCell,
        bool hasRoad
        )
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, 1);

        TriangulateEdgeStrip(begin, beginCell.Color, e2, c2, hasRoad);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, i);
            TriangulateEdgeStrip(e1, c1, e2, c2, hasRoad);
        }

        TriangulateEdgeStrip(e2, c2, end, endCell.Color, hasRoad);
    }
예제 #10
0
    //-----------------------WALLS------------------------------

    public void AddWall(EdgeVertices near, HexCell nearCell,
                        EdgeVertices far, HexCell farCell, bool hasRiver,
                        bool hasRoad)
    {
        if (nearCell.Walled != farCell.Walled &&
            !nearCell.IsUnderWater && !farCell.IsUnderWater &&
            nearCell.GetEdgeType(farCell) != HexEdgeType.Cliff)
        {
            AddWallSegment(near.v1, far.v1, near.v2, far.v2);
            if (hasRiver || hasRoad)
            {
                AddWallCap(near.v2, far.v2);
                AddWallCap(far.v4, near.v4);
            }
            else
            {
                AddWallSegment(near.v2, far.v2, near.v3, far.v3);
                AddWallSegment(near.v3, far.v3, near.v4, far.v4);
            }
            AddWallSegment(near.v4, far.v4, near.v5, far.v5);
        }
    }
예제 #11
0
    void TriangulateAdjacentToRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e
        )
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction) *
                          (HexMetrics.innerToOuter * 0.5f);
            }
            else if (
                cell.HasRiverThroughEdge(direction.Previous2())
                )
            {
                center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (
            cell.HasRiverThroughEdge(direction.Previous()) &&
            cell.HasRiverThroughEdge(direction.Next2())
            )
        {
            center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f;
        }

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f),
            Vector3.Lerp(center, e.v5, 0.5f)
            );

        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);
        TriangulateEdgeFan(center, m, cell.Color);
    }
    private void TriangulateRoadWithoutRiver(
        Hex source,
        HexDirections direction,
        EdgeVertices edgeVertices,
        Dictionary <HexDirections, bool> roadEdges,
        Vector3 center,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        Vector2 interpolators = GetRoadInterpolators(
            source,
            direction,
            roadEdges
            );

        TriangulateRoad(
            center,
            Vector3.Lerp(
                center,
                edgeVertices.vertex1,
                interpolators.x
                ),
            Vector3.Lerp(
                center,
                edgeVertices.vertex5,
                interpolators.y
                ),
            edgeVertices,
//                hex.HasRoadThroughEdge(direction),
            roadEdges[direction],
            source.Index,
            hexOuterRadius,
            wrapSize,
            roads
            );
    }
예제 #13
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);

        //terrain.AddQuadColor(c1, c2);
        //terrain.AddQuadColor(c1, c2);
        //terrain.AddQuadColor(c1, c2);
        //      terrain.AddQuadColor(c1, c2);

        //      Vector3 types;
        //      types.x = types.z = type1;
        //      types.y = type2;
        //      terrain.AddQuadTerrainTypes(types);
        //      terrain.AddQuadTerrainTypes(types);
        //      terrain.AddQuadTerrainTypes(types);
        //      terrain.AddQuadTerrainTypes(types);

        if (hasRoad)
        {
            TriangulateRoadSegment(e1.v2, e1.v3, e1.v4, e2.v2, e2.v3, e2.v4, w1, w2, indices);
        }
    }
예제 #14
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        //Create triangle
        Vector3      center = cell.Position;
        EdgeVertices e      = new EdgeVertices(
            center + HexMetrics.GetFirstSolidCorner(direction),
            center + HexMetrics.GetSecondSolidCorner(direction)
            );

        if (cell.HasRiver)
        {
            if (cell.HasRiverThroughEdge(direction))
            {
                e.v3.y = cell.StreamBedY;
                if (cell.HasRiverBeginOrEnd)
                {
                    TriangulateWithRiverBeginOrEnd(direction, cell, center, e);
                }
                else
                {
                    TriangulateWithRiver(direction, cell, center, e);
                }
            }
            else
            {
                TriangulateAdjacentToRiver(direction, cell, center, e);
            }
        }
        else
        {
            TriangulateEdgeFan(center, e, cell.Color);
        }

        if (direction <= HexDirection.SE)
        {
            TriangulateConnection(direction, cell, e);
        }
    }
    /// <summary>
    /// If eligible creates a wall segment between 2 cells.
    /// </summary>
    public void AddWall(EdgeVertices near, HexCell nearCell, EdgeVertices far, HexCell farCell, bool hasRiver, bool hasRoad)
    {
        bool walledUnwalled = nearCell.Walled != farCell.Walled;                  // Walls only between walled and unwalled cells
        bool noUnderwater   = !nearCell.IsUnderwater && !farCell.IsUnderwater;    // No walls underwater
        bool noSlope        = nearCell.GetEdgeType(farCell) != HexEdgeType.Cliff; // No walls on slopes

        if (walledUnwalled && noUnderwater && noSlope)
        {
            AddWallSegment(near.v1, far.v1, near.v2, far.v2);
            if (hasRiver || hasRoad)
            {
                // Leave a gap.
                AddWallCap(near.v2, far.v2);
                AddWallCap(far.v4, near.v4);
            }
            else
            {
                AddWallSegment(near.v2, far.v2, near.v3, far.v3);
                AddWallSegment(near.v3, far.v3, near.v4, far.v4);
            }
            AddWallSegment(near.v4, far.v4, near.v5, far.v5);
        }
    }
예제 #16
0
    private void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell,
                                         bool hasRoad)
    {
        var e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        var w2 = HexMetrics.TerraceLerp(weights1, weights2, 1);
        var i1 = beginCell.Index;
        var i2 = endCell.Index;

        TriangulateEdgeStrip(begin, weights1, i1, e2, w2, i2, hasRoad);

        for (var i = 2; i < HexMetrics.terraceSteps; i++)
        {
            var e1 = e2;
            var c1 = w2;

            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            w2 = HexMetrics.TerraceLerp(weights1, weights2, i);

            TriangulateEdgeStrip(e1, c1, i1, e2, w2, i2, hasRoad);
        }

        TriangulateEdgeStrip(e2, w2, i1, end, weights2, i2, hasRoad);
    }
예제 #17
0
    private void TriangulateEdgeStrip(
        EdgeVertices e1, Color w1, float type1,
        EdgeVertices e2, Color w2, float type2,
        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);

        var indices = new Vector3(type1, type2, type1);

        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);
        }
    }
예제 #18
0
    void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, float type)
    {
        terrain.AddTriangle(center, edge.v1, edge.v2);
//		terrain.AddTriangleColor(color);
        terrain.AddTriangle(center, edge.v2, edge.v3);
//		terrain.AddTriangleColor(color);
        terrain.AddTriangle(center, edge.v3, edge.v4);
//		terrain.AddTriangleColor(color);
        terrain.AddTriangle(center, edge.v4, edge.v5);
//		terrain.AddTriangleColor(color);

        terrain.AddTriangleColor(color1);
        terrain.AddTriangleColor(color1);
        terrain.AddTriangleColor(color1);
        terrain.AddTriangleColor(color1);
        Vector3 types;

        types.x = types.y = types.z = type;
        terrain.AddTriangleTerrainTypes(types);
        terrain.AddTriangleTerrainTypes(types);
        terrain.AddTriangleTerrainTypes(types);
        terrain.AddTriangleTerrainTypes(types);
    }
    void TriangulateEdgeStrip(
        EdgeVertices e1, Color c1, float type1,
        EdgeVertices e2, Color c2, float type2
        )
    {
        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);

        Vector3 types;

        types.x = types.z = type1;
        types.y = type2;
        terrain.AddQuadTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
        terrain.AddQuadTerrainTypes(types);
    }
예제 #20
0
    private void TriangulateConnection(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e1)
    {
        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            return;
        }

        Vector3      bridge = HexMetrics.GetBridge(direction);
        EdgeVertices e2     = new EdgeVertices(e1.v1 + bridge, e1.v4 + bridge);

        TriangulateEdgeStrip(e1, e2, cell.color, neighbor.color);

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

        if (direction <= HexDirection.E && nextNeighbor != null)
        {
            AddTriangle(e1.v4, e2.v4, e1.v4 + HexMetrics.GetBridge(nextDirection));
            AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color);
        }
    }
예제 #21
0
    /// <summary>
    /// 构建阶梯状连接区域
    /// 这里不再使用单一的顶点,而是直接使用cell与阶梯区域相连接的边,通过计算得出边上的顶点位置以及每个顶点的颜色
    /// </summary>
    /// <param name="begin">第一个cell与相邻阶梯化区域的边上顶点</param>
    /// <param name="beginCell">第一个cell的实例</param>
    /// <param name="end">第二个cell与相邻阶梯化区域的边上顶点</param>
    /// <param name="endCell">第二个cell的实例</param>
    private void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell)
    {
        //通过插值计算出相邻cell边的每个坐标点
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        //通过插值计算出相邻cell边每个坐标点的颜色
        Color c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, 1);

        //构建阶梯的第一段
        TriangulateEdgeStrip(begin, beginCell.Color, e2, c2);

        //循环生成中间部分
        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, i);
            TriangulateEdgeStrip(e1, c1, e2, c2);
        }

        //构建阶梯的最后一段
        TriangulateEdgeStrip(e2, c2, end, endCell.Color);
    }
예제 #22
0
    void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell, bool hasRoad)
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetric.TerraceLerp(color1, color2, 1);
        float        t1 = beginCell.TerrainTypeIndex;
        float        t2 = endCell.TerrainTypeIndex;

        //first task
        TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2, hasRoad);

        //process of creating actual steps
        for (int i = 2; i < HexMetric.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetric.TerraceLerp(color1, color2, i);
            TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2, hasRoad);
        }

        //last task
        TriangulateEdgeStrip(e2, c2, t1, end, color2, t2, hasRoad);
    }
예제 #23
0
    /// <summary>
    /// 三角化是河流开端或者结尾(只有流出或者只有流入)的六边形内部的有河流的扇形
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="cell"></param>
    /// <param name="center"></param>
    /// <param name="e"></param>
    void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        // 计算出六边形中心点与外部边缘的中线
        //   外部边缘:   ————
        //   中线:        -——-
        //   六边形中心点:   .
        EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f));

        // 调整中线的中心顶点的高度为河床高度
        m.v3.y = e.v3.y;

        // 三角化中线到外部边缘之间的长方形
        TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index);

        // 三角化六边形中心店到中线的扇形
        TriangulateEdgeFan(center, m, cell.Index);

        // 三角化河水
        if (!cell.IsUnderwater)                       // 检查是否在陆地
        {
            bool    reversed = cell.HasIncomingRiver; // 流入河水需要翻转UV
            Vector3 indices;
            indices.x = indices.y = indices.z = cell.Index;
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices);
            center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY;
            rivers.AddTriangle(center, m.v2, m.v4);
            if (reversed)
            {
                rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f));
            }
            else
            {
                rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f));
            }
            rivers.AddTriangleCellData(indices, weights1);
        }
    }
    /// <summary>
    /// Creates the triangles for a side of the hexagon, with river starting or ending this side.
    /// </summary>
    void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        // Edge 1/2 the way from edge and cell center
        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f),
            Vector3.Lerp(center, e.v5, 0.5f)
            );

        m.v3.y = e.v3.y;         // middle at river bed height, but not the center of the cell

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

        if (!cell.IsUnderwater)             // No river water surface underwater, riverbed itself is allowed
        // River water surface
        {
            bool reversed = cell.HasIncomingRiver;

            Vector3 indices;
            indices.x = indices.y = indices.z = cell.Index;
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices);

            // Add first/last water surface triangle for river begin/end
            center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY;
            Rivers.AddTriangle(center, m.v2, m.v4);
            if (reversed)
            {
                Rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f));
            }
            else
            {
                Rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f));
            }

            Rivers.AddTriangleCellData(indices, weights1);
        }
    }
예제 #25
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, weights1, weights2, weights2);
        estuaries.AddQuadCellData(indices, weights1, weights2);

        if (incomingRiver)
        {
            estuaries.AddQuadUV2(new Vector2(1.5f, 1.0f), 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));
        }
    }
    /// <summary>
    /// Creates the triangles for the bridge between two cells.
    /// </summary>
    void TriangulateEdgeStrip(EdgeVertices e1, Color w1, float index1, EdgeVertices e2, Color w2, float index2, bool hasRoad = false)
    {
        // Geometry
        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);

        // Add splat map and terrain types to cell data
        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 road present then build it in the middle of the cell bridge.
        if (hasRoad)
        {
            TriangulateRoadSegment(e1.v2, e1.v3, e1.v4, e2.v2, e2.v3, e2.v4, w1, w2, indices);
        }
    }
    /// <summary>
    /// Creates road geometry for cell center.
    /// </summary>
    void TriangulateRoad(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasRoadThroughCellEdge, float index)
    {
        if (hasRoadThroughCellEdge)           // Road in this direction ?
        {
            Vector3 indices;
            indices.x = indices.y = indices.z = index;
            Vector3 mC = Vector3.Lerp(mL, mR, 0.5f);
            TriangulateRoadSegment(mL, mC, mR, e.v2, e.v3, e.v4, weights1, weights1, indices);

            // Center connection triangles
            Roads.AddTriangle(center, mL, mC);
            Roads.AddTriangle(center, mC, mR);
            Roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(1f, 0f));
            Roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 0f));

            Roads.AddTriangleCellData(indices, weights1);
            Roads.AddTriangleCellData(indices, weights1);
        }
        else
        {
            // Then road exists in cell but not at this edge so draw auxiliary road geometry
            TriangulateRoadEdge(center, mL, mR, index);
        }
    }
예제 #28
0
    // Walls:

    //&&
    //    !nearCell.IsUnderwater && !farCell.IsUnderwater &&
    //    nearCell.GetEdgeType(farCell) != HexEdgeType.Cliff

    public void AddWall(
        EdgeVertices near, HexCell nearCell,
        EdgeVertices far, HexCell farCell,
        bool hasRiver, bool hasRoad
        )
    {
        if (
            nearCell.Walled != farCell.Walled
            )
        {
            AddWallSegment(near.v1, far.v1, near.v2, far.v2);
            if (hasRiver || hasRoad)
            {
                AddWallCap(near.v2, far.v2);
                AddWallCap(far.v4, near.v4);
            }
            else
            {
                AddWallSegment(near.v2, far.v2, near.v3, far.v3);
                AddWallSegment(near.v3, far.v3, near.v4, far.v4);
            }
            AddWallSegment(near.v4, far.v4, near.v5, far.v5);
        }
    }
예제 #29
0
        //三角化河流
        void TriangulateWithRiver(int direction, int prevD, int nextD, Color cellColor, Vector3 center, EdgeVertices e, ref DynamicBuffer <ColorBuffer> colorBuffer, ref DynamicBuffer <VertexBuffer> vertexBuffer, bool oppositeHasRiverThroughEdge)
        {
            Vector3 centerL, centerR;

            if (oppositeHasRiverThroughEdge)
            {
                centerL = center + HexMetrics.GetFirstSolidCorner(prevD) * 0.25f;
                centerR = center + HexMetrics.GetSecondSolidCorner(nextD) * 0.25f;
            }
            else
            {
                centerL = centerR = 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;
            TriangulateEdgeStrip(m, cellColor, e, cellColor, ref colorBuffer, ref vertexBuffer);
            AddTriangle(centerL, cellColor, m.v1, cellColor, m.v2, cellColor, ref colorBuffer, ref vertexBuffer);
            AddQuad(centerL, cellColor, center, cellColor, m.v2, cellColor, m.v3, cellColor, ref colorBuffer, ref vertexBuffer);
            AddQuad(center, cellColor, centerR, cellColor, m.v3, cellColor, m.v4, cellColor, ref colorBuffer, ref vertexBuffer);
            AddTriangle(centerR, cellColor, m.v4, cellColor, m.v5, cellColor, ref colorBuffer, ref vertexBuffer);
        }
예제 #30
0
    void TriangulateAdjacentToRiver(Direction direction, Cell cell, Vector3 center, EdgeVertices edges)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadsNearRiver(direction, cell, center, edges);
        }

        if (cell.HasRiverAtDirection(direction.Next()))
        {
            if (cell.HasRiverAtDirection(direction.Previous()))
            {
                center += Metrics.GetMiddleSolidCorner(direction) * Metrics.InnerToOuter * 0.5f;
            }
            else if (cell.HasRiverAtDirection(direction.PrePrevious()))
            {
                center += Metrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (cell.HasRiverAtDirection(direction.Previous()) && cell.HasRiverAtDirection(direction.AfterNext()))
        {
            center += Metrics.GetSecondSolidCorner(direction) * 0.25f;
        }

        var middleChannelVertices = new EdgeVertices(
            Vector3.Lerp(center, edges.vertex1, 0.5f),
            Vector3.Lerp(center, edges.vertex5, 0.5f));

        middleChannelVertices.vertex3.y = edges.vertex3.y;
        TriangulateEdgeStrip(middleChannelVertices, edges, cell.Color, cell.Color);
        TriangulateEdgeFan(center, middleChannelVertices, cell.Color);

        if (!cell.IsUnderWater && !cell.HasRoadAtDirection(direction))
        {
            objectManager.AddObjects((center + edges.vertex1 + edges.vertex5) / 3, cell);
        }
    }