Пример #1
0
    /// <summary>
    /// 三角化扇形内的道路
    ///    ----e
    ///   mL--mR
    ///      .
    /// </summary>
    /// <param name="center">六边形中点</param>
    /// <param name="mL">e.v1与center的中点</param>
    /// <param name="mR">e.v5与center的中点</param>
    /// <param name="e">扇形的弧(五顶点边)</param>
    /// <param name="hasRoadThroughCellEdge">该扇形是否有道路</param>
    /// <param name="index">六边形格子索引</param>
    void TriangulateRoad(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasRoadThroughCellEdge, int 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);
        }
    }
Пример #2
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);
                }
            }
        }
    }
Пример #3
0
    public void TriangulateRoadEdge(Vector3 center, Vector3 midLeft, Vector3 midRight, float index)
    {
        Roads.AddTriangle(center, midLeft, midRight);
        Roads.AddTriangleUV(new Vector2(1, 0), Vector2.zero, Vector2.zero);
        Vector3 indices = new Vector3(index, index, index);

        Roads.AddTriangleCellData(indices, Weights1);
    }
Пример #4
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);
        }
    }
Пример #5
0
 private void TriangulateWall(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasWallThroughCellEdge)
 {
     if (hasWallThroughCellEdge)
     {
         Vector3 mC = Vector3.Lerp(mL, mR, 0.5f);
         TriangulateWallSegment(mL, mC, mR, e.v2, e.v3, e.v4);
         _walls.AddTriangle(center, mL, mC);
         _walls.AddTriangle(center, mC, mR);
     }
     else
     {
         TriangulateWallEdge(center, mL, mR);
     }
 }
Пример #6
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);
        }
    }
Пример #7
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);
            Vector3 indices;
            indices.x = bottomCell.Index;
            indices.y = leftCell.Index;
            indices.z = rightCell.Index;
            terrain.AddTriangleCellData(indices, weights1, weights2, weights3);
        }

        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
Пример #8
0
    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);
        }
    }
Пример #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(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);
    }
Пример #10
0
    public void TriangulateWithRiverBeginningOrEnd(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges)
    {
        EdgeVertices modifiedEdges = new EdgeVertices(Vector3.Lerp(center, edges.v1, 0.5f), Vector3.Lerp(center, edges.v5, 0.5f));

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

        Color color = Weights1; // cell.Color;


        TriangulateEdgeStrip(modifiedEdges, color, cell.TerrainTypeIndex, edges, color, cell.CellIndex);
        TriangulateEdgeFan(center, modifiedEdges, color, cell.CellIndex);


        if (!cell.IsUnderwater)
        {
            bool    reverse = cell.HasIncomingRiver;
            Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex);
            TriangulateRiverQuad(modifiedEdges.v2, modifiedEdges.v4, edges.v2, edges.v4, cell.RiverSurfaceY, 0.6f, reverse, indices);

            center.y = modifiedEdges.v2.y = modifiedEdges.v4.y = cell.RiverSurfaceY;

            Rivers.AddTriangle(center, modifiedEdges.v2, modifiedEdges.v4);
            if (reverse)
            {
                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);
        }
    }
Пример #11
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));
        }
    }
Пример #12
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;
        }
    }
Пример #13
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, weights1, cell.Index, e, weights1, cell.Index);
        TriangulateEdgeFan(center, m, cell.Index);

        if (!cell.IsUnderWater)
        {
            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);
            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.5f), 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);
        }
    }
Пример #14
0
    void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        Vector3 centerL, centerR;

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

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

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

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

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

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.IncomingRiver == direction;
            TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f, HexMetrics.kRiverSolidUVStep, reversed);
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f + HexMetrics.kRiverSolidUVStep, HexMetrics.kRiverSolidUVStep, reversed);
        }
    }
Пример #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);
    }
Пример #16
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);
 }
Пример #17
0
    /* Creates a single triangle from cell center to cell edge */
    void TriangulateWedge(HexDirection direction, HexCell cell)
    {
        Vector3      center = cell.transform.localPosition;
        EdgeVertices e      = new EdgeVertices(
            center + HexMetrics.GetFirstSolidCorner(direction),
            center + HexMetrics.GetSecondSolidCorner(direction)
            );

        cellMesh.AddTriangle(center, e.v1, e.v2);
    }
