Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Threading.Tasks;
- using UnityEngine;
- public class HexagonalGrid : List<GridTile>
- {
- public int GridSize { get; private set; }
- public int TileCount { get; private set; }
- public WorldGenerator World { get; private set; }
- public HexagonalGrid(WorldGenerator Generator, float[,] HeightMap, float[,] TemperatureMap, float[,] HumidityMap, float cullRange)
- {
- this.GridSize = Generator.MapSize;
- this.TileCount = Generator.TileCount;
- this.World = Generator;
- // GENERATE GRID TILES
- Clear();
- int maxX = Mathf.FloorToInt(TileCount * 0.7f);
- for (int x = 0; x < maxX; x++)
- {
- for (int y = 0; y < TileCount * 2 + 2; y++)
- {
- if (y % 2 != 0)
- {
- if (x == maxX - 1) continue;
- }
- GridTile tile = new GridTile(this, new Point(x, y), HeightMap, TemperatureMap, HumidityMap, cullRange);
- Add(tile);
- }
- }
- }
- public GridTile GetTile(Vector2Int Point)
- {
- GridTile result = null;
- object locker = new object();
- Parallel.ForEach(this, (tile, state) => {
- if (tile.IsContaining(Point))
- {
- lock (locker) { result = tile; }
- state.Stop();
- }
- });
- return result;
- }
- public GridTile GetCullingTile(Vector2Int Pixel)
- {
- GridTile result = null;
- object locker = new object();
- Parallel.ForEach(this, (tile, state) => {
- if(tile.IsCullContaining(Pixel))
- {
- lock (locker) { result = tile; }
- state.Stop();
- }
- });
- return result;
- }
- private GridTile selectedTile;
- public void SelectTile(GridTile Tile)
- {
- if (selectedTile != null) selectedTile.GridLineObject.GetComponent<LineRenderer>().widthMultiplier = World.GridWidthMultiplier;
- Tile.GridLineObject.GetComponent<LineRenderer>().widthMultiplier = 1f;
- selectedTile = Tile;
- }
- }
- public class GridTile
- {
- public Point Position { get; private set; }
- public Vector2 Center { get; private set; }
- public Vector3[] Points { get; private set; }
- public Point[] FillingPixels { get; private set; }
- public Point[] CulledPixels { get; private set; }
- public GameObject GridLineObject;
- public List<GameObject> CulledDetail = new List<GameObject>();
- public float Height { get; private set; }
- public float Temperature { get; private set; }
- public float Humidity { get; private set; }
- public int BiomeIndex { get; private set; }
- public int HeightIndex { get; private set; }
- private HexagonalGrid grid;
- private float hexSize;
- public GridTile(HexagonalGrid Parent, Point Position, float[,] HeightMap, float[,] TemperatureMap, float[,] HumidityMap, float cullRange)
- {
- grid = Parent;
- this.Position = Position;
- // CALCULATE POSITION AND SIZE
- float tileSize = (float)grid.GridSize / grid.TileCount;
- hexSize = tileSize / 2f;
- float height = Mathf.Sqrt(3) * hexSize;
- float centerX = 0;
- float centerY = 0;
- if(Position.Y == 0 || Position.Y % 2 == 0)
- {
- centerX = (tileSize * Position.X) + (hexSize * Position.X) + hexSize;
- centerY = (height / 2 * Position.Y) + hexSize;
- }
- else
- {
- centerX = (tileSize * Position.X) + (hexSize * Position.X) + tileSize + (hexSize / 2);
- centerY = (height / 2 * Position.Y) + hexSize;
- }
- Center = new Vector2(centerX, centerY);
- Points = generatePoints(hexSize, HeightMap);
- FillingPixels = generateFillingPixels(Points);
- if(cullRange != 0f)
- {
- float culledHexA = hexSize * cullRange;
- Vector3[] culledPoints = generatePoints(culledHexA, HeightMap);
- CulledPixels = generateFillingPixels(culledPoints);
- }
- // ASSIGN HEIGHT, HUMIDITY, TEMPERATURE, BIOME
- float avrHeight = 0;
- float avrTemp = 0;
- float avrHum = 0;
- foreach(Point point in FillingPixels)
- {
- if (point.X < 0 || point.Y < 0 || point.X >= HeightMap.GetLength(0) || point.Y >= HeightMap.GetLength(1)) continue;
- avrHeight += HeightMap[point.X, point.Y];
- avrTemp += TemperatureMap[point.X, point.Y];
- avrHum += HumidityMap[point.X, point.Y];
- }
- Height = avrHeight / FillingPixels.GetLength(0);
- Temperature = avrTemp / FillingPixels.GetLength(0);
- Humidity = avrHum / FillingPixels.GetLength(0);
- BiomeIndex = BiomeData.GetBiomeIndex(grid.World.Biomes, Height, Temperature, Humidity);
- HeightIndex = HeightInfo.GetHeightIndex(grid.World.Heights, Height);
- }
- private Vector3[] generatePoints(float Size, float[,] heightMap)
- {
- Vector3[] result = new Vector3[6];
- //PointHeights = new float[6];
- float lastHeight = 0;
- for(int i = 0; i < 6; i++)
- {
- Vector2 point = Utils.HexCorner(Center, Size, i);
- float height = lastHeight;
- //Points[i] = Utils.HexCorner(Center, Size, i);
- //float height = 0;
- if (point.x > 0 && point.y > 0 && point.x < heightMap.GetLength(0) && point.y < heightMap.GetLength(1))
- {
- height = heightMap[(int)point.x, (int)point.y];
- }
- result[i] = new Vector3(point.x, height, point.y);
- lastHeight = height;
- //PointHeights[i] = height;
- }
- return result;
- }
- private Point[] generateFillingPixels(Vector3[] points)
- {
- List<Point> pixels = new List<Point>();
- // GENERATE SIDE PIXEL POSITIONS
- for (int i = 0; i < 6; i++)
- {
- int pointB = i == 5 ? 0 : i + 1;
- Point p1 = new Point(Mathf.RoundToInt(points[i].x), Mathf.RoundToInt(points[i].z));
- Point p2 = new Point(Mathf.RoundToInt(points[pointB].x), Mathf.RoundToInt(points[pointB].z));
- pixels.AddRange(Utils.GetLinePixels(p1, p2).ToArray());
- }
- // FILL HEX
- List<Point> samplePoints = new List<Point>();
- samplePoints.Add(new Point(Mathf.RoundToInt(Center.x), Mathf.RoundToInt(Center.y)));
- while (samplePoints.Count > 0)
- {
- Point[] curSamplePoints = samplePoints.ToArray();
- samplePoints.Clear();
- foreach (Point sPoint in curSamplePoints)
- {
- for (int x = -1; x < 2; x++)
- {
- for (int y = -1; y < 2; y++)
- {
- if (x == 0 && y == 0) continue; // Ignored point
- if (x == -1 && y == -1) continue; // Ignored point
- if (x == 1 && y == 1) continue; // Ignored point
- if (x == 1 && y == -1) continue; // Ignored point
- if (x == -1 && y == 1) continue; // Ignored point
- Point curPoint = new Point(sPoint.X + x, sPoint.Y + y);
- if (curPoint.X < 0 || curPoint.Y < 0 || curPoint.X >= grid.GridSize || curPoint.Y >= grid.GridSize) continue; // Outside Bounds
- if (!pixels.Exists(pixel => pixel.X == curPoint.X && pixel.Y == curPoint.Y))
- {
- pixels.Add(curPoint);
- samplePoints.Add(curPoint);
- }
- }
- }
- }
- }
- return pixels.ToArray();
- }
- public bool IsContaining(Vector2Int Point)
- {
- foreach (Point p in FillingPixels)
- {
- if (p.X == Point.x && p.Y == Point.y) return true;
- }
- return false;
- }
- public bool IsCullContaining(Vector2Int Point)
- {
- foreach(Point p in CulledPixels)
- {
- if (p.X == Point.x && p.Y == Point.y) return true;
- }
- return false;
- }
- }
- public static class Utils
- {
- public static Vector2 HexCorner(Vector2 center, float size, int i)
- {
- float angle_deg = 60 * i - 0;
- float angle_rad = Mathf.PI / 180 * angle_deg;
- return new Vector2(center.x + size * Mathf.Cos(angle_rad), center.y + size * Mathf.Sin(angle_rad));
- }
- public static List<Point> GetLinePixels(Point a, Point b)
- {
- List<Point> result = new List<Point>();
- int w = b.X - a.X;
- int h = b.Y - a.Y;
- int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
- if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1;
- if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1;
- if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1;
- int longest = Mathf.Abs(w);
- int shortest = Mathf.Abs(h);
- if (!(longest > shortest))
- {
- longest = Mathf.Abs(h);
- shortest = Mathf.Abs(w);
- if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
- dx2 = 0;
- }
- int numerator = longest >> 1;
- for (int i = 0; i <= longest; i++)
- {
- result.Add(a);
- //putpixel(x, y, color);
- numerator += shortest;
- if (!(numerator < longest))
- {
- numerator -= longest;
- a.X += dx1;
- a.Y += dy1;
- }
- else
- {
- a.X += dx2;
- a.Y += dy2;
- }
- }
- return result;
- }
- //public static List<Point> GetLinePixels(Point a, Point b)
- //{
- // List<Point> result = new List<Point>();
- // //Point a = new Point(Mathf.RoundToInt(PointA.x), Mathf.RoundToInt(PointA.y));
- // //Point b = new Point(Mathf.RoundToInt(PointB.x), Mathf.RoundToInt(PointB.y));
- // int dx = Mathf.Abs(b.X - a.X), sx = a.X < b.X ? 1 : -1;
- // int dy = Mathf.Abs(b.Y - a.Y), sy = a.Y < b.Y ? 1 : -1;
- // int err = (dx > dy ? dx : -dy) / 2, e2;
- // for (; ; )
- // {
- // result.Add(new Point(a.X, a.Y));
- // if (a.X == b.Y && a.X == b.Y) break;
- // e2 = err;
- // if (e2 > -dx) { err -= dy; a.X += sx; }
- // if (e2 < dy) { err += dx; a.Y += sy; }
- // }
- // return result;
- //}
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement