Beispiel #1
0
    public void Triangulate(HexMesh mesh)
    {
        for (HexDirection direction = HexDirection.NE; direction <= HexDirection.NW; direction++)
        {
            Vector3      center = Position;
            EdgeVertices edge   = new EdgeVertices(
                Position + HexMetrics.GetFirstSolidCorner(direction),
                Position + HexMetrics.GetSecondSolidCorner(direction)
                );

            mesh.AddTriangle(Position, edge.v1, edge.v2);
            mesh.AddTriangleColor(Color, Color, Color);
            mesh.AddTriangle(Position, edge.v2, edge.v3);
            mesh.AddTriangleColor(Color, Color, Color);
            mesh.AddTriangle(Position, edge.v3, edge.v4);
            mesh.AddTriangleColor(Color, Color, Color);
            mesh.AddTriangle(Position, edge.v4, edge.v5);
            mesh.AddTriangleColor(Color, Color, Color);

            HexCell neighbor = GetNeighbor(direction);
            if (direction <= HexDirection.SE && neighbor != null)
            {
                edges[(int)direction] = HexEdge.Build(this, neighbor, direction);
                edges[(int)direction].Triangulate(mesh);

                HexCell nextNeighbor = GetNeighbor(direction.Next());
                if (direction <= HexDirection.E && nextNeighbor != null)
                {
                    corners[(int)direction] = Corner.Build(this, neighbor, nextNeighbor, direction);
                    corners[(int)direction].Triangulate(mesh);
                }
            }
        }
    }
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;
        Vector3 vert1  = center + Hexmetrics.GetFirstSolidCorner(direction);
        Vector3 vert2  = center + Hexmetrics.GetSecondSolidCorner(direction);

        terrain.AddTriangle(center, vert1, vert2);

        terrain.AddTriangleColor(cell.color);

        if (direction <= HexDirection.SE)
        {
            TriangulateConnection(direction, cell, vert1, vert2);
        }
    }
Beispiel #3
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;
        }
    }
Beispiel #4
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;

        map.AddTriangle(
            center,
            center + _hexMetrics.GetFirstCorner(direction),
            center + _hexMetrics.GetSecondCorner(direction)
            );
        map.AddTriangleColor(cell.Color);
    }
Beispiel #5
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;

        terrain.AddTriangle(
            center,
            center + HexMetrics.GetFirstCorner(direction),
            center + HexMetrics.GetSecondCorner(direction)
            );
        HexCell prevNeighbor = cell.GetNeighbor(direction.Previous()) ?? cell;
        HexCell neighbor     = cell.GetNeighbor(direction) ?? cell;
        HexCell nextNeighbor = cell.GetNeighbor(direction.Next()) ?? cell;

        terrain.AddTriangleColor(cell.Color);
    }
Beispiel #6
0
    protected static void TriangulateBoundaryTriangle(
        HexMesh mesh,
        Vector3 beginCorner, HexCell beginCell,
        Vector3 leftCorner, HexCell leftCell,
        Vector3 boundary, Color boundaryColor
        )
    {
        Vector3 v1 = beginCorner;
        Color   c1 = beginCell.Color;

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

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

            mesh.AddTriangle(HexMetrics.Perturb(v1), HexMetrics.Perturb(v3), boundary, false);
            mesh.AddTriangleColor(c1, c3, boundaryColor);

            v1 = v3;
            c1 = c3;
        }
    }
    public override void Triangulate(HexMesh mesh)
    {
        float lerpCoef = (float)(rightCell.Elevation - beginCell.Elevation) / (leftCell.Elevation - beginCell.Elevation);

        if (lerpCoef < 0)
        {
            lerpCoef = -lerpCoef;
        }
        Vector3 boundary      = Vector3.Lerp(HexMetrics.Perturb(beginCorner), HexMetrics.Perturb(leftCorner), lerpCoef);
        Color   boundaryColor = Color.Lerp(beginCell.Color, leftCell.Color, lerpCoef);

        Corner.TriangulateBoundaryTriangle(mesh, rightCorner, rightCell, beginCorner, beginCell, boundary, boundaryColor);

        if (HexMetrics.GetEdgeType(leftCell.Elevation, rightCell.Elevation) == HexEdgeType.Slope)
        {
            TriangulateBoundaryTriangle(mesh, leftCorner, leftCell, rightCorner, rightCell, boundary, boundaryColor);
        }
        else
        {
            mesh.AddTriangle(HexMetrics.Perturb(leftCorner), HexMetrics.Perturb(rightCorner), boundary, false);
            mesh.AddTriangleColor(leftCell.Color, rightCell.Color, boundaryColor);
        }
    }
