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); } }
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); }
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); } } } }
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); } }
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)); } } }
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); } }
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); }
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)); } }