#ifndef VOXEL_MESH_UPDATER_H #define VOXEL_MESH_UPDATER_H #include #include #include #include "../meshers/blocky/voxel_mesher_blocky.h" #include "../meshers/dmc/voxel_mesher_dmc.h" #include "../voxel_buffer.h" class VoxelMeshUpdater { public: static const int MAX_LOD = 32; // Like VoxelLodTerrain struct InputBlock { Ref voxels; Vector3i position; unsigned int lod = 0; }; struct Input { std::vector blocks; Vector3i priority_position; // In LOD0 block coordinates int exclusive_region_extent = 0; bool use_exclusive_region = false; bool is_empty() const { return blocks.empty(); } }; struct OutputBlock { VoxelMesher::Output blocky_surfaces; VoxelMesher::Output smooth_surfaces; Vector3i position; unsigned int lod = 0; }; struct Stats { bool first = true; uint64_t min_time = 0; uint64_t max_time = 0; uint32_t remaining_blocks = 0; }; struct Output { Vector blocks; Stats stats; }; struct MeshingParams { bool baked_ao = true; float baked_ao_darkness = 0.75; bool smooth_surface = false; }; VoxelMeshUpdater(Ref library, MeshingParams params); ~VoxelMeshUpdater(); void push(const Input &input); void pop(Output &output); int get_required_padding() const; static Dictionary to_dictionary(const Stats &stats); private: static void _thread_func(void *p_self); void thread_func(); void thread_sync(int queue_index, Stats stats); void process_block(const InputBlock &block, OutputBlock &output); private: Input _shared_input; Mutex *_input_mutex; HashMap _block_indexes[MAX_LOD]; bool _needs_sort; Output _shared_output; Mutex *_output_mutex; Ref _blocky_mesher; Ref _dmc_mesher; Input _input; Output _output; Semaphore *_semaphore; Thread *_thread; bool _thread_exit; }; #endif // VOXEL_MESH_UPDATER_H