Merge pull request #54921 from lawnjelly/portals_roaming_margin

This commit is contained in:
Rémi Verschelde 2021-11-15 22:45:46 +01:00 committed by GitHub
commit 89792e5c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 29 additions and 22 deletions

View File

@ -75,6 +75,11 @@
Optionally during conversion the potentially visible set (PVS) of rooms that are potentially visible from each room can be calculated. This can be used either to aid in dynamic portal culling, or to totally replace portal culling.
In [code]Full[/code] PVS Mode, all objects within the potentially visible rooms will be frustum culled, and rendered if they are within the view frustum.
</member>
<member name="roaming_expansion_margin" type="float" setter="set_roaming_expansion_margin" getter="get_roaming_expansion_margin" default="1.0">
In order to reduce processing for roaming objects, an expansion is applied to their AABB as they move. This expanded volume is used to calculate which rooms the roaming object is within. If the object's exact AABB is still within this expanded volume on the next move, there is no need to reprocess the object, which can save considerable CPU.
The downside is that if the expansion is too much, the object may end up unexpectedly sprawling into neighbouring rooms and showing up where it might otherwise be culled.
In order to balance roaming performance against culling accuracy, this expansion margin can be customized by the user. It will typically depend on your room and object sizes, and movement speeds. The default value should work reasonably in most circumstances.
</member>
<member name="room_simplify" type="float" setter="set_room_simplify" getter="get_room_simplify" default="0.5">
During the conversion process, the geometry of objects within [Room]s, or a custom specified manual bound, are used to generate a [b]convex hull bound[/b].
This convex hull is [b]required[/b] in the visibility system, and is used for many purposes. Most importantly, it is used to decide whether the [Camera] (or an object) is within a [Room]. The convex hull generating algorithm is good, but occasionally it can create too many (or too few) planes to give a good representation of the room volume.

View File

