godot_voxel/terrain/voxel_terrain.h

146 lines
4.2 KiB
C
Raw Normal View History

#ifndef VOXEL_TERRAIN_H
#define VOXEL_TERRAIN_H
#include "../math/rect3i.h"
#include "../math/vector3i.h"
2019-05-25 08:16:03 -07:00
#include "../streams/voxel_stream.h"
#include "../util/zprofiling.h"
#include "voxel_data_loader.h"
2019-04-23 17:29:47 -07:00
#include "voxel_mesh_updater.h"
#include <scene/3d/spatial.h>
class VoxelMap;
class VoxelLibrary;
2017-03-26 09:09:37 -07:00
// Infinite paged terrain made of voxel blocks all with the same level of detail.
2019-05-03 16:00:50 -07:00
// Voxels are polygonized around the viewer by distance in a large cubic space.
2019-05-25 08:07:38 -07:00
// Data is streamed using a VoxelStream.
2019-04-23 17:29:47 -07:00
class VoxelTerrain : public Spatial {
GDCLASS(VoxelTerrain, Spatial)
public:
2016-12-31 19:40:16 -08:00
VoxelTerrain();
~VoxelTerrain();
void set_stream(Ref<VoxelStream> p_stream);
2019-05-25 08:07:38 -07:00
Ref<VoxelStream> get_stream() const;
unsigned int get_block_size_pow2() const;
void set_block_size_po2(unsigned int p_block_size_po2);
void set_voxel_library(Ref<VoxelLibrary> library);
Ref<VoxelLibrary> get_voxel_library() const;
void make_block_dirty(Vector3i bpos);
//void make_blocks_dirty(Vector3i min, Vector3i size);
void make_voxel_dirty(Vector3i pos);
2018-10-01 12:48:47 -07:00
void make_area_dirty(Rect3i box);
2017-03-26 09:09:37 -07:00
void set_generate_collisions(bool enabled);
bool get_generate_collisions() const { return _generate_collisions; }
int get_view_distance() const;
void set_view_distance(int distance_in_voxels);
2017-03-26 09:09:37 -07:00
void set_viewer_path(NodePath path);
NodePath get_viewer_path() const;
2019-06-17 22:24:56 -07:00
void set_material(unsigned int id, Ref<Material> material);
Ref<Material> get_material(unsigned int id) const;
bool is_smooth_meshing_enabled() const;
void set_smooth_meshing_enabled(bool enabled);
2019-09-03 14:54:40 -07:00
Ref<VoxelMap> get_storage() { return _map; }
struct Stats {
VoxelMeshUpdater::Stats updater;
VoxelDataLoader::Stats stream;
2019-08-25 10:47:43 -07:00
int updated_blocks = 0;
int dropped_block_loads = 0;
int dropped_block_meshs = 0;
uint64_t time_detect_required_blocks = 0;
uint64_t time_request_blocks_to_load = 0;
uint64_t time_process_load_responses = 0;
uint64_t time_request_blocks_to_update = 0;
uint64_t time_process_update_responses = 0;
};
protected:
2016-12-31 19:40:16 -08:00
void _notification(int p_what);
private:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
2016-12-31 19:40:16 -08:00
void _process();
void _on_stream_params_changed();
void _set_block_size_po2(int p_block_size_po2);
void make_all_view_dirty_deferred();
void start_updater();
void stop_updater();
void start_streamer();
void stop_streamer();
void reset_map();
Spatial *get_viewer(NodePath path) const;
void immerge_block(Vector3i bpos);
void save_all_modified_blocks(bool with_copy);
void get_viewer_block_pos_and_direction(Vector3i &out_block_pos, Vector3 &out_direction);
void send_block_data_requests();
Dictionary get_statistics() const;
2016-12-31 19:40:16 -08:00
static void _bind_methods();
2016-12-31 19:40:16 -08:00
// Convenience
2017-08-20 06:17:54 -07:00
Vector3 _voxel_to_block_binding(Vector3 pos);
Vector3 _block_to_voxel_binding(Vector3 pos);
//void _force_load_blocks_binding(Vector3 center, Vector3 extents) { force_load_blocks(center, extents); }
void _make_voxel_dirty_binding(Vector3 pos) { make_voxel_dirty(pos); }
2018-10-01 12:48:47 -07:00
void _make_area_dirty_binding(AABB aabb);
2017-03-26 11:07:01 -07:00
Variant _raycast_binding(Vector3 origin, Vector3 direction, real_t max_distance);
void set_voxel(Vector3 pos, int value, int c);
int get_voxel(Vector3 pos, int c);
2017-01-01 17:19:02 -08:00
private:
// Voxel storage
Ref<VoxelMap> _map;
// How many blocks to load around the viewer
int _view_distance_blocks;
// TODO Terrains only need to handle the visible portion of voxels, which reduces the bounds blocks to handle.
// Therefore, could a simple grid be better to use than a hashmap?
Set<Vector3i> _loading_blocks;
Vector<Vector3i> _blocks_pending_load;
Vector<Vector3i> _blocks_pending_update;
Vector<VoxelMeshUpdater::OutputBlock> _blocks_pending_main_thread_update;
std::vector<VoxelDataLoader::InputBlock> _blocks_to_save;
2019-05-25 08:07:38 -07:00
Ref<VoxelStream> _stream;
VoxelDataLoader *_stream_thread;
Ref<VoxelLibrary> _library;
VoxelMeshUpdater *_block_updater;
2017-01-01 17:19:02 -08:00
NodePath _viewer_path;
Vector3i _last_viewer_block_pos;
int _last_view_distance_blocks;
bool _generate_collisions = true;
bool _run_in_editor;
bool _smooth_meshing_enabled;
2017-03-26 09:09:37 -07:00
Ref<Material> _materials[VoxelMesherBlocky::MAX_MATERIALS];
Stats _stats;
};
#endif // VOXEL_TERRAIN_H