From 126f367c502e660e081d7e94983e7349f51e9940 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Mon, 28 Aug 2017 02:32:23 +0200 Subject: [PATCH] Fix visibility + staying visible in other scenes --- voxel_block.cpp | 23 +++++++++++++++++++++++ voxel_block.h | 4 ++++ voxel_map.h | 11 +++++++++++ voxel_terrain.cpp | 41 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/voxel_block.cpp b/voxel_block.cpp index 7db13e8..7e07b27 100644 --- a/voxel_block.cpp +++ b/voxel_block.cpp @@ -56,3 +56,26 @@ void VoxelBlock::set_mesh(Ref mesh, Ref world) { _mesh = mesh; } + +void VoxelBlock::enter_world(World *world) { + if(_mesh_instance.is_valid()) { + VisualServer &vs = *VisualServer::get_singleton(); + vs.instance_set_scenario(_mesh_instance, world->get_scenario()); + } +} + +void VoxelBlock::exit_world() { + if(_mesh_instance.is_valid()) { + VisualServer &vs = *VisualServer::get_singleton(); + vs.instance_set_scenario(_mesh_instance, RID()); + } +} + +void VoxelBlock::set_visible(bool visible) { + if(_mesh_instance.is_valid()) { + VisualServer &vs = *VisualServer::get_singleton(); + vs.instance_set_visible(_mesh_instance, visible); + } +} + + diff --git a/voxel_block.h b/voxel_block.h index fcc9178..4987e92 100644 --- a/voxel_block.h +++ b/voxel_block.h @@ -17,6 +17,10 @@ public: void set_mesh(Ref mesh, Ref world); + void enter_world(World *world); + void exit_world(); + void set_visible(bool visible); + private: VoxelBlock(); diff --git a/voxel_map.h b/voxel_map.h index c007cf4..16b0e95 100644 --- a/voxel_map.h +++ b/voxel_map.h @@ -105,6 +105,17 @@ public: void clear(); + template + void for_all_blocks(Op_T op) { + const Vector3i *key = NULL; + while (key = _blocks.next(key)) { + VoxelBlock *block = _blocks.get(*key); + if (block != NULL) { + op(block); + } + } + } + private: void set_block(Vector3i bpos, VoxelBlock *block); diff --git a/voxel_terrain.cpp b/voxel_terrain.cpp index 8d3d59f..6f4eab7 100644 --- a/voxel_terrain.cpp +++ b/voxel_terrain.cpp @@ -306,6 +306,28 @@ int VoxelTerrain::get_block_update_count() { return _block_update_queue.size(); } +struct EnterWorldAction { + World *world; + EnterWorldAction(World *w) : world(w) {} + void operator()(VoxelBlock *block) { + block->enter_world(world); + } +}; + +struct ExitWorldAction { + void operator()(VoxelBlock *block) { + block->exit_world(); + } +}; + +struct SetVisibilityAction { + bool visible; + SetVisibilityAction(bool v) : visible(v) {} + void operator()(VoxelBlock *block) { + block->set_visible(visible); + } +}; + void VoxelTerrain::_notification(int p_what) { switch (p_what) { @@ -321,13 +343,22 @@ void VoxelTerrain::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: break; -// case NOTIFICATION_READY: -// break; + case NOTIFICATION_ENTER_WORLD: { + ERR_FAIL_COND(_map.is_null()); + _map->for_all_blocks(EnterWorldAction(*get_world())); + } break; + + case NOTIFICATION_EXIT_WORLD: + ERR_FAIL_COND(_map.is_null()); + _map->for_all_blocks(ExitWorldAction()); + break; + + case NOTIFICATION_VISIBILITY_CHANGED: + ERR_FAIL_COND(_map.is_null()); + _map->for_all_blocks(SetVisibilityAction(is_visible())); + break; // TODO Listen for transform changes - // TODO Listen for NOTIFICATION_VISIBILITY_CHANGED - // TODO Listen for NOTIFICATION_ENTER_WORLD - // TODO Listen for NOTIFICATION_EXIT_WORLD default: break;