protected LandLayout(ILandSettings settings) { Bounds = settings.LandBounds; Settings = settings; var points = GeneratePoints(settings.ZonesCount, Bounds, settings.ZonesDensity); var cells = CellMeshGenerator.Generate(points, (Bounds)Bounds); var zonesType = SetZoneTypes(cells, settings); var zones = new ZoneLayout[points.Length]; for (int i = 0; i < zones.Length; i++) { zones[i] = new ZoneLayout(zonesType[i], cells[i]); } Zones = zones; _idwCoeff = settings.IDWCoeff; var zoneMaxType = (int)settings.ZoneTypes.Max(z => z.Type); _influenceLookup = new float[zoneMaxType + 1]; _zoneTypesCount = zones.Where(z => z.Type != ZoneType.Empty).Distinct(ZoneLayout.TypeComparer).Count(); _zoneSettings = settings.ZoneTypes.ToArray(); }
/// <summary> /// Check chunk corners and zone vertices /// </summary> /// <param name="chunkPosition"></param> /// <param name="zone"></param> /// <returns></returns> private bool CheckChunkConservative(Vector2i chunkPosition, ZoneLayout zone) { if (!zone.ChunkBounds.Contains(chunkPosition)) { return(false); } var chunkBounds = Chunk.GetBounds(chunkPosition); var floatBounds = (Bounds)chunkBounds; var chunkCorner1 = Convert(floatBounds.min); var chunkCorner2 = new Vector2(floatBounds.min.x, floatBounds.max.z); var chunkCorner3 = Convert(floatBounds.max); var chunkCorner4 = new Vector2(floatBounds.max.x, floatBounds.min.z); ZoneLayout zone1 = zone, zone2 = zone, zone3 = zone, zone4 = zone; var distanceCorner1 = float.MaxValue; var distanceCorner2 = float.MaxValue; var distanceCorner3 = float.MaxValue; var distanceCorner4 = float.MaxValue; foreach (var z in Zones) { if (Vector2.SqrMagnitude(z.Center - chunkCorner1) < distanceCorner1) { zone1 = z; distanceCorner1 = Vector2.SqrMagnitude(z.Center - chunkCorner1); } if (Vector2.SqrMagnitude(z.Center - chunkCorner2) < distanceCorner2) { zone2 = z; distanceCorner2 = Vector2.SqrMagnitude(z.Center - chunkCorner2); } if (Vector2.SqrMagnitude(z.Center - chunkCorner3) < distanceCorner3) { zone3 = z; distanceCorner3 = Vector2.SqrMagnitude(z.Center - chunkCorner3); } if (Vector2.SqrMagnitude(z.Center - chunkCorner4) < distanceCorner4) { zone4 = z; distanceCorner4 = Vector2.SqrMagnitude(z.Center - chunkCorner4); } } if (zone1 == zone || zone2 == zone || zone3 == zone || zone4 == zone) { return(true); } //Check zone vertices in chunk foreach (var vert in zone.Cell.Vertices) { if (floatBounds.Contains(Convert(vert))) { return(true); } } return(false); }
/// <summary> /// Get all chunks of zone /// </summary> /// <returns></returns> public IEnumerable <Vector2i> GetChunks(ZoneLayout zone) { var centerChunk = Chunk.GetPosition(zone.Center); var result = new List <Vector2i>(); var processed = new List <Vector2i>(); GetChunksFloodFill(zone, centerChunk, processed, result); return(result); }
public ZoneLayout(ZoneType type, Cell cell) { Cell = cell; Center = cell.Center; Type = type; Bounds = (Bounds2i)cell.Bounds; ChunkBounds = new Bounds2i(Chunk.GetPosition(Bounds.Min), Chunk.GetPosition(Bounds.Max)); _neighbors = new ZoneLayout[0]; }
private void GetChunksFloodFill(ZoneLayout zone, Vector2i from, List <Vector2i> processed, List <Vector2i> result) { if (!processed.Contains(@from)) { processed.Add(from); if (CheckChunkConservative(from, zone)) { result.Add(from); GetChunksFloodFill(zone, from + Vector2i.Forward, processed, result); GetChunksFloodFill(zone, from + Vector2i.Back, processed, result); GetChunksFloodFill(zone, from + Vector2i.Left, processed, result); GetChunksFloodFill(zone, from + Vector2i.Right, processed, result); } } }