@ -313,6 +313,7 @@ void RoomManager::_bind_methods() {
LIMPL_PROPERTY_RANGE(Variant::INT, portal_depth_limit, set_portal_depth_limit, get_portal_depth_limit, "0,255,1");
LIMPL_PROPERTY_RANGE(Variant::REAL, room_simplify, set_room_simplify, get_room_simplify, "0.0,1.0,0.005");
LIMPL_PROPERTY_RANGE(Variant::REAL, default_portal_margin, set_default_portal_margin, get_default_portal_margin, "0.0, 10.0, 0.01");
LIMPL_PROPERTY_RANGE(Variant::REAL, roaming_expansion_margin, set_roaming_expansion_margin, get_roaming_expansion_margin, "0.0, 3.0, 0.01");
#undef LIMPL_PROPERTY
#undef LIMPL_PROPERTY_RANGE
@ -382,7 +383,15 @@ void RoomManager::set_portal_depth_limit(int p_limit) {
_settings_portal_depth_limit = p_limit;
if (is_inside_world() && get_world().is_valid()) {
VisualServer::get_singleton()->rooms_set_params(get_world()->get_scenario(), p_limit);
VisualServer::get_singleton()->rooms_set_params(get_world()->get_scenario(), p_limit, _settings_roaming_expansion_margin);
}
}
void RoomManager::set_roaming_expansion_margin(real_t p_dist) {
_settings_roaming_expansion_margin = p_dist;
if (is_inside_world() && get_world().is_valid()) {
VisualServer::get_singleton()->rooms_set_params(get_world()->get_scenario(), _settings_portal_depth_limit, _settings_roaming_expansion_margin);
}
}

View File

@ -88,6 +88,9 @@ public:
void set_portal_depth_limit(int p_limit);
int get_portal_depth_limit() const { return _settings_portal_depth_limit; }
void set_roaming_expansion_margin(real_t p_dist);
real_t get_roaming_expansion_margin() const { return _settings_roaming_expansion_margin; }
void set_pvs_mode(PVSMode p_mode);
PVSMode get_pvs_mode() const;
@ -256,6 +259,7 @@ private:
real_t _overlap_warning_threshold = 1.0;
Room::SimplifyInfo _room_simplify_info;
int _settings_portal_depth_limit = 16;
real_t _settings_roaming_expansion_margin = 1.0;
// debug override camera
ObjectID _godot_preview_camera_ID = -1;

View File

@ -822,20 +822,6 @@ void PortalRenderer::rooms_finalize(bool p_generate_pvs, bool p_cull_using_pvs,
// from position
_rooms_lookup_bsp.create(*this);
// calculate the roaming expansion margin based on the average room size
Vector3 total_size = Vector3(0, 0, 0);
for (int n = 0; n < get_num_rooms(); n++) {
total_size += get_room(n)._aabb.size;
}
if (get_num_rooms()) {
total_size /= get_num_rooms();
AABB temp;
temp.size = total_size;
// longest axis of average room * fudge factor
_roaming_expansion_margin = temp.get_longest_axis_size() * 0.08;
}
// calculate PVS
if (p_generate_pvs) {
PVSBuilder pvs;

View File

@ -156,7 +156,10 @@ public:
void rooms_finalize(bool p_generate_pvs, bool p_cull_using_pvs, bool p_use_secondary_pvs, bool p_use_signals, String p_pvs_filename, bool p_use_simple_pvs, bool p_log_pvs_generation);
void rooms_override_camera(bool p_override, const Vector3 &p_point, const Vector<Plane> *p_convex);
void rooms_set_active(bool p_active) { _active = p_active; }
void rooms_set_params(int p_portal_depth_limit) { _tracer.set_depth_limit(p_portal_depth_limit); }
void rooms_set_params(int p_portal_depth_limit, real_t p_roaming_expansion_margin) {
_tracer.set_depth_limit(p_portal_depth_limit);
_roaming_expansion_margin = p_roaming_expansion_margin;
}
void rooms_set_cull_using_pvs(bool p_enable) { _cull_using_pvs = p_enable; }
void rooms_update_gameplay_monitor(const Vector<Vector3> &p_camera_positions);

View File

@ -600,7 +600,7 @@ public:
BIND8(rooms_finalize, RID, bool, bool, bool, bool, String, bool, bool)
BIND4(rooms_override_camera, RID, bool, const Vector3 &, const Vector<Plane> *)
BIND2(rooms_set_active, RID, bool)
BIND2(rooms_set_params, RID, int)
BIND3(rooms_set_params, RID, int, real_t)
BIND3(rooms_set_debug_feature, RID, RoomsDebugFeature, bool)
BIND2(rooms_update_gameplay_monitor, RID, const Vector<Vector3> &)

View File

@ -1346,10 +1346,10 @@ void VisualServerScene::rooms_set_active(RID p_scenario, bool p_active) {
scenario->_portal_renderer.rooms_set_active(p_active);
}
void VisualServerScene::rooms_set_params(RID p_scenario, int p_portal_depth_limit) {
void VisualServerScene::rooms_set_params(RID p_scenario, int p_portal_depth_limit, real_t p_roaming_expansion_margin) {
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->_portal_renderer.rooms_set_params(p_portal_depth_limit);
scenario->_portal_renderer.rooms_set_params(p_portal_depth_limit, p_roaming_expansion_margin);
}
void VisualServerScene::rooms_set_debug_feature(RID p_scenario, VisualServer::RoomsDebugFeature p_feature, bool p_active) {

View File

@ -668,7 +668,7 @@ public:
virtual void rooms_finalize(RID p_scenario, bool p_generate_pvs, bool p_cull_using_pvs, bool p_use_secondary_pvs, bool p_use_signals, String p_pvs_filename, bool p_use_simple_pvs, bool p_log_pvs_generation);
virtual void rooms_override_camera(RID p_scenario, bool p_override, const Vector3 &p_point, const Vector<Plane> *p_convex);
virtual void rooms_set_active(RID p_scenario, bool p_active);
virtual void rooms_set_params(RID p_scenario, int p_portal_depth_limit);
virtual void rooms_set_params(RID p_scenario, int p_portal_depth_limit, real_t p_roaming_expansion_margin);
virtual void rooms_set_debug_feature(RID p_scenario, VisualServer::RoomsDebugFeature p_feature, bool p_active);
virtual void rooms_update_gameplay_monitor(RID p_scenario, const Vector<Vector3> &p_camera_positions);

View File

@ -523,7 +523,7 @@ public:
FUNC8(rooms_finalize, RID, bool, bool, bool, bool, String, bool, bool)
FUNC4(rooms_override_camera, RID, bool, const Vector3 &, const Vector<Plane> *)
FUNC2(rooms_set_active, RID, bool)
FUNC2(rooms_set_params, RID, int)
FUNC3(rooms_set_params, RID, int, real_t)
FUNC3(rooms_set_debug_feature, RID, RoomsDebugFeature, bool)
FUNC2(rooms_update_gameplay_monitor, RID, const Vector<Vector3> &)

View File

@ -926,7 +926,7 @@ public:
virtual void rooms_finalize(RID p_scenario, bool p_generate_pvs, bool p_cull_using_pvs, bool p_use_secondary_pvs, bool p_use_signals, String p_pvs_filename, bool p_use_simple_pvs, bool p_log_pvs_generation) = 0;
virtual void rooms_override_camera(RID p_scenario, bool p_override, const Vector3 &p_point, const Vector<Plane> *p_convex) = 0;
virtual void rooms_set_active(RID p_scenario, bool p_active) = 0;
virtual void rooms_set_params(RID p_scenario, int p_portal_depth_limit) = 0;
virtual void rooms_set_params(RID p_scenario, int p_portal_depth_limit, real_t p_roaming_expansion_margin) = 0;
virtual void rooms_set_debug_feature(RID p_scenario, RoomsDebugFeature p_feature, bool p_active) = 0;
virtual void rooms_update_gameplay_monitor(RID p_scenario, const Vector<Vector3> &p_camera_positions) = 0;