godot_voxel/terrain/voxel_terrain.h

189 lines
5.4 KiB
C
Raw Normal View History

#ifndef VOXEL_TERRAIN_H
#define VOXEL_TERRAIN_H
#include "../server/voxel_server.h"
#include "voxel_map.h"
#include "voxel_node.h"
#include <scene/3d/spatial.h>
class VoxelTool;
2017-03-26 18:09:37 +02:00
// Infinite paged terrain made of voxel blocks all with the same level of detail.
2019-05-04 00:00:50 +01:00
// Voxels are polygonized around the viewer by distance in a large cubic space.
2019-05-25 16:07:38 +01:00
// Data is streamed using a VoxelStream.
class VoxelTerrain : public VoxelNode {
GDCLASS(VoxelTerrain, VoxelNode)
public:
static const unsigned int MAX_VIEW_DISTANCE_FOR_LARGE_VOLUME = 512;
2017-01-01 04:40:16 +01:00
VoxelTerrain();
~VoxelTerrain();
void set_stream(Ref<VoxelStream> p_stream) override;
Ref<VoxelStream> get_stream() const override;
2020-02-15 03:12:13 +08:00
void set_generator(Ref<VoxelGenerator> p_generator) override;
Ref<VoxelGenerator> get_generator() const override;
void set_mesher(Ref<VoxelMesher> mesher) override;
Ref<VoxelMesher> get_mesher() const override;
unsigned int get_block_size_pow2() const;
void set_block_size_po2(unsigned int p_block_size_po2);
void make_voxel_dirty(Vector3i pos);
2018-10-01 20:48:47 +01:00
void make_area_dirty(Rect3i box);
2017-03-26 18:09:37 +02:00
void set_generate_collisions(bool enabled);
bool get_generate_collisions() const { return _generate_collisions; }
2020-09-06 19:01:12 +01:00
unsigned int get_max_view_distance() const;
void set_max_view_distance(unsigned int distance_in_voxels);
2017-03-26 18:09:37 +02:00
// TODO Make this obsolete with multi-viewers
void set_viewer_path(NodePath path);
NodePath get_viewer_path() const;
2019-06-18 14:24:56 +09:00
void set_material(unsigned int id, Ref<Material> material);
Ref<Material> get_material(unsigned int id) const;
VoxelMap &get_storage() { return _map; }
const VoxelMap &get_storage() const { return _map; }
Ref<VoxelTool> get_voxel_tool();
void set_run_stream_in_editor(bool enable);
bool is_stream_running_in_editor() const;
void set_bounds(Rect3i box);
Rect3i get_bounds() const;
void restart_stream() override;
void remesh_all_blocks() override;
// For convenience, this is actually stored in a particular type of mesher
Ref<VoxelLibrary> get_voxel_library() const;
struct Stats {
2019-08-25 18:47:43 +01:00
int updated_blocks = 0;
int dropped_block_loads = 0;
int dropped_block_meshs = 0;
int remaining_main_thread_blocks = 0;
uint32_t time_detect_required_blocks = 0;
uint32_t time_request_blocks_to_load = 0;
uint32_t time_process_load_responses = 0;
uint32_t time_request_blocks_to_update = 0;
uint32_t time_process_update_responses = 0;
};
2020-12-25 17:08:40 +00:00
const Stats &get_stats() const;
struct BlockToSave {
Ref<VoxelBuffer> voxels;
Vector3i position;
};
protected:
2017-01-01 04:40:16 +01: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;
2017-01-01 04:40:16 +01:00
void _process();
void _on_stream_params_changed();
void _set_block_size_po2(int p_block_size_po2);
2020-09-06 19:01:12 +01:00
void make_all_view_dirty();
void start_updater();
void stop_updater();
void start_streamer();
void stop_streamer();
void reset_map();
2020-09-06 19:01:12 +01:00
void view_block(Vector3i bpos, bool data_flag, bool mesh_flag, bool collision_flag);
void unview_block(Vector3i bpos, bool data_flag, bool mesh_flag, bool collision_flag);
void immerge_block(Vector3i bpos);
2020-09-06 19:01:12 +01:00
void make_block_dirty(Vector3i bpos);
void make_block_dirty(VoxelBlock *block);
void try_schedule_block_update(VoxelBlock *block);
void save_all_modified_blocks(bool with_copy);
void get_viewer_pos_and_direction(Vector3 &out_pos, Vector3 &out_direction) const;
void send_block_data_requests();
void emit_block_loaded(const VoxelBlock *block);
void emit_block_unloaded(const VoxelBlock *block);
2020-09-06 19:01:12 +01:00
bool try_get_paired_viewer_index(uint32_t id, size_t &out_i) const;
2017-01-01 04:40:16 +01:00
static void _bind_methods();
// Bindings
Vector3 _b_voxel_to_block(Vector3 pos);
Vector3 _b_block_to_voxel(Vector3 pos);
//void _force_load_blocks_binding(Vector3 center, Vector3 extents) { force_load_blocks(center, extents); }
void _b_save_modified_blocks();
void _b_save_block(Vector3 p_block_pos);
void _b_set_bounds(AABB aabb);
AABB _b_get_bounds() const;
2020-12-25 17:08:40 +00:00
Dictionary _b_get_statistics() const;
uint32_t _volume_id = 0;
VoxelServer::ReceptionBuffers _reception_buffers;
2020-09-06 19:01:12 +01:00
struct PairedViewer {
struct State {
Vector3i block_position;
2020-09-09 18:58:58 +01:00
int view_distance_blocks = 0;
bool requires_collisions = false;
bool requires_meshes = false;
2020-09-06 19:01:12 +01:00
};
uint32_t id;
State state;
State prev_state;
};
std::vector<PairedViewer> _paired_viewers;
2017-01-02 02:19:02 +01:00
// Voxel storage
VoxelMap _map;
2017-01-02 02:19:02 +01:00
// Area within which voxels can exist.
// Note, these bounds might not be exactly represented. This volume is chunk-based, so the result will be
// approximated to the closest chunk.
Rect3i _bounds_in_voxels;
Rect3i _prev_bounds_in_voxels;
// How many blocks to load around the viewer
2020-09-06 19:01:12 +01:00
unsigned int _max_view_distance_blocks = 8;
// 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?
2020-09-06 19:01:12 +01:00
struct LoadingBlock {
VoxelViewerRefCount viewers;
};
2020-09-06 19:01:12 +01:00
HashMap<Vector3i, LoadingBlock, Vector3iHasher> _loading_blocks;
std::vector<Vector3i> _blocks_pending_load;
std::vector<Vector3i> _blocks_pending_update;
std::vector<BlockToSave> _blocks_to_save;
2019-05-25 16:07:38 +01:00
Ref<VoxelStream> _stream;
Ref<VoxelMesher> _mesher;
Ref<VoxelGenerator> _generator;
2017-01-02 02:19:02 +01:00
bool _generate_collisions = true;
bool _run_stream_in_editor = true;
//bool _stream_enabled = false;
2017-03-26 18:09:37 +02:00
Ref<Material> _materials[VoxelMesherBlocky::MAX_MATERIALS];
Stats _stats;
};
#endif // VOXEL_TERRAIN_H