예제 #1
0
        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();
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
 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];
 }
예제 #5
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);
                }
            }
        }