1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Merge pull request #51521 from lawnjelly/portals_occluders

Sphere occluders (portals and general use)
This commit is contained in:
Rémi Verschelde
2021-08-17 13:55:34 +02:00
committed by GitHub
36 changed files with 1825 additions and 7 deletions

View File

@@ -1157,6 +1157,67 @@ void VisualServerScene::roomgroup_add_room(RID p_roomgroup, RID p_room) {
roomgroup->scenario->_portal_renderer.roomgroup_add_room(roomgroup->scenario_roomgroup_id, room->scenario_room_id);
}
// Occluders
RID VisualServerScene::occluder_create() {
Occluder *ro = memnew(Occluder);
ERR_FAIL_COND_V(!ro, RID());
RID occluder_rid = occluder_owner.make_rid(ro);
return occluder_rid;
}
void VisualServerScene::occluder_set_scenario(RID p_occluder, RID p_scenario, VisualServer::OccluderType p_type) {
Occluder *ro = occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!ro);
Scenario *scenario = scenario_owner.getornull(p_scenario);
// noop?
if (ro->scenario == scenario) {
return;
}
// if the portal is in a scenario already, remove it
if (ro->scenario) {
ro->scenario->_portal_renderer.occluder_destroy(ro->scenario_occluder_id);
ro->scenario = nullptr;
ro->scenario_occluder_id = 0;
}
// create when entering the world
if (scenario) {
ro->scenario = scenario;
// defer the actual creation to here
ro->scenario_occluder_id = scenario->_portal_renderer.occluder_create((VSOccluder::Type)p_type);
}
}
void VisualServerScene::occluder_set_active(RID p_occluder, bool p_active) {
Occluder *ro = occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!ro);
ERR_FAIL_COND(!ro->scenario);
ro->scenario->_portal_renderer.occluder_set_active(ro->scenario_occluder_id, p_active);
}
void VisualServerScene::occluder_set_transform(RID p_occluder, const Transform &p_xform) {
Occluder *ro = occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!ro);
ERR_FAIL_COND(!ro->scenario);
ro->scenario->_portal_renderer.occluder_set_transform(ro->scenario_occluder_id, p_xform);
}
void VisualServerScene::occluder_spheres_update(RID p_occluder, const Vector<Plane> &p_spheres) {
Occluder *ro = occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!ro);
ERR_FAIL_COND(!ro->scenario);
ro->scenario->_portal_renderer.occluder_update_spheres(ro->scenario_occluder_id, p_spheres);
}
void VisualServerScene::set_use_occlusion_culling(bool p_enable) {
// this is not scenario specific, and is global
// (mainly for debugging)
PortalRenderer::use_occlusion_culling = p_enable;
}
// Rooms
void VisualServerScene::callbacks_register(VisualServerCallbacks *p_callbacks) {
_visual_server_callbacks = p_callbacks;
@@ -1397,6 +1458,9 @@ int VisualServerScene::_cull_convex_from_point(Scenario *p_scenario, const Vecto
// fallback to BVH / octree if portals not active
if (res == -1) {
res = p_scenario->sps->cull_convex(p_convex, p_result_array, p_result_max, p_mask);
// Opportunity for occlusion culling on the main scene. This will be a noop if no occluders.
res = p_scenario->_portal_renderer.occlusion_cull(p_point, p_convex, (VSInstance **)p_result_array, res);
}
return res;
}
@@ -4011,6 +4075,10 @@ bool VisualServerScene::free(RID p_rid) {
RoomGroup *roomgroup = roomgroup_owner.get(p_rid);
roomgroup_owner.free(p_rid);
memdelete(roomgroup);
} else if (occluder_owner.owns(p_rid)) {
Occluder *ro = occluder_owner.get(p_rid);
occluder_owner.free(p_rid);
memdelete(ro);
} else {
return false;
}