#pragma once #include "Generation/Generator.hpp" #include "ChunkIndex.hpp" #include "ChunkRegistry.hpp" #include "../Compute/Queue.hpp" #include "../Math/Ray.hpp" #include "Generation/ChunkMeshing.hpp" #include "Generation/Lighting.hpp" #include "VoxelTraversal.hpp" namespace MC::World { class World { public: std::vector get_visible_chunks(Time const& time, Position::World position); Chunk::BlockData block_at(Position::BlockWorld pos); void set_block(Position::BlockWorld pos, BlockType type); void break_block(Position::BlockWorld pos); using TraversalResult = VoxelTraversal::TraversalResult; template TraversalResult traverse(Ray ray, F&& predicate, Real max_distance = 0) { return VoxelTraversal::traverse( ray, [this, &predicate](Position::BlockWorld pos) { return predicate(block_at(pos)); }, max_distance ); } Real get_average_chunk_time() const; ChunkRegistry& chunks() { return m_registry; } private: std::vector get_visible_chunk_indices(Position::World position) const; void process_chunk_updates(Time const& time); void request_generation(ChunkIndex index, Real priority); void request_reification(ChunkIndex index, Real priority); Bool should_reassess_priorities(Position::World player_position) const; void reassess_priorities(Position::World player_position); enum class RequestType { Initial, Update }; static Real calculate_priority(ChunkIndex chunk, Position::World player_position, RequestType request_type); void log_chunk_time(U64 chunk_time_ms); U8 m_view_distance_radius = 10; Bool is_chunk_in_radius(Position::World position, ChunkIndex chunk) const; struct GenerationResult { Chunk chunk; U64 generation_duration; }; using GenerationQueue = Compute::Queue; GenerationQueue m_generation_queue{1}; struct ReificationResult { Generation::ChunkMeshing::ChunkMesh chunk_mesh; }; using ReificationQueue = Compute::Queue; ReificationQueue m_reification_queue{1}; Real m_priority_reassession_distance_threshold = 50; Position::World m_last_priority_reassession_at = {}; Generation::Generator m_generator; Generation::Lighting m_lighting; ChunkRegistry m_registry; struct Statistics { UInt chunk_time_sample_count; Real average_chunk_time_ms; }; Statistics m_statistics{0, 0.0f}; }; }