diff --git a/TrueCraft.Client/Handlers/ChunkHandler.cs b/TrueCraft.Client/Handlers/ChunkHandler.cs index e0854f7..3e495bb 100644 --- a/TrueCraft.Client/Handlers/ChunkHandler.cs +++ b/TrueCraft.Client/Handlers/ChunkHandler.cs @@ -26,7 +26,7 @@ namespace TrueCraft.Client.Handlers // Relevant chunk is not loaded - ignore packet return; } - chunk.SetBlockID(adjusted, packet.ID); + chunk.SetBlockID(adjusted, (byte)packet.BlockID); chunk.SetMetadata(adjusted, (byte)packet.Metadata); client.OnChunkModified(new ChunkEventArgs(new ReadOnlyChunk(chunk))); } @@ -41,10 +41,10 @@ namespace TrueCraft.Client.Handlers public static void HandleChunkData(IPacket _packet, MultiplayerClient client) { var packet = (ChunkDataPacket)_packet; + var coords = new Coordinates3D(packet.X, packet.Y, packet.Z); var data = ZlibStream.UncompressBuffer(packet.CompressedData); IChunk chunk; - var adjustedCoords = client.World.World.FindBlockPosition( - new Coordinates3D(packet.X, packet.Y, packet.Z), out chunk); + var adjustedCoords = client.World.World.FindBlockPosition(coords, out chunk); if (packet.Width == Chunk.Width && packet.Height == Chunk.Height diff --git a/TrueCraft.Client/Modules/ChunkModule.cs b/TrueCraft.Client/Modules/ChunkModule.cs index a1a188a..206ecdc 100644 --- a/TrueCraft.Client/Modules/ChunkModule.cs +++ b/TrueCraft.Client/Modules/ChunkModule.cs @@ -6,6 +6,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using TrueCraft.API; +using System.Linq; +using System.Threading; namespace TrueCraft.Client.Modules { @@ -15,7 +17,8 @@ namespace TrueCraft.Client.Modules public ChunkRenderer ChunkRenderer { get; set; } public int ChunksRendered { get; set; } - private List ChunkMeshes { get; set; } + private HashSet ActiveMeshes { get; set; } + private List ChunkMeshes { get; set; } private ConcurrentBag IncomingChunks { get; set; } private BasicEffect OpaqueEffect { get; set; } @@ -27,7 +30,8 @@ namespace TrueCraft.Client.Modules ChunkRenderer = new ChunkRenderer(Game.Client.World, Game, Game.BlockRepository); Game.Client.ChunkLoaded += (sender, e) => ChunkRenderer.Enqueue(e.Chunk); - //Client.ChunkModified += (sender, e) => ChunkRenderer.Enqueue(e.Chunk, true); + Game.Client.ChunkUnloaded += (sender, e) => UnloadChunk(e.Chunk); + Game.Client.ChunkModified += (sender, e) => ChunkRenderer.Enqueue(e.Chunk, true); ChunkRenderer.MeshCompleted += MeshCompleted; ChunkRenderer.Start(); @@ -50,8 +54,9 @@ namespace TrueCraft.Client.Modules TransparentEffect.Texture = Game.TextureMapper.GetTexture("terrain.png"); TransparentEffect.VertexColorEnabled = true; - ChunkMeshes = new List(); + ChunkMeshes = new List(); IncomingChunks = new ConcurrentBag(); + ActiveMeshes = new HashSet(); } void MeshCompleted(object sender, RendererEventArgs e) @@ -59,6 +64,15 @@ namespace TrueCraft.Client.Modules IncomingChunks.Add(e.Result); } + void UnloadChunk(ReadOnlyChunk chunk) + { + Game.PendingMainThreadActions.Add(() => + { + ActiveMeshes.Remove(chunk.Coordinates); + ChunkMeshes.RemoveAll(m => m.Chunk.Coordinates == chunk.Coordinates); + }); + } + void HandleClientPropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) @@ -73,10 +87,17 @@ namespace TrueCraft.Client.Modules public void Update(GameTime gameTime) { - Mesh mesh; - while (IncomingChunks.TryTake(out mesh)) + Mesh _mesh; + while (IncomingChunks.TryTake(out _mesh)) { + var mesh = _mesh as ChunkMesh; + int existing = -1; + if (ActiveMeshes.Contains(mesh.Chunk.Coordinates)) + existing = ChunkMeshes.FindIndex(m => m.Chunk.Coordinates == mesh.Chunk.Coordinates); + ActiveMeshes.Add(mesh.Chunk.Coordinates); ChunkMeshes.Add(mesh); + if (existing != -1) + ChunkMeshes.RemoveAt(existing); } } diff --git a/TrueCraft.Client/Modules/DebugInfoModule.cs b/TrueCraft.Client/Modules/DebugInfoModule.cs index fa21aa9..0e31407 100644 --- a/TrueCraft.Client/Modules/DebugInfoModule.cs +++ b/TrueCraft.Client/Modules/DebugInfoModule.cs @@ -89,6 +89,9 @@ namespace TrueCraft.Client.Modules string.Format(ChatColor.Gray + "Looking at {0} ({1})", Game.HighlightedBlock, Enum.GetName(typeof(BlockFace), Game.HighlightedBlockFace))); + Font.DrawText(SpriteBatch, xOrigin, yOrigin + (yOffset * 3), + string.Format(ChatColor.Gray + "{0} pending chunks", Game.ChunkModule.ChunkRenderer.PendingChunks)); + SpriteBatch.End(); } diff --git a/TrueCraft.Client/ReadOnlyWorld.cs b/TrueCraft.Client/ReadOnlyWorld.cs index db654e3..bd33d2e 100644 --- a/TrueCraft.Client/ReadOnlyWorld.cs +++ b/TrueCraft.Client/ReadOnlyWorld.cs @@ -109,6 +109,8 @@ namespace TrueCraft.Client return Chunk.GetBlockLight(coordinates); } + public Coordinates2D Coordinates { get { return Chunk.Coordinates; } } + public int X { get { return Chunk.X; } } public int Z { get { return Chunk.Z; } } diff --git a/TrueCraft.Client/Rendering/ChunkRenderer.cs b/TrueCraft.Client/Rendering/ChunkRenderer.cs index ffd4f49..6f37224 100644 --- a/TrueCraft.Client/Rendering/ChunkRenderer.cs +++ b/TrueCraft.Client/Rendering/ChunkRenderer.cs @@ -39,6 +39,14 @@ namespace TrueCraft.Client.Rendering } } + public int PendingChunks + { + get + { + return _items.Count + _priorityItems.Count; + } + } + private ReadOnlyWorld World { get; set; } private TrueCraftGame Game { get; set; } private IBlockRepository BlockRepository { get; set; } diff --git a/TrueCraft.Client/Rendering/Renderer.cs b/TrueCraft.Client/Rendering/Renderer.cs index 765a4b8..f8067ec 100644 --- a/TrueCraft.Client/Rendering/Renderer.cs +++ b/TrueCraft.Client/Rendering/Renderer.cs @@ -20,8 +20,8 @@ namespace TrueCraft.Client.Rendering private volatile bool _isRunning; private Thread[] _rendererThreads; - private ConcurrentQueue _items, _priorityItems; private volatile bool _isDisposed; + protected ConcurrentQueue _items, _priorityItems; /// /// Gets whether this renderer is running. @@ -150,13 +150,10 @@ namespace TrueCraft.Client.Rendering throw new ObjectDisposedException(GetType().Name); if (!_isRunning) return; - lock (_syncLock) - { - if (hasPriority) - _priorityItems.Enqueue(item); - else - _items.Enqueue(item); - } + if (hasPriority) + _priorityItems.Enqueue(item); + else + _items.Enqueue(item); } /// diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs index 1003208..8b05784 100644 --- a/TrueCraft.Client/TrueCraftGame.cs +++ b/TrueCraft.Client/TrueCraftGame.cs @@ -269,9 +269,7 @@ namespace TrueCraft.Client // We should eventually make some means of detecing that we're on a vanilla server to enable this // It's a waste of bandwidth to do it on a TrueCraft server Client.QueuePacket(new PlayerGroundedPacket { OnGround = true }); - Client.QueuePacket(new PlayerPositionAndLookPacket(Client.Position.X, Client.Position.Y, - Client.Position.Y + MultiplayerClient.Height, Client.Position.Z, Client.Yaw, Client.Pitch, false)); - NextPhysicsUpdate = DateTime.UtcNow.AddMilliseconds(1000 / 20); + NextPhysicsUpdate = DateTime.UtcNow.AddMilliseconds(50); } foreach (var module in Modules)