Esempio n. 1
0
        /// <summary>
        /// Gets the chunk indices within the given bounds.
        /// </summary>
        /// <param name="bounds">The bounds.</param>
        /// <returns>The chunk indices.</returns>
        public static Vector2I[] GetChunks(RectangleI bounds)
        {
            var chunks = new Vector2I[bounds.Width * bounds.Height];

            int i = 0;
            for (int x = bounds.X; x < bounds.X + bounds.Width; x++)
            {
                for (int y = bounds.Y; y > bounds.Y - bounds.Height; y--)
                {
                    chunks[i++] = new Vector2I(x, y);
                }
            }

            return chunks;
        }
Esempio n. 2
0
        /// <summary>
        /// Dig a circle in the terrain with the given origin and radius.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="radius">The radius.</param>
        public void DigCircle(Vector2 origin, float radius)
        {
            Vector2I originI = new Vector2I((int)Math.Round(origin.x), (int)Math.Round(origin.y));
            int radiusI = (int)radius;
            Vector2I chunk = Metrics.ChunkIndex(originI.X, originI.Y);

            // Get the affected chunks
            var worldBounds = new RectangleI(
                (int)(origin.x - radius - 0.5f) - 1,
                (int)(origin.y + radius + 0.5f) + 1,
                (int)((radius * 2) + 0.5f) + 3,
                (int)((radius * 2) + 0.5f) + 3);
            RectangleI chunkBounds = Metrics.WorldToChunk(worldBounds);
            Vector2I[] chunks = TerrainChunk.GetChunks(chunkBounds);
            SynchronisedUpdate toSync = chunks.Length > 1 ? new SynchronisedUpdate(chunks) : null;

            // Enqueue the job
            JobSystem.Instance.Scheduler.BeginEnqueueChunks();
            try
            {
                if (JobSystem.Instance.Scheduler.ForAllChunks(
                    chunks,
                    (q) => q.State.CanDigCircle(chunk, originI, radiusI),
                    MissingQueue.Skip))
                {
                    JobSystem.Instance.Scheduler.EnqueueChunks(
                        () => this.DigCircleJob(origin, radius),
                        (q) => q.State.ReserveDigCircle(chunk, originI, radiusI, toSync),
                        (q) => q.State.UnreserveDigCircle(chunk, originI, radiusI),
                        false,
                        chunks);
                }
            }
            finally
            {
                JobSystem.Instance.Scheduler.EndEnqueueChunks();
            }
        }
        /// <summary>
        /// Gets the chunks that are current active.
        /// </summary>
        /// <returns>The active chunks.</returns>
        private HashSet<Vector2I> GetActiveChunks()
        {
            // bool indicates if the chunk is required or if the loading can be deferred to a background thread
            var activeChunks = new HashSet<Vector2I>();

            // Get the bounds within the camera
            RectangleI cameraPointBounds = this.cCameraBounds.GetBounds();
            Vector2I top = Metrics.ChunkIndex(cameraPointBounds.X, cameraPointBounds.Y);
            Vector2I bottom = Metrics.ChunkIndex(cameraPointBounds.Right - 1, cameraPointBounds.Bottom - 1);
            var cameraChunkBounds = new RectangleI(
                top.X - 2 - this.DistanceChunkBeginLoad,
                top.Y + 2 + this.DistanceChunkBeginLoad,
                bottom.X - top.X + 4 + (this.DistanceChunkBeginLoad * 2),
                top.Y - bottom.Y + 4 + (this.DistanceChunkBeginLoad * 2));

            // Add the chunks that the camera is pointing directly at. These are required to be loaded this frame
            this.PopulateActiveChunks(activeChunks, cameraChunkBounds);

            // Add all other chunks which contain significant actors
            foreach (ActorBoundsComponent actor in GameObject.FindObjectsOfType(typeof(ActorBoundsComponent)))
            {
                this.PopulateActiveChunks(activeChunks, Metrics.WorldToChunk(actor.GetBounds()));
            }

            return activeChunks;
        }
 /// <summary>
 /// Adds each chunk within the given world bounds to the given dictionary.
 /// </summary>
 /// <param name="chunks">The dictionary being populated.</param>
 /// <param name="chunkBounds">The bounds in chunk coordinates.</param>
 private void PopulateActiveChunks(HashSet<Vector2I> chunks, RectangleI chunkBounds)
 {
     for (int x = chunkBounds.X; x < chunkBounds.Right; x++)
     {
         for (int y = chunkBounds.Y; y > chunkBounds.Bottom; y--)
         {
             chunks.Add(new Vector2I(x, y));
         }
     }
 }
Esempio n. 5
0
 /// <summary>
 /// Convert the world bounds into chunk bounds.
 /// </summary>
 /// <param name="worldBounds">The bounds.</param>
 /// <returns>The bounds in chunk coordinates</returns>
 public static RectangleI WorldToChunk(RectangleI worldBounds)
 {
     Vector2I top = Metrics.ChunkIndex(worldBounds.X, worldBounds.Y);
     Vector2I bottom = Metrics.ChunkIndex(worldBounds.Right - 1, worldBounds.Bottom - 1);
     return new RectangleI(
         top.X,
         top.Y,
         bottom.X - top.X + 1,
         top.Y - bottom.Y + 1);
 }