예제 #1
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);
        }
    }
예제 #2
0
        private void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
        {
            EdgeVertices e1 = new EdgeVertices(
                center + HexMetrics.GetFirstWaterCorner(direction),
                center + HexMetrics.GetSecondWaterCorner(direction)
                );

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

            Vector3 center2 = neighbor.Position;

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

            if (cell.HasRiverThroughEdge(direction))
            {
                TriangulateEstuary(e1, e2, cell.IncomingRiver == direction);
            }
            else
            {
                waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
                waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
                waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
                waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
                waterShore.AddQuadUV(0f, 0f, 0f, 1f);
                waterShore.AddQuadUV(0f, 0f, 0f, 1f);
                waterShore.AddQuadUV(0f, 0f, 0f, 1f);
                waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            }

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

            if (nextNeighbor != null)
            {
                Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ?
                                                      HexMetrics.GetFirstWaterCorner(direction.Previous()) :
                                                      HexMetrics.GetFirstSolidCorner(direction.Previous()));
                v3.y = center.y;
                waterShore.AddTriangle(e1.v5, e2.v5, v3);
                waterShore.AddTriangleUV(
                    new Vector2(0f, 0f),
                    new Vector2(0f, 1f),
                    new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)
                    );
            }
        }
예제 #3
0
    void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell)
    {
        var center     = cell.Center;
        var closerEdge = cell.Edges[(int)direction];

        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.GetLeftSolidCorner(direction) * 0.25f;
            }
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next2()))
        {
            center += HexMetrics.GetRightSolidCorner(direction) * 0.25f;
        }

        var m = new EdgeVertices(Vector3.Lerp(center, closerEdge.V1, 0.5f), Vector3.Lerp(center, closerEdge.V5, 0.5f));

        m.V3.y = closerEdge.V3.y; // reassign middle verticle height as it is ommited in the calculation above

        TriangulateEdgeStrip(m, cell.Color, closerEdge, cell.Color);
        TriangulateEdgeFan(center, m, cell.Color);

        // river segments are added only if the current segment is not under water
        if (!cell.IsUnderwater)
        {
            bool reversed = cell.HasIncomingRiver;

            // outer circle of the hex
            TriangulateRiverQuadUnperturbed(m.V2, m.V4, closerEdge.V2, closerEdge.V4, cell.RiverSurfaceY, 0.6f, reversed);

            // end (or start) triangle
            center.y = m.V2.y = m.V4.y = cell.RiverSurfaceY;
            Rivers.AddTriangleUnperturbed(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));
            }
        }
    }
예제 #4
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
        {
            centerL = 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;
        //fill the space between the middle and edge lines.
        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);
        AddTriangle(centerL, m.v1, m.v2);
        AddTriangleColor(cell.Color);
        AddQuad(centerL, center, m.v2, m.v3);
        AddQuadColor(cell.Color);
        AddQuad(center, centerR, m.v3, m.v4);
        AddQuadColor(cell.Color);
        AddTriangle(centerR, m.v4, m.v5);
        AddTriangleColor(cell.Color);
    }