Пример #18
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
            {
                TriangulateCornerTerraces(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);
        }
        features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell);
    }
Пример #19
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);
    }
Пример #20
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);
            }
        }
    }
Пример #21
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));
        }
    }
Пример #22
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);
            }
        }
    }
Пример #23
0
    void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, float index)
    {
        terrain.AddTriangle(center, edge.v1, edge.v2);
        terrain.AddTriangle(center, edge.v2, edge.v3);
        terrain.AddTriangle(center, edge.v3, edge.v4);
        terrain.AddTriangle(center, edge.v4, edge.v5);

        Vector3 indices;

        indices.x = indices.y = indices.z = index;
        terrain.AddTriangleCellData(indices, weights1);
        terrain.AddTriangleCellData(indices, weights1);
        terrain.AddTriangleCellData(indices, weights1);
        terrain.AddTriangleCellData(indices, weights1);
    }
Пример #24
0
    public void CreateMeshColliders()
    {
        mesh.Clear();

        for (int i = 0; i < cells.Length; i++)
        {
            HexCell cell = cells[i];
            for (int j = 0; j < 6; j++)
            {
                mesh.AddTriangle(cell.Position, cell.Position + HexMetrics.corners[j] * 0.95f, cell.Position + HexMetrics.corners[j + 1] * 0.95f);
            }
        }

        mesh.Apply();
    }
Пример #25
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);
    }
    /// <summary>
    /// Creates the triangles for a side of the hexagon.
    /// </summary>
    void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, float index)
    {
        // Add geometry
        Terrain.AddTriangle(center, edge.v1, edge.v2);
        Terrain.AddTriangle(center, edge.v2, edge.v3);
        Terrain.AddTriangle(center, edge.v3, edge.v4);
        Terrain.AddTriangle(center, edge.v4, edge.v5);

        // Add splat map colors and terrain type into cell data
        Vector3 indices;

        indices.x = indices.y = indices.z = index;
        Terrain.AddTriangleCellData(indices, weights1);
        Terrain.AddTriangleCellData(indices, weights1);
        Terrain.AddTriangleCellData(indices, weights1);
        Terrain.AddTriangleCellData(indices, weights1);
    }
Пример #27
0
    /* creates the stage boundaries */
    void TriangulateOuterWallPanelCorner(HexDirection direction, HexCell cell, HexCell neighbor)
    {
        Vector3 offset   = new Vector3(0, wallHeight, 0);
        Vector3 endpoint = offset + cell.transform.localPosition + HexMetrics.GetSecondCorner(direction);

        EdgeVertices e1 = new EdgeVertices(
            cell.transform.localPosition + HexMetrics.GetSecondSolidCorner(direction),
            neighbor.transform.localPosition + HexMetrics.GetFirstSolidCorner(direction.Previous())
            );
        EdgeVertices e2 = new EdgeVertices(
            e1.v1 + offset,
            e1.v2 + offset
            );

        edgeMesh.AddQuad(e1, e2);
        edgeMesh.AddTriangle(e2.v1, endpoint, e2.v2);
    }
Пример #28
0
    /// <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));
        }
    }
Пример #29
0
    private void AddWallWedge(Vector3 near, Vector3 far, Vector3 point)
    {
        near  = HexMetrics.Perturb(near);
        far   = HexMetrics.Perturb(far);
        point = HexMetrics.Perturb(point);

        Vector3 center    = HexMetrics.WallLerp(near, far);
        Vector3 thickness = HexMetrics.WallThicknessOffset(near, far);

        Vector3 v1;
        Vector3 v2;
        Vector3 v3       = v1 = center - thickness;
        Vector3 v4       = v2 = center + thickness;
        Vector3 pointTop = point;

        point.y = center.y;
        v3.y    = v4.y = pointTop.y = center.y + HexMetrics.wallHeight;
        walls.AddQuad(v1, point, v3, pointTop);
        walls.AddQuad(point, v2, pointTop, v4);
        walls.AddTriangle(pointTop, v3, v4);
    }
Пример #30
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;
        }
    }