You've already forked godot
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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user