Portals - Allow user to set roaming expansion margin
Previously a crude metric was used to decide on the roaming expansion margin, but it created unexpected results in some scenarios. Instead this setting is exposed to the user via the RoomManager, allowing them to tailor it to the world size, room sizes, roaming objects sizes and the speeds of movement.
(cherry picked from commit 788f075b44
)
This commit is contained in:
parent
fc749f7f8b
commit
7de023e192
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -598,7 +598,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> &)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -521,7 +521,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> &)
|
||||
|
||||
|
|
|
@ -921,7 +921,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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue