Пример #1
0
        private void TriangulateEdgeStrip(EdgeVertices edge1, Color color1, float type1, EdgeVertices edge2, Color color2, float type2, bool hasRoad = false)
        {
            _terrain.AddQuad(edge1.v1, edge1.v2, edge2.v1, edge2.v2);
            _terrain.AddQuadColor(color1, color2);
            _terrain.AddQuad(edge1.v2, edge1.v3, edge2.v2, edge2.v3);
            _terrain.AddQuadColor(color1, color2);
            _terrain.AddQuad(edge1.v3, edge1.v4, edge2.v3, edge2.v4);
            _terrain.AddQuadColor(color1, color2);
            _terrain.AddQuad(edge1.v4, edge1.v5, edge2.v4, edge2.v5);
            _terrain.AddQuadColor(color1, color2);

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

            _terrain.AddQuadTerrainTypes(types);
            _terrain.AddQuadTerrainTypes(types);
            _terrain.AddQuadTerrainTypes(types);
            _terrain.AddQuadTerrainTypes(types);

            if (hasRoad)
            {
                TriangulateRoadSegment(edge1.v2, edge1.v3, edge1.v4, edge2.v2, edge2.v3, edge2.v4);
            }
        }
Пример #2
0
        private void TriangulateEdgeTerraces(EdgeVertices edge1, HexCell beginCell, EdgeVertices edge2, HexCell endCell, bool hasRoad)
        {
            float t1 = beginCell.TerrainTypeIndex;
            float t2 = endCell.TerrainTypeIndex;
            var   e2 = HexMetrics.GetTerracePosition(edge1, edge2, 1);
            // var c2 = HexMetrics.GetTerraceColor(beginCell.Color, endCell.Color, 1);
            var c2 = HexMetrics.GetTerraceColor(sColor1, sColor2, 1);

            // TriangulateEdgeStrip(edge1, beginCell.Color, e2, c2, hasRoad);
            TriangulateEdgeStrip(edge1, sColor1, t1, e2, c2, t2, hasRoad);

            for (var i = 2; i < HexMetrics.terraceSteps; i++)
            {
                var e1 = e2;
                var c1 = c2;
                e2 = HexMetrics.GetTerracePosition(edge1, edge2, i);
                // c2 = HexMetrics.GetTerraceColor(beginCell.Color, endCell.Color, i);
                c2 = HexMetrics.GetTerraceColor(sColor1, sColor2, i);
                TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2, hasRoad);
            }

            // TriangulateEdgeStrip(e2, c2, edge2, endCell.Color, hasRoad);
            TriangulateEdgeStrip(e2, c2, t1, edge2, sColor2, t2, hasRoad);
        }
Пример #3
0
        private void TriangulateConnection(HexDirection direction, HexCell cell, EdgeVertices edge)
        {
            var neighbor = cell.GetNeighbor(direction);

            if (neighbor == null)
            {
                return;
            }

            var bridge   = HexMetrics.GetBridge(direction);
            var edgeType = HexEdgeTypeExtension.GetEdgeType(cell.Evaluation, neighbor.Evaluation);

            bridge.y = neighbor.Position.y - cell.Position.y;
            var neighborEdge = new EdgeVertices(edge.v1 + bridge, edge.v5 + bridge, HexMetrics.edgeOuterStep);

            if (cell.HasRiverThroughEdge(direction))
            {
                neighborEdge.v3.y = neighbor.StreamBedY;

                if (!cell.IsUnderWater)
                {
                    if (!neighbor.IsUnderWater)
                    {
                        var isReverse = cell.HasInComingRiver && cell.IncomingRiver == direction;
                        TriangulateRiverQuad(edge.v2, edge.v4, neighborEdge.v2, neighborEdge.v4, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f, isReverse);
                    }
                    else if (cell.Evaluation > neighbor.WaterLevel)
                    {
                        TriangulateWaterFall(edge.v2, edge.v4, neighborEdge.v2, neighborEdge.v4, cell.RiverSurfaceY, neighbor.RiverSurfaceY, neighbor.WaterSurfaceY);
                    }
                }
                else if (!neighbor.IsUnderWater && neighbor.Evaluation > cell.WaterLevel)
                {
                    TriangulateWaterFall(neighborEdge.v4, neighborEdge.v2, edge.v4, edge.v2, neighbor.RiverSurfaceY, cell.RiverSurfaceY, cell.WaterSurfaceY);
                }
            }

            if (edgeType == HexEdgeType.Slop)
            {
                TriangulateEdgeTerraces(edge, cell, neighborEdge, neighbor, cell.HasRoadThroughEdge(direction));
            }
            else
            {
                // TriangulateEdgeStrip(edge, cell.Color, neighborEdge, neighbor.Color, cell.HasRoadThroughEdge(direction));
                TriangulateEdgeStrip(edge, sColor1, cell.TerrainTypeIndex, neighborEdge, sColor2, neighbor.TerrainTypeIndex, cell.HasRoadThroughEdge(direction));
            }


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

            if (direction <= HexDirection.E && nextNeighbor != null)
            {
                var v5 = edge.v5 + HexMetrics.GetBridge(direction.Next());
                v5.y = nextNeighbor.Position.y;

                if (cell.Evaluation <= neighbor.Evaluation)
                {
                    if (cell.Evaluation <= nextNeighbor.Evaluation)
                    {
                        TriangulateCorner(edge.v5, cell, neighborEdge.v5, neighbor, v5, nextNeighbor);
                    }
                    else
                    {
                        TriangulateCorner(v5, nextNeighbor, edge.v5, cell, neighborEdge.v5, neighbor);
                    }
                }
                else
                {
                    if (neighbor.Evaluation <= nextNeighbor.Evaluation)
                    {
                        TriangulateCorner(neighborEdge.v5, neighbor, v5, nextNeighbor, edge.v5, cell);
                    }
                    else
                    {
                        TriangulateCorner(v5, nextNeighbor, edge.v5, cell, neighborEdge.v5, neighbor);
                    }
                }
            }
        }
