/* The intention here is to find the AABB of the blob * and then draw another quad that contains the AABB but * is aligned to the edges of the hexagons rather than * world axes. We then use that box's edges to draw lines * that go across the hex diagonally. */ private void DrawLines( List <IHexCell> farmBlob, out List <FarmLine> toNortheastLines, out List <FarmLine> toNorthwestLines ) { if (RenderConfig.FarmPatchMaxWidth <= 0f) { throw new InvalidOperationException("RenderConfig.FarmPatchMaxWidth must be greater than zero"); } toNortheastLines = new List <FarmLine>(); toNorthwestLines = new List <FarmLine>(); Rect boundingRect = GetBlobRect(farmBlob); Vector2 aabbBottomLeft = new Vector2(boundingRect.xMin, boundingRect.yMin); Vector2 aabbBottomRight = new Vector2(boundingRect.xMax, boundingRect.yMin); Vector2 aabbTopLeft = new Vector2(boundingRect.xMin, boundingRect.yMax); Vector2 aabbTopRight = new Vector2(boundingRect.xMax, boundingRect.yMax); Vector2 toNortheastDirection = RenderConfig.GetEdgeMidpointXZ(HexDirection.NE).normalized; Vector2 toNorthwestDirection = new Vector2(toNortheastDirection.y, -toNortheastDirection.x).normalized; Vector2 eastPoint, southPoint, westPoint; Geometry2D.ClosestPointsOnTwoLines( aabbBottomRight, toNortheastDirection, aabbTopRight, toNorthwestDirection, out eastPoint, out eastPoint ); Geometry2D.ClosestPointsOnTwoLines( aabbBottomLeft, toNorthwestDirection, aabbBottomRight, toNortheastDirection, out southPoint, out southPoint ); Geometry2D.ClosestPointsOnTwoLines( aabbBottomLeft, toNorthwestDirection, aabbTopLeft, toNortheastDirection, out westPoint, out westPoint ); float southToWestDistance = (southPoint - westPoint).magnitude; float southToEastDistance = (southPoint - eastPoint).magnitude; //Draws the line segments going northeast for (float t = 0; t <= 1f;) { Vector2 start = Vector2.Lerp(southPoint, westPoint, t); toNortheastLines.Add(new FarmLine(start, toNortheastDirection)); HexHash hash = NoiseGenerator.SampleHashGrid(start); t += Mathf.Lerp(RenderConfig.FarmPatchMinWidth, RenderConfig.FarmPatchMaxWidth, hash.A) / southToWestDistance; } //Draws the line segments going northwest for (float t = 0; t <= 1f;) { Vector2 start = Vector2.Lerp(southPoint, eastPoint, t); toNorthwestLines.Add(new FarmLine(start, toNorthwestDirection)); HexHash hash = NoiseGenerator.SampleHashGrid(start); t += Mathf.Lerp(RenderConfig.FarmPatchMinWidth, RenderConfig.FarmPatchMaxWidth, hash.A) / southToEastDistance; } }
private void TriangulateCultureCorners_FlatEdge( IHexCell center, IHexCell left, IHexCell right, IHexCell nextRight, HexDirection direction, ICivilization centerOwner, ReadOnlyCollection <Vector2> centerRightContour, ReadOnlyCollection <Vector2> rightCenterContour, IHexMesh cultureMesh ) { if (left != null && CivTerritoryLogic.GetCivClaimingCell(left) != centerOwner) { Color cultureColor = centerOwner.Template.Color; var centerLeftContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction.Previous()); var rightLeftContour = CellEdgeContourCanon.GetContourForCellEdge(right, direction.Previous2()); Vector2 centerLeftFirstInner = Vector2.Lerp(centerLeftContour.First(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); Vector2 centerLeftLastInner = Vector2.Lerp(centerLeftContour.Last(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); Vector2 rightLeftFirstInner = Vector2.Lerp(rightLeftContour.First(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); Vector2 rightleftLastInner = Vector2.Lerp(rightLeftContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); Vector2 rayAlongCenterLeft = (centerLeftLastInner - centerLeftFirstInner).normalized; Vector2 rayAlongRightLeft = (rightLeftFirstInner - rightleftLastInner).normalized; Vector2 bezierControl; if (!Geometry2D.ClosestPointsOnTwoLines( centerLeftLastInner, rayAlongCenterLeft, rightLeftFirstInner, rayAlongRightLeft, out bezierControl, out bezierControl )) { Debug.LogError("TriangulateCultureCorners_FlatEdge failed to find a valid control point"); return; } Vector3 pivotXYZ = new Vector3(centerLeftContour.Last().x, 0f, centerLeftContour.Last().y); float paramDelta = 5f / RenderConfig.RiverQuadsPerCurve; for (float t = 0; t < 1f; t = Mathf.Clamp01(t + paramDelta)) { float nextT = Mathf.Clamp01(t + paramDelta); Vector2 bezierOne = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, nextT); Vector2 bezierTwo = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, t); cultureMesh.AddTriangle(pivotXYZ, new Vector3(bezierOne.x, 0f, bezierOne.y), new Vector3(bezierTwo.x, 0f, bezierTwo.y)); cultureMesh.AddTriangleUV(new Vector2(0f, 1f), Vector2.zero, Vector2.zero); cultureMesh.AddTriangleColor(cultureColor); } if (rightCenterContour.Count == 3) { Vector2 innerPoint = Vector2.Lerp(rightCenterContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); Vector2 secondToLastContour = rightCenterContour[rightCenterContour.Count - 2]; Vector2 lastContour = rightCenterContour.Last(); cultureMesh.AddTriangle( new Vector3(innerPoint.x, 0f, innerPoint.y), new Vector3(secondToLastContour.x, 0f, secondToLastContour.y), new Vector3(lastContour.x, 0f, lastContour.y) ); cultureMesh.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f)); cultureMesh.AddTriangleColor(cultureColor); } } }