You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-10 13:00:37 +00:00
Sphere occluders (portals and general use)
Add framework for supporting geometrical occluders within rooms, and add support for sphere occluders. Includes gizmos for editing. They also work outside the portal system.
This commit is contained in:
@@ -1156,6 +1156,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;
|
||||
@@ -1396,6 +1457,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;
|
||||
}
|
||||
@@ -4010,6 +4074,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