예제 #5
0
    void TriangulateAdjacentToRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e
        )
    {
        Terrain terrain = cell.Terrain;

        if (terrain.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (terrain.RiverTerrain.HasRiverThroughEdge(direction.Next()))
        {
            if (terrain.RiverTerrain.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction) *
                          (HexMetrics.innerToOuter * 0.5f);
            }
            else if (
                terrain.RiverTerrain.HasRiverThroughEdge(direction.Previous2())
                )
            {
                center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (
            terrain.RiverTerrain.HasRiverThroughEdge(direction.Previous()) &&
            terrain.RiverTerrain.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 (!terrain.IsUnderwater && !terrain.HasRoadThroughEdge(direction))
        {
            features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
예제 #6
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, weights1, cell.Index,
            e, weights1, cell.Index
            );
        TriangulateEdgeFan(center, m, cell.Index);

        //спавн объектов игрового окружения в каждом из 6 треугольников если нет рек и дорог
        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
예제 #7
0
        //We need to draw a river from previousCell to nextCell by adding rivers
        //to the edges of currentCell. PreviousCell is in directionToNext.Next2(),
        //and should have some river pointing at currentCell
        private RiverPathResults CreateRiverAlongCell_GentleCWTurn(
            IHexCell previousCell, IHexCell currentCell, IHexCell nextCell,
            HexDirection directionToPrevious, HexDirection directionToNext,
            IEnumerable <IHexCell> oceanCells, HashSet <IHexCell> cellsAdjacentToRiver
            )
        {
            var leftLeftPath = new RiverPath(
                currentCell, directionToPrevious.Next(), directionToNext.Previous(),
                RiverFlow.Clockwise, RiverCanon, Grid
                );

            var leftRightPath = new RiverPath(
                currentCell, directionToPrevious, directionToNext.Next(),
                RiverFlow.Counterclockwise, RiverCanon, Grid
                );

            var rightRightPath = new RiverPath(
                currentCell, directionToNext.Next(),
                RiverFlow.Counterclockwise, RiverCanon, Grid
                );

            var rightleftPath = new RiverPath(
                currentCell, directionToPrevious, directionToNext.Previous(),
                RiverFlow.Clockwise, RiverCanon, Grid
                );

            var pathsToTry = new List <RiverPath>();

            //If directionToNext.Previous() is considered up,
            //this case triggers when previousCell has a river
            //along its upper-left edge.
            if (RiverCanon.HasRiverAlongEdge(previousCell, directionToPrevious.Next2()))
            {
                pathsToTry.Add(leftLeftPath);
                pathsToTry.Add(leftRightPath);
            }

            //If directionToNext.Previous() is considered up,
            //this case triggers when previousCell has a river
            //along its upper-right edge.
            if (RiverCanon.HasRiverAlongEdge(previousCell, directionToPrevious.Previous2()))
            {
                pathsToTry.Add(rightRightPath);
                pathsToTry.Add(rightleftPath);
            }

            return(TryFollowSomePath(pathsToTry, oceanCells, cellsAdjacentToRiver));
        }
예제 #8
0
파일: HexMesh.cs 프로젝트: shi-yh/HexMap
    private void Triangulate(HexDirection dir, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;

        Vector3 v1 = center + HexMertics.GetFirstSolidCornor(dir);

        Vector3 v2 = center + HexMertics.GetSecondSolidCornor(dir);

        ///第一个顶点的位置为cell正中心,其余为cell的顶点
        AddTriangle(center, v1, v2);
        AddTriangleColor(cell.color);



        ///根据方向获取相邻的节点
        HexCell neighbor     = cell.GetNeighbor(dir) ?? cell;
        HexCell preNeighbor  = cell.GetNeighbor(dir.Previous()) ?? cell;
        HexCell nextNeighbor = cell.GetNeighbor(dir.Next()) ?? cell;

        if (dir <= HexDirection.SE)
        {
            TriangulateConnection(dir, cell, v1, v2);
        }


        //AddTriangle(v1, center + HexMertics.GetFirstCornor(dir),v3);
        //AddTriangleColor(cell.color, (cell.color + preNeighbor.color + neighbor.color) / 3, bridgeColor);

        //AddTriangle(v2, v4, center + HexMertics.GetSecondCornor(dir));
        //AddTriangleColor(cell.color, bridgeColor, (cell.color + neighbor.color + nextNeighbor.color) / 3);
    }
예제 #9
0
    /// <summary>
    /// Only call this after checking CanChangeDir, this function will not return the current dir if it is the only one left
    /// </summary>
    /// <param name="currentNeighbors"></param>
    /// <param name="currentDirection"></param>
    /// <returns></returns>
    private int GetNewDir(List <HexCell> currentNeighbors, HexDirection currentDirection)
    {
        var viableNeighborsIndices = new List <int>();

        for (int i = 0; i < currentNeighbors.Count; i++)
        {
            try
            {
                if (currentNeighbors[i].landType == LandType.Grass && i != (int)currentDirection)
                {
                    viableNeighborsIndices.Add(i);
                }
            }
            catch (NullReferenceException) { }
        }

        var favoredDirections = new HexDirection[] { currentDirection.Next(), currentDirection.Previous() };

        foreach (var hexDir in favoredDirections)
        {
            if (viableNeighborsIndices.Contains((int)hexDir))
            {
                return((int)hexDir);
            }
        }

        return(viableNeighborsIndices[UnityEngine.Random.Range(0, viableNeighborsIndices.Count)]);
    }
예제 #10
0
    void TriangulateWithRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e
        )
    {
        Vector3 centerL = center +
                          HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f;
        Vector3 centerR = center +
                          HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f;
        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);

        AddTriangle(centerL, m.v1, m.v2);
        AddTriangleColor(cell.Color);
        AddQuad(centerL, center, m.v2, m.v3);
        AddQuadColor(cell.Color);
        AddQuad(center, centerR, m.v3, m.v4);
        AddQuadColor(cell.Color);
        AddTriangle(centerR, m.v4, m.v5);
        AddTriangleColor(cell.Color);
    }
예제 #11
0
        public RiverPath(
            IHexCell cell, HexDirection pathStart, HexDirection pathEnd,
            RiverFlow flow, IRiverCanon riverCanon, IHexGrid grid
            )
        {
            Cell = cell;
            Path = new List <HexDirection>();
            Flow = flow;

            if (flow == RiverFlow.Clockwise)
            {
                for (HexDirection i = pathStart; i != pathEnd; i = i.Next())
                {
                    Path.Add(i);
                }
            }
            else
            {
                for (HexDirection i = pathStart; i != pathEnd; i = i.Previous())
                {
                    Path.Add(i);
                }
            }

            Path.Add(pathEnd);

            RiverCanon = riverCanon;
            Grid       = grid;
        }
예제 #12
0
        //Since we're often triangulating water that goes up against land,
        //We need to be careful about how we assign colors. There are three
        //basic cases: center is water, either left or right (but not both)
        //is water, or all three cells are water.
        private void GetWaterColors(
            IHexCell center, HexDirection direction, out Color centerColor, out Color leftColor, out Color rightColor
            )
        {
            centerColor = GetWaterColor(center);

            var left  = Grid.GetNeighbor(center, direction.Previous());
            var right = Grid.GetNeighbor(center, direction);

            bool isLeftWater  = left != null && left.Terrain.IsWater();
            bool isRightWater = right != null && right.Terrain.IsWater();

            if (isLeftWater)
            {
                leftColor = GetWaterColor(left);

                rightColor = isRightWater
                           ? rightColor = GetWaterColor(right)
                           : Color.Lerp(centerColor, leftColor, 0.5f);
            }
            else if (isRightWater)
            {
                rightColor = GetWaterColor(right);

                leftColor = Color.Lerp(centerColor, rightColor, 0.5f);
            }
            else
            {
                leftColor  = centerColor;
                rightColor = centerColor;
            }
        }
예제 #13
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;
        Vector3 v1     = center + HexMetrics.GetFirstSolidCorner(direction);
        Vector3 v2     = center + HexMetrics.GetSecondSolidCorner(direction);
        Vector3 bridge = HexMetrics.GetBridge(direction);
        Vector3 v3     = v1 + bridge;
        Vector3 v4     = v2 + bridge;

        AddTriangle(center, v1, v2);
        AddTriangleColor(cell.color);
        AddQuad(v1, v2, v3, v4);

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

        Color bridgeColor = (cell.color + neighbor.color) * 0.5f;

        AddQuadColor(cell.color, bridgeColor);

        AddTriangle(v1, center + HexMetrics.GetFirstCorner(direction), v3);
        AddTriangleColor(
            cell.color,
            (cell.color + prevNeighbor.color + neighbor.color) / 3f,
            bridgeColor
            );
        AddTriangle(v2, v4, center + HexMetrics.GetSecondCorner(direction));
        AddTriangleColor(
            cell.color,
            bridgeColor,
            (cell.color + neighbor.color + nextNeighbor.color) / 3f
            );
    }
예제 #14
0
    private void Triangulate(HexDirection d, HexCell hexCell)
    {
        Vector3 center = hexCell.transform.localPosition;
        Vector3 v1     = center + HexMetrics.GetFirstSolidCorner(d);
        Vector3 v2     = center + HexMetrics.GetSecondSolidCorner(d);

        AddTriangle(center, v1, v2);
        AddTriangleColor(hexCell.color, hexCell.color, hexCell.color);



        HexCell neighborNext = hexCell.GetNeighbor(d.Next()) ?? hexCell;
        HexCell neighborPrev = hexCell.GetNeighbor(d.Previous()) ?? hexCell;

        //Color colorNext = (hexCell.color + neighbor.color + neighborNext.color) / 3f;
        //Color colorPrev = (hexCell.color + neighbor.color + neighborPrev.color) / 3f;

        //Color colorBridge = (hexCell.color + neighbor.color) * 0.5f;
        if (d <= HexDirection.SE)   // NE , E, SE
        {
            TriangulateConnection(d, hexCell, v1, v2);
        }

        //// previous Corner

        //AddTriangle(v1, center + HexMetrics.GetFirstCorner(d), v3);
        //AddTriangleColor(hexCell.color, colorPrev, colorBridge);

        ////next corner
        //AddTriangle(v2, v4, center + HexMetrics.GetSecondCorner(d)); ;
        //AddTriangleColor(hexCell.color, colorBridge, colorNext);
    }
예제 #15
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;
        Vector3 v1     = center + HexMatrics.GetFirstSolidCorner(direction);
        Vector3 v2     = center + HexMatrics.GetSecondSolidCorner(direction);

        AddTriangle(center, v1, v2);
        AddTriangleColor(cell.color);

        Vector3 v3 = center + HexMatrics.GetFirstCorner(direction);
        Vector3 v4 = center + HexMatrics.GetSecondCorner(direction);

        AddQuad(v1, v2, v3, v4);

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

        AddQuadColor(
            cell.color,
            cell.color,
            (cell.color + prevNeighbor.color + neighbor.color) / 3f,
            (cell.color + neighbor.color + nextNeighbor.color) / 3f
            );
    }
