Fix visibility + staying visible in other scenes

This commit is contained in:
Marc Gilleron 2017-08-28 02:32:23 +02:00
parent 115e0e2870
commit 126f367c50
4 changed files with 74 additions and 5 deletions

View File

@ -56,3 +56,26 @@ void VoxelBlock::set_mesh(Ref<Mesh> mesh, Ref<World> 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);
}
}

View File

@ -17,6 +17,10 @@ public:
void set_mesh(Ref<Mesh> mesh, Ref<World> world);
void enter_world(World *world);
void exit_world();
void set_visible(bool visible);
private:
VoxelBlock();

View File

@ -105,6 +105,17 @@ public:
void clear();
template <typename Op_T>
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);

View File

@ -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;