private void RenderSpline(BezierSpline spline, IHexMesh mesh) { if (spline == null) { return; } float delta = 1f / RenderConfig.RoadQuadsPerCurve; float v1, v2 = 0; Vector3 lowerLeft, lowerRight, upperLeft, upperRight; for (float t = 0f; t < 1f; t += delta) { lowerLeft = spline.GetPoint(t) + spline.GetNormalXZ(t).normalized *RenderConfig.RoadWidth / 2f; lowerRight = spline.GetPoint(t) - spline.GetNormalXZ(t).normalized *RenderConfig.RoadWidth / 2f; upperLeft = spline.GetPoint(t + delta) + spline.GetNormalXZ(t + delta).normalized *RenderConfig.RoadWidth / 2f; upperRight = spline.GetPoint(t + delta) - spline.GetNormalXZ(t + delta).normalized *RenderConfig.RoadWidth / 2f; v1 = v2; v2 += (lowerLeft - lowerRight).magnitude / RenderConfig.RoadVRepeatLength; mesh.AddQuad(lowerLeft, lowerRight, upperLeft, upperRight); mesh.AddQuadUV(0f, 1f, v1, v2); } }
public void TriangulateRoads(IHexCell cell, IHexMesh roadsMesh) { if (cell.HasRoads) { var cellHash = NoiseGenerator.SampleHashGrid(cell.AbsolutePositionXZ); var directionsWithRoad = EnumUtil.GetValues <HexDirection>().Where( direction => Grid.HasNeighbor(cell, direction) && Grid.GetNeighbor(cell, direction).HasRoads ).ToList(); while (directionsWithRoad.Any()) { var startDirection = directionsWithRoad.First(); directionsWithRoad.Remove(startDirection); BezierSpline spline; if (directionsWithRoad.Any()) { var endDirection = GetBestDirection(startDirection, directionsWithRoad, cellHash); directionsWithRoad.Remove(endDirection); spline = BuildSplineBetween(cell, startDirection, endDirection); } else { spline = BuildSplineToCenter(cell, startDirection); } RenderSpline(spline, roadsMesh); } } }
private void TriangulateCultureAlongContour( IHexCell center, HexDirection direction, Color color, IHexMesh cultureMesh ) { var contour = CellEdgeContourCanon.GetContourForCellEdge(center, direction); Vector2 innerCCW, innerCW, outerCCW, outerCW; for (int i = 0; i < contour.Count - 1; i++) { outerCCW = contour[i]; outerCW = contour[i + 1]; innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); innerCW = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); cultureMesh.AddQuad( new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y), new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y) ); cultureMesh.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f)); cultureMesh.AddQuadColor(color); } }
private void TriangulateMarshCenter(IHexCell center, HexDirection direction, IHexMesh mesh) { mesh.AddTriangle( center.AbsolutePosition, center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction), center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction) ); mesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one); }
public void Destroy(IHexMesh mesh) { allMeshes.Remove(mesh); var concreteMesh = mesh as HexMesh; if (concreteMesh != null) { HexMeshPool.Despawn(concreteMesh); } }
private void TriangulateWaterCenter( IHexCell center, IHexMesh mesh, HexDirection direction, Vector3 localCell, Color centerColor ) { mesh.AddTriangle( localCell, localCell + RenderConfig.GetFirstSolidCorner(direction), localCell + RenderConfig.GetSecondSolidCorner(direction) ); mesh.AddTriangleColor(centerColor); }
private void TriangulateMarshCorner( IHexCell center, IHexCell left, IHexCell right, float centerV, float leftV, float rightV, HexDirection direction, IHexMesh mesh ) { Vector3 centerPoint = center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction); Vector3 leftPoint = left.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Next2()); Vector3 rightPoint = right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Previous2()); mesh.AddTriangle(centerPoint, leftPoint, rightPoint); mesh.AddTriangleUV(new Vector2(0f, centerV), new Vector2(0f, leftV), new Vector2(0f, rightV)); }
public void TrianglateOasis(IHexCell cell, IHexMesh waterMesh, IHexMesh landMesh) { if (cell.Feature != CellFeature.Oasis) { return; } float waterDistance = RenderConfig.OasisWaterRadius; float landDistance = RenderConfig.OasisWaterRadius + RenderConfig.OasisLandWidth; float tDelta = 2 * Mathf.PI / RenderConfig.OasisBoundarySegments; Vector3 perturbedCenter = NoiseGenerator.Perturb(cell.AbsolutePosition); Vector3 waterTwo = NoiseGenerator.Perturb( cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f) ); Vector3 landTwo = NoiseGenerator.Perturb( cell.AbsolutePosition + new Vector3(landDistance, 0f, 0f) ); for (float t = 0f; t < 2 * Mathf.PI; t += tDelta) { Vector3 waterOne = waterTwo; Vector3 landOne = landTwo; waterTwo = NoiseGenerator.Perturb( cell.AbsolutePosition + new Vector3(waterDistance * Mathf.Cos(t), 0f, waterDistance * Mathf.Sin(t)) ); landTwo = NoiseGenerator.Perturb( cell.AbsolutePosition + new Vector3(landDistance * Mathf.Cos(t), 0f, landDistance * Mathf.Sin(t)) ); waterMesh.AddTriangle(perturbedCenter, waterTwo, waterOne); waterMesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one); landMesh.AddQuad(waterTwo, waterOne, landTwo, landOne); } waterMesh.AddTriangle( perturbedCenter, NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f)), waterTwo ); landMesh.AddQuad( NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f)), waterTwo, NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(landDistance, 0f, 0f)), landTwo ); waterMesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one); }
private void ClearHexMeshes() { if (standingWater != null) { standingWater.Clear(); HexMeshFactory.Destroy(standingWater); standingWater = null; } if (culture != null) { culture.Clear(); HexMeshFactory.Destroy(culture); culture = null; } if (roads != null) { roads.Clear(); HexMeshFactory.Destroy(roads); roads = null; } if (marshWater != null) { marshWater.Clear(); HexMeshFactory.Destroy(marshWater); marshWater = null; } if (oasisWater != null) { oasisWater.Clear(); HexMeshFactory.Destroy(oasisWater); oasisWater = null; } if (oasisLand != null) { oasisLand.Clear(); HexMeshFactory.Destroy(oasisLand); oasisLand = null; } }
private void TriangulateWaterEdge( IHexCell center, Vector3 localCenterPos, Color centerColor, IHexCell right, Vector3 localRightPos, Color rightColor, HexDirection direction, IHexMesh mesh ) { mesh.AddQuad( localCenterPos + RenderConfig.GetFirstSolidCorner(direction), localCenterPos + RenderConfig.GetSecondSolidCorner(direction), localRightPos + RenderConfig.GetSecondSolidCorner(direction.Opposite()), localRightPos + RenderConfig.GetFirstSolidCorner(direction.Opposite()) ); mesh.AddQuadColor(centerColor, rightColor); }
private void TriangulateWaterCorner( IHexCell center, Vector3 localCenterPos, Color centerColor, IHexCell right, Vector3 localRightPos, Color rightColor, IHexCell left, Vector3 localLeftPos, Color leftColor, HexDirection direction, IHexMesh mesh ) { mesh.AddTriangle( localCenterPos + RenderConfig.GetFirstSolidCorner(direction), localLeftPos + RenderConfig.GetFirstSolidCorner(direction.Next2()), localRightPos + RenderConfig.GetFirstSolidCorner(direction.Previous2()) ); mesh.AddTriangleColor(centerColor, leftColor, rightColor); }
public void TriangulateMarshes(IHexCell center, IHexMesh mesh) { foreach (var direction in EnumUtil.GetValues <HexDirection>()) { if (center.Vegetation == CellVegetation.Marsh) { TriangulateMarshCenter(center, direction, mesh); } if (direction > HexDirection.SE) { continue; } IHexCell right = Grid.GetNeighbor(center, direction); IHexCell left = Grid.GetNeighbor(center, direction.Previous()); if (right == null) { continue; } float centerV = center.Vegetation == CellVegetation.Marsh ? 1f : 0f; float leftV = left != null && left.Vegetation == CellVegetation.Marsh ? 1f : 0f; float rightV = right != null && right.Vegetation == CellVegetation.Marsh ? 1f : 0f; if (centerV != 0f || rightV != 0f) { TriangulateMarshEdge(center, right, centerV, rightV, direction, mesh); } if (direction > HexDirection.E) { continue; } if (left == null) { continue; } if (centerV != 0f || leftV != 0f || rightV != 0f) { TriangulateMarshCorner(center, left, right, centerV, leftV, rightV, direction, mesh); } } }
public void TriangulateCellWeights(IHexCell center, IHexMesh weightsMesh) { foreach (var direction in EnumUtil.GetValues <HexDirection>()) { bool hasCenterRightRiver = RiverCanon.HasRiverAlongEdge(center, direction); IHexCell right = Grid.GetNeighbor(center, direction); if (hasCenterRightRiver) { TriangulateCellWeights_River(center, right, direction, hasCenterRightRiver, weightsMesh); } else { TriangulateCellWeights_NoRiver(center, right, direction, weightsMesh); } } }
public void TriangulateCultureInDirection( IHexCell center, HexDirection direction, IHexMesh cultureMesh ) { var centerOwner = CivTerritoryLogic.GetCivClaimingCell(center); if (centerOwner == null) { return; } IHexCell left = Grid.GetNeighbor(center, direction.Previous()); IHexCell right = Grid.GetNeighbor(center, direction); IHexCell nextRight = Grid.GetNeighbor(center, direction.Next()); if (right == null) { return; } if (CivTerritoryLogic.GetCivClaimingCell(right) != centerOwner) { TriangulateCultureAlongContour(center, direction, centerOwner.Template.Color, cultureMesh); } else { var centerRightContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction); var rightCenterContour = CellEdgeContourCanon.GetContourForCellEdge(right, direction.Opposite()); if (rightCenterContour.Count <= 3) { TriangulateCultureCorners_FlatEdge( center, left, right, nextRight, direction, centerOwner, centerRightContour, rightCenterContour, cultureMesh ); } else { TriangulateCultureCorners_River( center, left, right, nextRight, direction, centerOwner, centerRightContour, cultureMesh ); } } }
public void Clear() { if (cells == null || cells.Count == 0) { return; } CellSignals.MapBeingClearedSignal.OnNext(new UniRx.Unit()); cells.Clear(); foreach (var chunk in chunks) { MapChunkPool.Despawn(chunk); } chunks = null; castChunks = null; if (RiverSurfaceMesh != null) { HexMeshFactory.Destroy(RiverSurfaceMesh); } if (RiverBankMesh != null) { HexMeshFactory.Destroy(RiverBankMesh); } if (RiverDuckMesh != null) { HexMeshFactory.Destroy(RiverDuckMesh); } if (FarmMesh != null) { HexMeshFactory.Destroy(FarmMesh); } RiverSurfaceMesh = null; RiverBankMesh = null; RiverDuckMesh = null; FarmMesh = null; }
private void TriangulateCellWeights_NoRiver( IHexCell center, IHexCell right, HexDirection direction, IHexMesh weightsMesh ) { if (right == null) { weightsMesh.AddTriangle( center.AbsolutePosition, center.AbsolutePosition + RenderConfig.GetFirstCorner(direction), center.AbsolutePosition + RenderConfig.GetSecondCorner(direction) ); weightsMesh.AddTriangleColor(CenterWeights); return; } Vector3 firstEdgeInner = center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction); Vector3 secondEdgeInner = center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction); //Solid center region weightsMesh.AddTriangle(center.AbsolutePosition, firstEdgeInner, secondEdgeInner); weightsMesh.AddTriangleColor(CenterWeights); Vector3 firstEdgeOuter = (firstEdgeInner + right.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction.Opposite())) / 2f; Vector3 secondEdgeOuter = (secondEdgeInner + right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Opposite())) / 2f; //The edge between Center and Right, going up to the dividing line weightsMesh.AddQuad(firstEdgeInner, secondEdgeInner, firstEdgeOuter, secondEdgeOuter); weightsMesh.AddQuadColor(CenterWeights, CenterRightWeights); //Previous corner out to the edge of the cell weightsMesh.AddTriangle(firstEdgeInner, center.AbsolutePosition + RenderConfig.GetFirstCorner(direction), firstEdgeOuter); weightsMesh.AddTriangleColor(CenterWeights, CenterLeftRightWeights, CenterRightWeights); //Next corner out to the edge of the cell weightsMesh.AddTriangle(secondEdgeInner, secondEdgeOuter, center.AbsolutePosition + RenderConfig.GetSecondCorner(direction)); weightsMesh.AddTriangleColor(CenterWeights, CenterRightWeights, CenterRightNextRightWeights); }
public void Build(int cellCountX, int cellCountZ) { RiverSurfaceMesh = HexMeshFactory.Create("River Surfaces", RenderConfig.RiverSurfaceData); RiverBankMesh = HexMeshFactory.Create("River Banks", RenderConfig.RiverBankData); RiverDuckMesh = HexMeshFactory.Create("River Ducking", RenderConfig.RiverDuckData); FarmMesh = HexMeshFactory.Create("Farmland", RenderConfig.FarmlandData); RiverSurfaceMesh.transform.SetParent(transform, false); RiverBankMesh.transform.SetParent(transform, false); RiverDuckMesh.transform.SetParent(transform, false); FarmMesh.transform.SetParent(transform, false); Clear(); CellCountX = cellCountX; CellCountZ = cellCountZ; ShaderData.Initialize(CellCountX, CellCountZ); CreateCells(); CreateChunks(); AttachChunksToCells(); }
public void TriangulateOrientation(IHexCell center, IHexMesh orientationMesh) { short indexOffset = (short)(center.Index + 1); foreach (var direction in EnumUtil.GetValues <HexDirection>()) { byte[] rg = BitConverter.GetBytes(indexOffset); byte b = (byte)direction; var cellColor = new Color32(rg[0], rg[1], b, 0); var centerContour = CellContourCanon.GetContourForCellEdge(center, direction); for (int i = 1; i < centerContour.Count; i++) { orientationMesh.AddTriangle( center.AbsolutePosition, centerContour[i - 1].ToXYZ(), centerContour[i].ToXYZ() ); orientationMesh.AddTriangleColor(cellColor); } if (direction <= HexDirection.SE && RiverCanon.HasRiverAlongEdge(center, direction)) { var right = Grid.GetNeighbor(center, direction); ContourTriangulator.TriangulateContoursBetween( center, right, direction, cellColor, cellColor, orientationMesh ); if (direction <= HexDirection.E && RiverCanon.HasRiverAlongEdge(right, direction.Previous2())) { } } } }
//Center should always be a water cell of some variety. //We need to extend water borders into land cells to make //sure the water goes all the way up to the shore. public void TriangulateWaterForCell(IHexCell center, Transform localTransform, IHexMesh mesh) { Vector3 localCenterPos = localTransform.InverseTransformPoint(center.AbsolutePosition); localCenterPos.y = RenderConfig.WaterY; foreach (var direction in EnumUtil.GetValues <HexDirection>()) { Color centerColor, leftColor, rightColor; GetWaterColors(center, direction, out centerColor, out leftColor, out rightColor); TriangulateWaterCenter(center, mesh, direction, localCenterPos, centerColor); var right = Grid.GetNeighbor(center, direction); if (right == null || (right.Terrain.IsWater() && direction > HexDirection.SE)) { continue; } Vector3 localRightPos = localTransform.InverseTransformPoint(right.AbsolutePosition); localRightPos.y = RenderConfig.WaterY; if (center.Terrain.IsWater()) { TriangulateWaterEdge( center, localCenterPos, centerColor, right, localRightPos, rightColor, direction, mesh ); } else if (right.Terrain.IsWater()) { TriangulateWaterEdge( right, localRightPos, rightColor, center, localCenterPos, centerColor, direction.Opposite(), mesh ); } var left = Grid.GetNeighbor(center, direction.Previous()); //We can't use the normal paradigm for corners because //we aren't triangulating from every cell. We need to //triangulate every land corner, and then exclude water //corners, which this check does. if (left == null || (right.Terrain.IsWater() && direction > HexDirection.E) || (left.Terrain.IsWater() && direction > HexDirection.SW) ) { continue; } Vector3 localLeftPos = localTransform.InverseTransformPoint(left.AbsolutePosition); localLeftPos.y = RenderConfig.WaterY; TriangulateWaterCorner( center, localCenterPos, centerColor, right, localRightPos, rightColor, left, localLeftPos, leftColor, direction, mesh ); } }
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); } } }
private void TriangulateCellWeights_River( IHexCell center, IHexCell right, HexDirection direction, bool hasCenterRightRiver, IHexMesh weightsMesh ) { var centerRightContour = CellContourCanon.GetContourForCellEdge(center, direction); Vector3 innerOne, innerTwo, contourOneXYZ, contourTwoXYZ; for (int i = 1; i < centerRightContour.Count; i++) { contourOneXYZ = centerRightContour[i - 1].ToXYZ(); contourTwoXYZ = centerRightContour[i].ToXYZ(); innerOne = Vector3.Lerp(center.AbsolutePosition, contourOneXYZ, RenderConfig.SolidFactor); innerTwo = Vector3.Lerp(center.AbsolutePosition, contourTwoXYZ, RenderConfig.SolidFactor); weightsMesh.AddTriangle(center.AbsolutePosition, innerOne, innerTwo); weightsMesh.AddTriangleColor(CenterWeights); weightsMesh.AddQuad(innerOne, innerTwo, contourOneXYZ, contourTwoXYZ); if (hasCenterRightRiver) { weightsMesh.AddQuadColor(CenterWeights); } else { weightsMesh.AddQuadColor(CenterWeights, CenterRightWeights); } } if (hasCenterRightRiver && direction <= HexDirection.SE) { ContourTriangulator.TriangulateContoursBetween( center, right, direction, CenterWeights, RightWeights, weightsMesh ); } }
public void TriangulateContoursBetween( IHexCell center, IHexCell right, HexDirection direction, Color centerWeights, Color rightWeights, IHexMesh mesh ) { var centerRightContour = CellContourCanon.GetContourForCellEdge(center, direction); var rightCenterContour = CellContourCanon.GetContourForCellEdge(right, direction.Opposite()); int centerRightIndex = 1, rightCenterIndex = rightCenterContour.Count - 1; while (centerRightIndex < centerRightContour.Count && rightCenterIndex > 0) { mesh.AddQuad( centerRightContour[centerRightIndex - 1].ToXYZ(), centerRightContour[centerRightIndex].ToXYZ(), rightCenterContour[rightCenterIndex].ToXYZ(), rightCenterContour[rightCenterIndex - 1].ToXYZ() ); mesh.AddQuadColor(centerWeights, rightWeights); centerRightIndex++; rightCenterIndex--; } for (; centerRightIndex < centerRightContour.Count; centerRightIndex++) { mesh.AddTriangle( centerRightContour[centerRightIndex - 1].ToXYZ(), rightCenterContour[0].ToXYZ(), centerRightContour[centerRightIndex].ToXYZ() ); mesh.AddTriangleColor(centerWeights, rightWeights, centerWeights); } for (; rightCenterIndex > 0; rightCenterIndex--) { mesh.AddTriangle( centerRightContour.Last().ToXYZ(), rightCenterContour[rightCenterIndex].ToXYZ(), rightCenterContour[rightCenterIndex - 1].ToXYZ() ); mesh.AddTriangleColor(centerWeights, rightWeights, rightWeights); } if (RiverCanon.HasRiverAlongEdge(right, direction.Next2())) { var nextRight = Grid.GetNeighbor(center, direction.Next()); var rightNextRightContour = CellContourCanon.GetContourForCellEdge(right, direction.Next2()); var nextRightRightContour = CellContourCanon.GetContourForCellEdge(nextRight, direction.Previous()); mesh.AddTriangle( centerRightContour.Last().ToXYZ(), rightNextRightContour.Last().ToXYZ(), nextRightRightContour.First().ToXYZ() ); mesh.AddTriangleColor(centerWeights, rightWeights, rightWeights); } }
private void TriangulateMarshEdge( IHexCell center, IHexCell right, float centerV, float rightV, HexDirection direction, IHexMesh mesh ) { mesh.AddQuad( center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction), center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction), right.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction.Opposite()), right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Opposite()) ); mesh.AddQuadUV(0f, 0f, centerV, rightV); }
private void TriangulateCultureCorners_River( IHexCell center, IHexCell left, IHexCell right, IHexCell nextRight, HexDirection direction, ICivilization centerOwner, ReadOnlyCollection <Vector2> centerRightContour, IHexMesh cultureMesh ) { Color cultureColor = centerOwner.Template.Color; if (left != null && CivTerritoryLogic.GetCivClaimingCell(left) != centerOwner) { float ccwTransparency = 1f, cwTransparency; Vector2 innerCCW, innerCW, outerCCW, outerCW; float cultureWidth = (centerRightContour.First() - center.AbsolutePositionXZ).magnitude * RenderConfig.CultureWidthPercent; int i = 0; do { outerCCW = centerRightContour[i]; outerCW = centerRightContour[i + 1]; float distanceFromStart = (centerRightContour.First() - outerCW).magnitude; cwTransparency = Mathf.Clamp01(1f - distanceFromStart / cultureWidth); innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); innerCW = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); cultureMesh.AddQuad( new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y), new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y) ); cultureMesh.AddQuadUV( new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, ccwTransparency), new Vector2(0f, cwTransparency) ); cultureMesh.AddQuadColor(cultureColor); ccwTransparency = cwTransparency; i++; } while(cwTransparency > 0f && i < centerRightContour.Count - 1); } if (nextRight != null && CivTerritoryLogic.GetCivClaimingCell(nextRight) != centerOwner) { float cwTransparency = 1f, ccwTransparency; Vector2 innerCCW, innerCW, outerCCW, outerCW; float cultureWidth = (centerRightContour.Last() - center.AbsolutePositionXZ).magnitude * RenderConfig.CultureWidthPercent; int i = centerRightContour.Count - 1; do { outerCCW = centerRightContour[i - 1]; outerCW = centerRightContour[i]; float distanceFromStart = (centerRightContour.Last() - outerCCW).magnitude; ccwTransparency = Mathf.Clamp01(1f - distanceFromStart / cultureWidth); innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); innerCW = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent); cultureMesh.AddQuad( new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y), new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y) ); cultureMesh.AddQuadUV( new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, ccwTransparency), new Vector2(0f, cwTransparency) ); cultureMesh.AddQuadColor(cultureColor); cwTransparency = ccwTransparency; i--; }while(ccwTransparency > 0f && i > 0); } }