Пример #4
0
        private void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices edge)
        {
            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, edge.v5, 2f / 3f);
            }
            else if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                centerL = Vector3.Lerp(center, edge.v1, 2f / 3f);
                centerR = center;
            }
            else if (cell.HasRiverThroughEdge(direction.Next().Next()))
            {
                centerL = center;
                centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.innerToOuter);
            }
            else if (cell.HasRiverThroughEdge(direction.Previous().Previous()))
            {
                centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.innerToOuter);
                centerR = center;
            }
            else
            {
                centerL = centerR = center;
            }
            var mEdge = new EdgeVertices(Vector3.Lerp(centerL, edge.v1, 0.5f), Vector3.Lerp(centerR, edge.v5, 0.5f), HexMetrics.edgeOuterStep);

            mEdge.v3.y = center.y = edge.v3.y = cell.StreamBedY;

            // TriangulateEdgeStrip(mEdge, cell.Color, edge, cell.Color);
            TriangulateEdgeStrip(mEdge, sColor1, cell.TerrainTypeIndex, edge, sColor1, cell.TerrainTypeIndex);
            _terrain.AddTriangle(centerL, mEdge.v1, mEdge.v2);
            // _terrain.AddTriangleColor(cell.Color);
            _terrain.AddTriangleColor(sColor1);
            _terrain.AddQuad(centerL, center, mEdge.v2, mEdge.v3);
            // _terrain.AddQuadColor(cell.Color);
            _terrain.AddQuadColor(sColor1);
            _terrain.AddQuad(center, centerR, mEdge.v3, mEdge.v4);
            // _terrain.AddQuadColor(cell.Color);
            _terrain.AddQuadColor(sColor1);
            _terrain.AddTriangle(centerR, mEdge.v4, mEdge.v5);
            // _terrain.AddTriangleColor(cell.Color);
            _terrain.AddTriangleColor(sColor1);

            var types = new Vector3(cell.TerrainTypeIndex, cell.TerrainTypeIndex, cell.TerrainTypeIndex);

            _terrain.AddTriangleTerrainTypes(types);
            _terrain.AddQuadTerrainTypes(types);
            _terrain.AddQuadTerrainTypes(types);
            _terrain.AddTriangleTerrainTypes(types);

            if (!cell.IsUnderWater)
            {
                var reverse = cell.IncomingRiver == direction;
                TriangulateRiverQuad(centerL, centerR, mEdge.v2, mEdge.v4, cell.RiverSurfaceY, 0.4f, reverse);
                TriangulateRiverQuad(mEdge.v2, mEdge.v4, edge.v2, edge.v4, cell.RiverSurfaceY, 0.6f, reverse);
            }
        }
Пример #5
0
        private void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices edge)
        {
            var mEdge = new EdgeVertices(
                Vector3.Lerp(center, edge.v1, 0.5f),
                Vector3.Lerp(center, edge.v5, 0.5f),
                HexMetrics.edgeOuterStep);

            mEdge.v3.y = edge.v3.y;
            // TriangulateEdgeStrip(mEdge, cell.Color, edge, cell.Color);
            // TriangulateEdgeFan(mEdge, center, cell.Color);
            TriangulateEdgeStrip(mEdge, sColor1, cell.TerrainTypeIndex, edge, sColor1, cell.TerrainTypeIndex);
            TriangulateEdgeFan(mEdge, center, cell.TerrainTypeIndex);

            if (!cell.IsUnderWater)
            {
                bool isReverse = cell.HasInComingRiver;
                TriangulateRiverQuad(mEdge.v2, mEdge.v4, edge.v2, edge.v4, cell.RiverSurfaceY, 0.6f, isReverse);
                center.y = mEdge.v2.y = mEdge.v4.y = cell.RiverSurfaceY;
                _river.AddTriangle(center, mEdge.v2, mEdge.v4);
                if (isReverse)
                {
                    _river.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1, 0.2f), new Vector2(0, 0.2f));
                }
                else
                {
                    _river.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0, 0.6f), new Vector2(1, 0.6f));
                }
            }
        }
Пример #6
0
        private void TriangulateRoadAdjacentToRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices edge)
        {
            var hasRoadThroughEdge = cell.HasRoadThroughEdge(direction);
            var previousHasRiver   = cell.HasRiverThroughEdge(direction.Previous());
            var nextHasRiver       = cell.HasRiverThroughEdge(direction.Next());
            var interpolators      = GetRoadInterpolators(direction, cell);
            var roadCenter         = center;

            if (cell.HasRiverBeginOrEnd)
            {
                roadCenter += HexMetrics.GetSolidEdgeMiddle(cell.RiverBeginOrEndDirection.Opposite()) * 1f / 3f;
            }
            else if (cell.IncomingRiver == cell.OutgoingRiver.Opposite())
            {
                Vector3 corner;
                if (previousHasRiver)
                {
                    if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Next()))
                    {
                        return;
                    }

                    corner = HexMetrics.GetSecondSolidCorner(direction);
                }
                else
                {
                    if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Previous()))
                    {
                        return;
                    }

                    corner = HexMetrics.GetFirstSolidCorner(direction);
                }

                roadCenter += corner * 0.5f;
                center     += corner * 0.25f;
            }
            else if (cell.IncomingRiver == cell.OutgoingRiver.Previous())
            {
                roadCenter -= HexMetrics.GetSecondCorner(cell.IncomingRiver) * 0.2f;
            }
            else if (cell.IncomingRiver == cell.OutgoingRiver.Next())
            {
                roadCenter -= HexMetrics.GetFirstCorner(cell.IncomingRiver) * 0.2f;
            }
            else if (previousHasRiver && nextHasRiver)
            {
                if (!hasRoadThroughEdge)
                {
                    return;
                }

                var offset = HexMetrics.GetSolidEdgeMiddle(direction) * HexMetrics.innerToOuter;
                roadCenter += offset * 0.7f;
                center     += offset * 0.5f;
            }
            else
            {
                HexDirection middle;
                if (previousHasRiver)
                {
                    middle = direction.Next();
                }
                else if (nextHasRiver)
                {
                    middle = direction.Previous();
                }
                else
                {
                    middle = direction;
                }

                if (!cell.HasRoadThroughEdge(middle) &&
                    !cell.HasRoadThroughEdge(middle.Previous()) &&
                    !cell.HasRiverThroughEdge(middle.Next()))
                {
                    return;
                }

                roadCenter += HexMetrics.GetSolidEdgeMiddle(middle) * 0.25f;
            }
            var mL = Vector3.Lerp(roadCenter, edge.v1, interpolators.x);
            var mR = Vector3.Lerp(roadCenter, edge.v5, interpolators.y);

            TriangulateRoad(roadCenter, mL, mR, edge, hasRoadThroughEdge);
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                TriangulateRoadEdge(roadCenter, center, mL);
            }

            if (cell.HasRiverThroughEdge(direction.Next()))
            {
                TriangulateRoadEdge(roadCenter, mR, center);
            }
        }
Пример #7
0
        private void TriangulateAdjacentToRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices edge)
        {
            if (cell.HasRoads)
            {
                TriangulateRoadAdjacentToRiver(direction, cell, center, edge);
            }
            if (cell.HasRiverThroughEdge(direction.Next()))
            {
                if (cell.HasRiverThroughEdge(direction.Previous()))
                {
                    center += HexMetrics.GetSolidEdgeMiddle(direction) * (HexMetrics.innerToOuter * 0.5f);
                }
                else if (cell.HasRiverThroughEdge(direction.Previous().Previous()))
                {
                    center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
                }
            }
            else if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                if (cell.HasRiverThroughEdge(direction.Next().Next()))
                {
                    center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f;
                }
            }
            var mEdge = new EdgeVertices(
                Vector3.Lerp(center, edge.v1, 0.5f),
                Vector3.Lerp(center, edge.v5, 0.5f), HexMetrics.edgeOuterStep);

            // TriangulateEdgeStrip(mEdge, cell.Color, edge, cell.Color);
            // TriangulateEdgeFan(mEdge, center, cell.Color);
            TriangulateEdgeStrip(mEdge, sColor1, cell.TerrainTypeIndex, edge, sColor1, cell.TerrainTypeIndex);
            TriangulateEdgeFan(mEdge, center, cell.TerrainTypeIndex);
        }
Пример #8
0
        private void TriangulateWithoutRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices edge)
        {
            // TriangulateEdgeFan(edge, center, cell.Color);
            TriangulateEdgeFan(edge, center, cell.TerrainTypeIndex);

            if (cell.HasRoads)
            {
                var interpolators = GetRoadInterpolators(direction, cell);
                TriangulateRoad(center,
                                Vector3.Lerp(center, edge.v1, interpolators.x),
                                Vector3.Lerp(center, edge.v5, interpolators.y),
                                edge, cell.HasRoadThroughEdge(direction));
            }
        }