2016-05-10 01:59:54 +02:00
|
|
|
#ifndef VOXEL_TERRAIN_H
|
|
|
|
#define VOXEL_TERRAIN_H
|
|
|
|
|
|
|
|
#include <scene/main/node.h>
|
|
|
|
#include "voxel_map.h"
|
|
|
|
#include "voxel_mesher.h"
|
2017-01-02 02:15:57 +01:00
|
|
|
#include "voxel_provider.h"
|
2017-04-01 20:10:38 +02:00
|
|
|
#include "zprofiling.h"
|
2017-03-26 18:09:37 +02:00
|
|
|
|
2016-05-10 01:59:54 +02:00
|
|
|
// Infinite static terrain made of voxels.
|
|
|
|
// It is loaded around VoxelTerrainStreamers.
|
|
|
|
class VoxelTerrain : public Node /*, public IVoxelMapObserver*/ {
|
2017-03-25 01:23:36 +01:00
|
|
|
GDCLASS(VoxelTerrain, Node)
|
2016-05-10 01:59:54 +02:00
|
|
|
public:
|
2017-01-01 04:40:16 +01:00
|
|
|
VoxelTerrain();
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-01-02 02:15:57 +01:00
|
|
|
void set_provider(Ref<VoxelProvider> provider);
|
|
|
|
Ref<VoxelProvider> get_provider();
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-01-02 02:15:57 +01:00
|
|
|
void force_load_blocks(Vector3i center, Vector3i extents);
|
2017-01-01 04:40:16 +01:00
|
|
|
int get_block_update_count();
|
2017-03-28 00:56:01 +02:00
|
|
|
//void clear_update_queue();
|
|
|
|
|
|
|
|
void make_block_dirty(Vector3i bpos);
|
|
|
|
void make_blocks_dirty(Vector3i min, Vector3i size);
|
2017-03-29 22:36:42 +02:00
|
|
|
void make_voxel_dirty(Vector3i pos);
|
|
|
|
bool is_block_dirty(Vector3i bpos);
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-03-26 18:09:37 +02:00
|
|
|
void set_generate_collisions(bool enabled);
|
|
|
|
bool get_generate_collisions() { return _generate_collisions; }
|
|
|
|
|
2017-03-28 00:56:01 +02:00
|
|
|
void set_viewer_path(NodePath path);
|
|
|
|
NodePath get_viewer_path();
|
|
|
|
|
2017-01-01 04:40:16 +01:00
|
|
|
Ref<VoxelMesher> get_mesher() { return _mesher; }
|
2017-01-05 02:39:40 +01:00
|
|
|
Ref<VoxelMap> get_map() { return _map; }
|
2017-03-26 20:07:01 +02:00
|
|
|
Ref<VoxelLibrary> get_voxel_library();
|
2016-05-10 01:59:54 +02:00
|
|
|
|
|
|
|
protected:
|
2017-01-01 04:40:16 +01:00
|
|
|
void _notification(int p_what);
|
2017-03-28 00:56:01 +02:00
|
|
|
|
|
|
|
private:
|
2017-01-01 04:40:16 +01:00
|
|
|
void _process();
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-01-01 04:40:16 +01:00
|
|
|
void update_blocks();
|
|
|
|
void update_block_mesh(Vector3i block_pos);
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-03-28 00:56:01 +02:00
|
|
|
Spatial * get_viewer(NodePath path);
|
|
|
|
|
2017-01-01 04:40:16 +01:00
|
|
|
// Observer events
|
|
|
|
//void block_removed(VoxelBlock & block);
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-01-01 04:40:16 +01:00
|
|
|
static void _bind_methods();
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-01-01 04:40:16 +01:00
|
|
|
// Convenience
|
|
|
|
Vector3 _voxel_to_block_binding(Vector3 pos) { return Vector3i(VoxelMap::voxel_to_block(pos)).to_vec3(); }
|
|
|
|
Vector3 _block_to_voxel_binding(Vector3 pos) { return Vector3i(VoxelMap::block_to_voxel(pos)).to_vec3(); }
|
|
|
|
void _force_load_blocks_binding(Vector3 center, Vector3 extents) { force_load_blocks(center, extents); }
|
2017-03-28 00:56:01 +02:00
|
|
|
void _make_block_dirty_binding(Vector3 bpos) { make_block_dirty(bpos); }
|
|
|
|
void _make_blocks_dirty_binding(Vector3 min, Vector3 size) { make_blocks_dirty(min, size); }
|
2017-03-29 22:36:42 +02:00
|
|
|
void _make_voxel_dirty_binding(Vector3 pos) { make_voxel_dirty(pos); }
|
2017-03-28 00:56:01 +02:00
|
|
|
|
2017-03-26 20:07:01 +02:00
|
|
|
Variant _raycast_binding(Vector3 origin, Vector3 direction, real_t max_distance);
|
2016-05-10 01:59:54 +02:00
|
|
|
|
2017-03-29 22:36:42 +02:00
|
|
|
void set_voxel(Vector3 pos, int value, int c);
|
|
|
|
int get_voxel(Vector3 pos, int c);
|
2017-03-28 00:56:01 +02:00
|
|
|
|
2017-01-02 02:19:02 +01:00
|
|
|
private:
|
|
|
|
// Parameters
|
|
|
|
int _min_y; // In blocks, not voxels
|
|
|
|
int _max_y;
|
|
|
|
|
|
|
|
// Voxel storage
|
|
|
|
Ref<VoxelMap> _map;
|
|
|
|
|
2017-03-28 00:56:01 +02:00
|
|
|
// 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?
|
|
|
|
|
2017-01-02 02:19:02 +01:00
|
|
|
Vector<Vector3i> _block_update_queue;
|
2017-03-28 00:56:01 +02:00
|
|
|
HashMap<Vector3i, bool, Vector3iHasher> _dirty_blocks; // only the key is relevant
|
|
|
|
|
2017-01-02 02:19:02 +01:00
|
|
|
Ref<VoxelMesher> _mesher;
|
|
|
|
Ref<VoxelProvider> _provider;
|
|
|
|
|
2017-03-28 00:56:01 +02:00
|
|
|
NodePath _viewer_path;
|
|
|
|
|
2017-03-26 18:09:37 +02:00
|
|
|
bool _generate_collisions;
|
|
|
|
|
2017-04-01 20:10:38 +02:00
|
|
|
#ifdef VOXEL_PROFILING
|
|
|
|
ZProfiler _zprofiler;
|
|
|
|
Dictionary get_profiling_info() { return _zprofiler.get_all_serialized_info(); }
|
|
|
|
#endif
|
|
|
|
|
2016-05-10 01:59:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // VOXEL_TERRAIN_H
|
|
|
|
|