Exemplo n.º 1
0
        private bool IsWithinView(ChunkCoordinates chunk, ICamera camera)
        {
            var frustum  = camera.BoundingFrustum;
            var chunkPos = new Vector3(chunk.X * ChunkColumn.ChunkWidth, 0, chunk.Z * ChunkColumn.ChunkDepth);

            if (chunk.DistanceTo(new ChunkCoordinates(camera.Position)) > RenderDistance)
            {
                return(false);
            }

            return(frustum.Intersects(new Microsoft.Xna.Framework.BoundingBox(chunkPos,
                                                                              chunkPos + new Vector3(ChunkColumn.ChunkWidth, MathF.Max(camera.Position.Y + 10f, 256f),
                                                                                                     ChunkColumn.ChunkDepth))));
        }
Exemplo n.º 2
0
        public override void OnTick()
        {
            ChunkCoordinates cur = new ChunkCoordinates(KnownPosition);

            if (cur.DistanceTo(_prevChunkCoordinates) >= 2)
            {
                _prevChunkCoordinates = cur;
                SendChunksForKnownPosition(cur);
            }

            _timeSinceLastKeepAlive++;

            if (Level.GameTick % 20 == 0)
            {
                if (Connection.KeepAliveReady || _timeSinceLastKeepAlive >= 100)
                {
                    Connection.SendKeepAlive();
                    _timeSinceLastKeepAlive = 0;
                }
            }
        }
Exemplo n.º 3
0
        private void ChunkUpdateThread()
        {
            //Environment.ProcessorCount / 2;
            Stopwatch sw = new Stopwatch();

            while (!CancelationToken.IsCancellationRequested)
            {
                int maxThreads = Options.VideoOptions.ChunkThreads;

                var cameraChunkPos = new ChunkCoordinates(new PlayerLocation(_cameraPosition.X, _cameraPosition.Y,
                                                                             _cameraPosition.Z));
                //SpinWait.SpinUntil(() => Interlocked.Read(ref _threadsRunning) < maxThreads);

                foreach (var data in _chunkData.ToArray().Where(x =>
                                                                QuickMath.Abs(cameraChunkPos.DistanceTo(x.Key)) > Options.VideoOptions.RenderDistance))
                {
                    data.Value?.Dispose();
                    _chunkData.TryRemove(data.Key, out _);
                }

                //var cameraChunkPos = new ChunkCoordinates(new PlayerLocation(camera.Position.X, camera.Position.Y,
                //     camera.Position.Z));

                var renderedChunks = Chunks.ToArray().Where(x =>
                {
                    if (Math.Abs(x.Key.DistanceTo(cameraChunkPos)) > Options.VideoOptions.RenderDistance)
                    {
                        return(false);
                    }

                    var chunkPos = new Vector3(x.Key.X * ChunkColumn.ChunkWidth, 0, x.Key.Z * ChunkColumn.ChunkDepth);
                    return(_cameraBoundingFrustum.Intersects(new Microsoft.Xna.Framework.BoundingBox(chunkPos,
                                                                                                     chunkPos + new Vector3(ChunkColumn.ChunkWidth, 256 /*16 * ((x.Value.GetHeighest() >> 4) + 1)*/,
                                                                                                                            ChunkColumn.ChunkDepth))));
                }).ToArray();

                foreach (var c in renderedChunks)
                {
                    if (_chunkData.TryGetValue(c.Key, out var data))
                    {
                        if (_renderedChunks.TryAdd(data))
                        {
                        }
                    }
                }

                foreach (var c in _renderedChunks.ToArray())
                {
                    if (c == null || c.Coordinates == default || !renderedChunks.Any(x => x.Key.Equals(c.Coordinates)))
                    {
                        _renderedChunks.Remove(c);
                    }
                }

                if (Interlocked.Read(ref _threadsRunning) >= maxThreads)
                {
                    continue;
                }


                bool nonInView = false;
                try
                {
                    if (HighestPriority.TryDequeue(out var coords))
                    {
                        if (Math.Abs(cameraChunkPos.DistanceTo(coords)) > Options.VideoOptions.RenderDistance)
                        {
                            if (!Enqueued.Contains(coords))
                            {
                                Enqueued.Add(coords);
                            }
                        }
                        else
                        {
                            Enqueued.Remove(coords);
                            Schedule(coords, WorkItemPriority.Highest);
                        }

                        //Enqueued.Remove(coords);
                    }
                    else if (Enqueued.Count > 0)
                    {
                        //var cc = new ChunkCoordinates(CameraPosition);

                        var where = Enqueued.Where(x => IsWithinView(x, _cameraBoundingFrustum)).ToArray();
                        if (where.Length > 0)
                        {
                            coords = where.MinBy(x => Math.Abs(x.DistanceTo(new ChunkCoordinates(_cameraPosition))));
                        }
                        else
                        {
                            coords = Enqueued.MinBy(x => Math.Abs(x.DistanceTo(new ChunkCoordinates(_cameraPosition))));
                        }

                        if (Math.Abs(cameraChunkPos.DistanceTo(coords)) <= Options.VideoOptions.RenderDistance)
                        {
                            if (!_workItems.ContainsKey(coords))
                            {
                                Schedule(coords, WorkItemPriority.AboveNormal);
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    break;
                }
            }

            if (!CancelationToken.IsCancellationRequested)
            {
                Log.Warn($"Chunk update loop has unexpectedly ended!");
            }

            //TaskScheduler.Dispose();
        }