private GameEvent GetCurrentGameEvent(Channel channel) { var player = channel.Player; var gameEvent = new GameEvent() { EntityInfos = new List <EntityData>() }; foreach (var entity in _entities) { if (entity != player) { gameEvent.EntityInfos.Add(new EntityData { PositionData = entity.PositionData, ModelIndex = entity.ModelIndex }); } } if (player.PositionData != null) { var playerChunkPos = (ChunkPos)player.PositionData.Placement.Pos; int chunksInPacket = 0; ChunkPos.IterateOutwards( playerChunkPos, ChunkViewRadiusXZ, ChunkViewRadiusY, chunkPos => { if (!channel.SentChunks.ContainsKey(chunkPos)) { var chunk = _startWorld.GetChunk(chunkPos); if (chunksInPacket < 5 && chunk.IsCreated) { channel.SentChunks[chunkPos] = true; if (chunk != null) { if (gameEvent.ChunkDataList == null) { gameEvent.ChunkDataList = new List <ChunkData>(); } gameEvent.ChunkDataList.Add(chunk.GetChunkData()); ++chunksInPacket; } } } }); } if (channel.SentBlockUpdates != _blockUpdates.Count) { gameEvent.BlockUpdates = _blockUpdates.GetRange(channel.SentBlockUpdates, _blockUpdates.Count - channel.SentBlockUpdates); channel.SentBlockUpdates = _blockUpdates.Count; } return(gameEvent); }
private void RenderBlocks(GameClient gameClient) { GL.UseProgram(_cubeShader.Value.Id); GL.UniformMatrix4(0, false, ref _projectionMatrix); GL.UniformMatrix4(4, false, ref _modelViewMatrix); var cameraChunkPos = (ChunkPos)gameClient.PositionData.Placement.Pos; var offset = (gameClient.PositionData.Placement.Pos - EntityPos.Origin) + new EntityOffset(0, gameClient.PhysicsValues.PlayerEyeHeight, 0); int chunkUpdates = 0; ChunkPos.IterateOutwards( cameraChunkPos, ChunkViewRadiusXZ, ChunkViewRadiusY, chunkPos => { ChunkBufferEntry entry; _chunkBuffers.TryGetValue(chunkPos, out entry); /* Don't let nearby entries expire. */ if (entry != null) { entry.LastAccess = _currentFrameTime; } if (!IsInViewingFrustum(gameClient, offset, chunkPos)) { return; } var chunk = gameClient.World.PeekChunk(chunkPos); if (chunk != null && chunk.HasData) { if (entry == null) { entry = new ChunkBufferEntry { LastAccess = _currentFrameTime }; _chunkBuffers[chunkPos] = entry; } if (entry.ContentHash != chunk.ContentHash) { if (chunkUpdates < 5 && entry.TriangleTask != null && entry.TriangleTask.IsCompleted) { var triangles = entry.TriangleTask.Result; if (entry.TriangleTaskContentHash == chunk.ContentHash) { ++chunkUpdates; if (entry.VertexArray == null) { entry.VertexArray = new VertexArray(_cubeVertexSpecification); } entry.VertexArray.SetData(triangles, BufferUsageHint.StaticDraw); entry.ContentHash = chunk.ContentHash; } triangles.Dispose(); entry.TriangleTask = null; entry.TriangleTaskContentHash = 0; } if (entry.ContentHash != chunk.ContentHash && entry.TriangleTask == null) { var triangleBuffer = new TriangleBuffer(_cubeVertexSpecification); var localChunk = chunk; entry.TriangleTask = Task.Run(() => { RenderChunk(triangleBuffer, localChunk); return(triangleBuffer); }); entry.TriangleTaskContentHash = chunk.ContentHash; } } entry.VertexArray?.Draw(); } }); GL.UseProgram(0); RemoveExpiredChunks(); }
private GameEvent GetCurrentGameEvent(Channel channel) { var player = channel.Player; var gameEvent = new GameEvent() { EntityInfos = new List <EntityData>() }; foreach (var entity in Universe.GetEntitiesWithComponent <PositionComponent>()) { if (entity != player) { var position = entity.Get <PositionComponent>(); gameEvent.EntityInfos.Add( new EntityData { PositionData = position, ModelIndex = Mod.MobTypes.GetOrDefault(entity.Get <MobTypeComponent>()?.MobType)?.Model?.Index, }); } } PositionComponent playerPosition; if (player.TryGet(out playerPosition)) { var playerChunkPos = (ChunkPos)playerPosition.Placement.Pos; int chunksInPacket = 0; ChunkPos.IterateOutwards( playerChunkPos, ChunkViewRadiusXZ, ChunkViewRadiusY, chunkPos => { if (chunksInPacket < 5 && !channel.SentChunks.ContainsKey(chunkPos)) { var chunk = Universe.StartWorld.GetChunk(chunkPos); if (!chunk.IsCreated) { _worldGenerator.OnChunkRequested(chunk); } else { channel.SentChunks[chunkPos] = true; if (chunk != null) { if (gameEvent.ChunkDataList == null) { gameEvent.ChunkDataList = new List <ChunkData>(); } gameEvent.ChunkDataList.Add(chunk.GetChunkData()); ++chunksInPacket; } } } }); } if (channel.SentBlockUpdates != _blockUpdates.Count) { gameEvent.BlockUpdates = _blockUpdates.GetRange(channel.SentBlockUpdates, _blockUpdates.Count - channel.SentBlockUpdates); channel.SentBlockUpdates = _blockUpdates.Count; } return(gameEvent); }