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