예제 #16
0
        private void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
        {
            var edge = new EdgeVertices(
                center + HexMetrics.GetFirstWaterCorner(direction),
                center + HexMetrics.GetSecondWaterCorner(direction),
                HexMetrics.edgeOuterStep);

            _water.AddTriangle(center, edge.v1, edge.v2);
            _water.AddTriangle(center, edge.v2, edge.v3);
            _water.AddTriangle(center, edge.v3, edge.v4);
            _water.AddTriangle(center, edge.v4, edge.v5);

            var center2 = neighbor.Position;

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

            if (cell.HasRiverThroughEdge(direction))
            {
                TriangulateEstuary(edge, edge2, cell.IncomingRiver == direction);
            }
            else
            {
                _waterShore.AddQuad(edge.v1, edge.v2, edge2.v1, edge2.v2);
                _waterShore.AddQuad(edge.v2, edge.v3, edge2.v2, edge2.v3);
                _waterShore.AddQuad(edge.v3, edge.v4, edge2.v3, edge2.v4);
                _waterShore.AddQuad(edge.v4, edge.v5, edge2.v4, edge2.v5);
                _waterShore.AddQuadUV(0, 0, 0, 1);
                _waterShore.AddQuadUV(0, 0, 0, 1);
                _waterShore.AddQuadUV(0, 0, 0, 1);
                _waterShore.AddQuadUV(0, 0, 0, 1);
            }
            var nextNeighbor = cell.GetNeighbor(direction.Next());

            if (nextNeighbor != null)
            {
                var v3 = nextNeighbor.Position + (nextNeighbor.IsUnderWater
                             ? HexMetrics.GetFirstWaterCorner(direction.Previous())
                             : HexMetrics.GetFirstSolidCorner(direction.Previous()));
                v3.y = center.y;
                _waterShore.AddTriangle(edge.v5, edge2.v5, v3);
                _waterShore.AddTriangleUV(Vector2.zero, Vector2.up, nextNeighbor.IsUnderWater ? Vector2.zero : Vector2.up);
            }
        }