Beispiel #8
0
 void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, Color color)
 {
     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);
 }
Beispiel #9
0
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
        }
    }
Beispiel #10
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);
        }
    }
Beispiel #11
0
 private void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
 {
     _terrain.AddTriangle(bottom, left, right);
     _terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
 }
Beispiel #12
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, 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 TriangulateCorner(Vector3 bottom, HexCell bottomCell,
                           Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(bottom, bottomCell, left,
                                          leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(left, leftCell, right,
                                          rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left,
                                               leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCorner(right, rightCell, bottom,
                                  bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerCliffTerraces(bottom, bottomCell, left,
                                               leftCell, right, rightCell);
            }
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom,
                                               bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right,
                                               rightCell, bottom, bottomCell);
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(color1, color2, color3);
            Vector3 types;
            types.x = bottomCell.TerrainTypeIndex;
            types.y = leftCell.TerrainTypeIndex;
            types.z = rightCell.TerrainTypeIndex;
            terrain.AddTriangleTerrainTypes(types);
        }

        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
Beispiel #14
0
    /*
     * 绘制三角形的连接区域
     * 根据边界类型调用其他Corner绘制方法
     * 每一个三角形都连接3个cell
     *
     * 颜色对应
     * red bottom vertex,
     * green left vertex
     * blue  right vertex
     */
    void TriangulateCorner(
        Vector3 bottom, HexCell bottomCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {   //slope-slope-flat,类型
                TriangulateCornerTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell);
            }
            //slope-flat-slope,类型(底-左-右)
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(
                    left, leftCell, right, rightCell, bottom, bottomCell);
            }
            //
            else
            {
                TriangulateCornerTerracesCliff(
                    bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                //flat-slope-slope,类型(底-左-右)
                TriangulateCornerTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }//The Mirror Cases镜像情况
            else
            {
                TriangulateCornerCliffTerraces(
                    bottom, bottomCell, left, leftCell, right, rightCell);
            }
        }
        //Double Cliffs,双悬崖情况
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(
                    right, rightCell, bottom, bottomCell, left, leftCell
                    );
            }
            else
            {
                TriangulateCornerTerracesCliff(
                    left, leftCell, right, rightCell, bottom, bottomCell
                    );
            }
        }
        else
        {
            terrain.AddTriangle(bottom, left, right);
            terrain.AddTriangleColor(color1, color2, color3);
            //添加地形贴图UV
            Vector3 types;
            types.x = bottomCell.TerrainTypeIndex;
            types.y = leftCell.TerrainTypeIndex;
            types.z = rightCell.TerrainTypeIndex;
            terrain.AddTriangleTerrainTypes(types);
        }

        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
Beispiel #15
0
    // Each corner is connected to three edges, which could be flats, slopes, or cliffs. So there are many possible configurations.
    void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left,
                           HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        HexEdgeType leftEdgeType  = bottomCell.GetEdgeType(leftCell);
        HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell);

        // If both edges are slopes, then we have terraces on both the left and the right side.
        // Also, because the bottom cell is the lowest, we know that those slopes go up.
        // Furthermore, this means that the left and right cell have the same elevation, so the top edge connection is flat.
        if (leftEdgeType == HexEdgeType.Slope)
        {
            if (rightEdgeType == HexEdgeType.Slope)
            {
                TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }
            else if (rightEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell);
            }

            return;
        }
        else if (rightEdgeType == HexEdgeType.Slope)
        {
            if (leftEdgeType == HexEdgeType.Flat)
            {
                TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell);
            }

            return;
        }
        else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            if (leftCell.Elevation < rightCell.Elevation)
            {
                TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
            }
            else
            {
                TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
            }

            return;
        }

        Terrain.AddTriangle(bottom, left, right);
        Terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color);
    }
Beispiel #16
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);
        }
    }
Beispiel #17
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);
        }
    }
Beispiel #18
0
 public override void Triangulate(HexMesh mesh)
 {
     mesh.AddTriangle(beginCorner, leftCorner, rightCorner);
     mesh.AddTriangleColor(beginCell.Color, leftCell.Color, rightCell.Color);
 }
    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));
        }
    }