예제 #17
0
    void TriangulateConnection(HexDirection direction, HexCell cell, Vector3 v1, Vector3 v2)
    {
        Vector3 bridge = HexMetrics.GetBridge(direction);
        Vector3 v3     = v1 + bridge;
        Vector3 v4     = v2 + bridge;

        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor != null)
        {
            v3.y = v4.y = neighbor.transform.localPosition.y;
        }

        if (direction <= HexDirection.SE)
        {
            AddQuad(v1, v2, v3, v4);
            AddQuadColor(
                room.region.regionColor,
                room.region.regionColor,
                room.region.regionColor,
                room.region.regionColor
                );
        }
        /// if the neifhfbour is wall we create wall
        if (cell.edgeTypes[(int)direction] == EdgeType.WALL)
        {
            AddConnectionWall(v1, v2, v3, v4, cell);
        }
        /// if the neihgbour is door we create door
        if (cell.edgeTypes[(int)direction] == EdgeType.DOOR)
        {
            GenerateDoor(v1, v2, v3, v4);
        }

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

        Vector3 v2Top = v2 + Vector3.up * HexMetrics.wallHeight;
        Vector3 v4Top = v4 + Vector3.up * HexMetrics.wallHeight;

        if (direction <= HexDirection.NW)
        {
            Vector3 v5 = v2 + HexMetrics.GetBridge(direction.Next());
            if (nextNeighbor != null)
            {
                v5.y = nextNeighbor.transform.localPosition.y;
            }
            if (direction <= HexDirection.E)
            {
                AddTriangle(v2, v4, v5);
                AddTriangleColor(room.region.regionColor);
            }
            /// create a triangle wall adjacent to wall
            if (cell.edgeTypes[(int)direction] == EdgeType.WALL || cell.edgeTypes[(int)direction] == EdgeType.DOOR)
            {
                AddConnectionWallTriangle(v2, v4, v5, cell);
            }
        }
    }
예제 #18
0
 public bool IsSmoothCorner(HexDirection direction)
 {
     if (HasBuilding(direction.Previous()) && !HasBuilding(direction) && HasBuilding(direction.Next()))
     {
         return(true);
     }
     return(false);
 }
예제 #19
0
        //We need to draw a river from previousCell to nextCell by adding rivers
        //to the edges of currentCell. PreviousCell and nextCell are across from
        //each-other. Previous river should have some river pointing at currentCell
        private RiverPathResults CreateRiverAlongCell_StraightAcross(
            IHexCell previousCell, IHexCell currentCell, IHexCell nextCell,
            HexDirection directionToPrevious, HexDirection directionToNext,
            IEnumerable <IHexCell> oceanCells, HashSet <IHexCell> cellsAdjacentToRiver
            )
        {
            var leftToLeftPath = new RiverPath(
                currentCell, directionToNext.Previous2(), directionToNext.Previous(),
                RiverFlow.Clockwise, RiverCanon, Grid
                );

            var leftToRightPath = new RiverPath(
                currentCell, directionToPrevious, directionToNext.Next(),
                RiverFlow.Counterclockwise, RiverCanon, Grid
                );

            var rightToRightPath = new RiverPath(
                currentCell, directionToNext.Next2(), directionToNext.Next(),
                RiverFlow.Counterclockwise, RiverCanon, Grid
                );

            var rightToLeftPath = new RiverPath(
                currentCell, directionToPrevious, directionToNext.Previous(),
                RiverFlow.Clockwise, RiverCanon, Grid
                );

            var pathsToTry = new List <RiverPath>();

            //If nextCell is above us, this case happens when previousCell has a
            //river along its left edge
            if (RiverCanon.HasRiverAlongEdge(previousCell, directionToNext.Previous()))
            {
                pathsToTry.Add(leftToLeftPath);
                pathsToTry.Add(leftToRightPath);

                //If nextCell is above us, this case happens when previousCell has a
                //river along its right edge
            }
            else if (RiverCanon.HasRiverAlongEdge(previousCell, directionToNext.Next()))
            {
                pathsToTry.Add(rightToRightPath);
                pathsToTry.Add(rightToLeftPath);
            }

            return(TryFollowSomePath(pathsToTry, oceanCells, cellsAdjacentToRiver));
        }
예제 #20
0
        public void updateChunkWithRiversAndRoads1Test()
        {
            GameObject obj  = MonoBehaviour.Instantiate(Resources.Load <GameObject>("Prefabs/Hex Grid"));
            HexGrid    grid = obj.GetComponent <HexGrid>();

            HexGridChunk[] chunks = grid.getHexGridChunks();

            HexCell[]    cells     = chunks[0].getCells();
            HexDirection direction = HexDirection.NE;
            int          index     = 7;

            // ....................................................
            // SET DIRECT RIVER
            // ....................................................
            // Find cell with next steps: go to NE, go to NE
            HexCell cell = cells[index].GetNeighbor(direction)
                           .GetNeighbor(direction);

            // Set river to NW direction
            cell.SetOutgoingRiver(direction.Previous());
            // Get neigbor from SE direction cell
            HexCell neighbor = cell.GetNeighbor(direction.Next2());

            // Set river to NW direction
            neighbor.SetOutgoingRiver(direction.Previous());

            // Set road to previous 2 direction
            cell.AddRoad(direction.Next());

            // Set road to opposite direction
            cell.AddRoad(direction.Next().Opposite());
            // ....................................................

            // Update chunk
            foreach (HexGridChunk chunk in chunks)
            {
                chunk.Triangulate();
            }

            Assert.IsTrue(cell.HasIncomingRiver);
            Assert.IsTrue(cell.HasOutgoingRiver);
            Assert.IsTrue(cell.HasRoads);

            GameObject.Destroy(obj);
        }
예제 #21
0
    public bool IsDrawPreviousRoadMesh(HexDirection direction)
    {
        if (isThroughRoad[(int)direction] == true && isThroughRoad[(int)direction.Previous()] == false)
        {
            return(true);
        }

        return(false);
    }
예제 #22
0
    private void TriangulateAdjacentToRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            // Check whether we are on the inside of a curve.  This occurs when
            // both the previous and next direction contai a river. In this case teh center
            // will be moved towards the edge.
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction)
                          * (HexMetrics.innerToOuter * 0.5f);
                // Check whether this is a straight river, in that case move the center
                // towards the first corner.
            }
            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);

        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            features.AddFeature((center + e.v1 + e.v5) * (1f / 3f));
        }
    }
예제 #23
0
    public void TryExpandCorridor(ref Stack <TileProperties> remainingTiles, TileProperties affectedTile, HexDirection previousDirection)
    {
        TileProperties nextTile = affectedTile.GetNeighbor(previousDirection);

        if (affectedTile.Tile && nextTile.Tile && !ExpandCorridor(ref remainingTiles, affectedTile, previousDirection))
        {
            ExpandCorridor(ref remainingTiles, affectedTile, previousDirection.Previous());
            ExpandCorridor(ref remainingTiles, affectedTile, previousDirection.Next());
        }
    }
        public void RationalizeRiverContoursInCorner(IHexCell center, HexDirection direction)
        {
            IHexCell left = Grid.GetNeighbor(center, direction.Previous());

            //Contours will only fall short or overlap when we're at a river confluence,
            //so we can save ourselves time by checking for that
            if (left != null &&
                RiverCanon.HasRiverAlongEdge(center, direction.Previous()) &&
                RiverCanon.HasRiverAlongEdge(center, direction) &&
                RiverCanon.HasRiverAlongEdge(left, direction.Next())
                )
            {
                IHexCell right = Grid.GetNeighbor(center, direction);

                RiverSection centerLeftSection  = RiverSectionCanon.GetSectionBetweenCells(center, left);
                RiverSection centerRightSection = RiverSectionCanon.GetSectionBetweenCells(center, right);

                bool shouldCullContours = true;

                //Rationalizing contours also doesn't need to occur between segments
                //that are adjacent segments of the same river, which would put us on
                //the inside of a river curve. So we make some checks to exclude that
                //possibility, as well
                foreach (var river in RiverAssemblyCanon.Rivers)
                {
                    int leftIndex  = river.IndexOf(centerLeftSection);
                    int rightIndex = river.IndexOf(centerRightSection);

                    bool areAdjacentInRiver = ((leftIndex + 1) == rightIndex) || ((rightIndex + 1) == leftIndex);

                    if (leftIndex != -1 && rightIndex != -1 && areAdjacentInRiver)
                    {
                        shouldCullContours = false;
                        break;
                    }
                }

                if (shouldCullContours)
                {
                    ContourRationalizer.RationalizeCellContours(center, direction);
                }
            }
        }
예제 #25
0
    /// <summary>
    /// 填充河道细胞中其他没有河道的顶面部分
    /// 在此函数中处理河流和道路共存的情况
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="cell"></param>
    /// <param name="center"></param>
    /// <param name="e"></param>
    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.GetSoliEdgeMiddle(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);

        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
예제 #26
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, color1, cell.TerrainTypeIndex,
            e, color1, cell.TerrainTypeIndex
            );
        TriangulateEdgeFan(center, e, cell.TerrainTypeIndex);
    }
예제 #27
0
    public void TriangulateAdjacentToRiver(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadsAdjacentToRiver(dir, cell, center, edges);
        }


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


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

        Color color = Weights1; // cell.Color;

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


        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(dir))
        {
            // centred in triangle
            Vector3 position = (center + edges.v1 + edges.v5) * (1f / 3f);
            FeatureManager.AddFeature(cell, position);
        }
    }
예제 #28
0
    void TriangulateWaterShore(
        HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center
        )
    {
        EdgeVertices e1 = new EdgeVertices(
            center + HexMetrics.GetFirstWaterCorner(direction),
            center + HexMetrics.GetSecondWaterCorner(direction)
            );

        water.AddTriangle(center, e1.v1, e1.v2);

        Vector3 center2 = neighbor.Position;

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

        waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
        waterShore.AddQuadUV(0f, 0f, 0f, 1f);

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

        if (nextNeighbor != null)
        {
            Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ?
                                                  HexMetrics.GetFirstWaterCorner(direction.Previous()) :
                                                  HexMetrics.GetFirstOuterCorner(direction.Previous()));
            v3.y = center.y;
            waterShore.AddTriangle(
                e1.v2, e2.v2, v3
                );
            waterShore.AddTriangleUV(
                new Vector2(0f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)
                );
        }
    }
예제 #29
0
    void TriangulateAdjacentToRiver(HexDirection dir, HexCell hexCell, Vector3 center, EdgeVertices e)
    {
        // // Road + River
        if (hexCell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(dir, hexCell, center, e);
        }

        // Overlapping
        if (hexCell.HasRiverThroughEdge(dir.Next()))
        {
            if (hexCell.HasRiverThroughEdge(dir.Previous()))
            {
                center += Hex.GetSolidEdgeMiddle(dir) * Hex.innerToOuter * 0.5f;
            }
            else if (hexCell.HasRiverThroughEdge(dir.Previous().Previous()))
            {
                center += Hex.GetFirstSolidPoint(dir) * 0.25f;
            }
        }
        else if (hexCell.HasRiverThroughEdge(dir.Previous()) &&
                 hexCell.HasRiverThroughEdge(dir.Next().Next()))
        {
            center += Hex.GetSecondSolidPoint(dir) * 0.25f;
        }


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

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

        if (!hexCell.IsUnderwater && !hexCell.HasRoadThroughEdge(dir))
        {
            features.AddFeature(hexCell, ((center + e.v1 + e.v5) * (1f / 3f)));
        }
    }
예제 #30
0
        public void updateChunkWithWallsTest()
        {
            GameObject obj  = MonoBehaviour.Instantiate(Resources.Load <GameObject>("Prefabs/Hex Grid"));
            HexGrid    grid = obj.GetComponent <HexGrid>();

            HexGridChunk[] chunks = grid.getHexGridChunks();

            HexCell[]    cells     = chunks[0].getCells();
            HexDirection direction = HexDirection.NE;
            int          index     = 7;

            cells[index].Walled = true;
            cells[index].SetOutgoingRiver(direction);

            HexCell cell1 = cells[index].GetNeighbor(direction)
                            .GetNeighbor(direction);

            cell1.Walled = true;
            cell1.GetNeighbor(direction.Previous()).Elevation = 1;
            cell1.GetNeighbor(direction.Previous()).Walled    = true;


            HexCell cell2 = cells[index].GetNeighbor(direction.Next())
                            .GetNeighbor(direction.Next()).GetNeighbor(direction);

            cell2.GetNeighbor(direction.Previous()).Walled = true;
            cell2.GetNeighbor(direction).Walled            = true;

            // Update chunk
            foreach (HexGridChunk chunk in chunks)
            {
                chunk.Triangulate();
            }

            Assert.IsTrue(cells[index].Walled);
            Assert.AreEqual(direction, cells[index].OutgoingRiver);

            GameObject.Destroy(obj);
        }