From 93c78af488fb0a390b66450c9860afdc02510cca Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sat, 31 Jul 2021 07:53:17 +0100 Subject: [PATCH] Portals - disable frustum culling gizmos with preview camera When using the preview camera feature it turns out as well as culling the game objects, this also culls the editor gizmos from the preview camera, which makes the editor hard to use in this mode. To get around this problem we simply disable frustum culling for GLOBAL portal_mode objects when in preview camera mode. This could be a bit slower in an editor scene with lots of gizmos but is the simplest way of solving the problem. --- servers/visual/portals/portal_renderer.cpp | 2 +- servers/visual/portals/portal_tracer.cpp | 54 +++++++++++++++------- servers/visual/portals/portal_tracer.h | 2 +- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/servers/visual/portals/portal_renderer.cpp b/servers/visual/portals/portal_renderer.cpp index 41cb04fa6bf..fcf4a983502 100644 --- a/servers/visual/portals/portal_renderer.cpp +++ b/servers/visual/portals/portal_renderer.cpp @@ -994,7 +994,7 @@ int PortalRenderer::cull_convex_implementation(const Vector3 &p_point, const Vec return out_count; } - out_count = _tracer.trace_globals(planes, p_result_array, out_count, p_result_max, p_mask); + out_count = _tracer.trace_globals(planes, p_result_array, out_count, p_result_max, p_mask, _override_camera); return out_count; } diff --git a/servers/visual/portals/portal_tracer.cpp b/servers/visual/portals/portal_tracer.cpp index 00d002760b8..18a76d20b1a 100644 --- a/servers/visual/portals/portal_tracer.cpp +++ b/servers/visual/portals/portal_tracer.cpp @@ -228,36 +228,56 @@ void PortalTracer::cull_statics(const VSRoom &p_room, const LocalVector & } // for n through statics } -int PortalTracer::trace_globals(const LocalVector &p_planes, VSInstance **p_result_array, int first_result, int p_result_max, uint32_t p_mask) { +int PortalTracer::trace_globals(const LocalVector &p_planes, VSInstance **p_result_array, int first_result, int p_result_max, uint32_t p_mask, bool p_override_camera) { uint32_t num_globals = _portal_renderer->get_num_moving_globals(); int current_result = first_result; - for (uint32_t n = 0; n < num_globals; n++) { - const PortalRenderer::Moving &moving = _portal_renderer->get_moving_global(n); + if (!p_override_camera) { + for (uint32_t n = 0; n < num_globals; n++) { + const PortalRenderer::Moving &moving = _portal_renderer->get_moving_global(n); #ifdef PORTAL_RENDERER_STORE_MOVING_RIDS - // debug check the instance is valid - void *vss_instance = VSG::scene->_instance_get_from_rid(moving.instance_rid); + // debug check the instance is valid + void *vss_instance = VSG::scene->_instance_get_from_rid(moving.instance_rid); - if (vss_instance) { + if (vss_instance) { #endif - if (test_cull_inside(moving.exact_aabb, p_planes, false)) { - if (VSG::scene->_instance_cull_check(moving.instance, p_mask)) { - p_result_array[current_result++] = moving.instance; + if (test_cull_inside(moving.exact_aabb, p_planes, false)) { + if (VSG::scene->_instance_cull_check(moving.instance, p_mask)) { + p_result_array[current_result++] = moving.instance; - // full up? - if (current_result >= p_result_max) { - return current_result; + // full up? + if (current_result >= p_result_max) { + return current_result; + } } } - } #ifdef PORTAL_RENDERER_STORE_MOVING_RIDS - } else { - WARN_PRINT("vss instance is null " + PortalRenderer::_addr_to_string(moving.instance)); - } + } else { + WARN_PRINT("vss instance is null " + PortalRenderer::_addr_to_string(moving.instance)); + } #endif - } + } + } // if not override camera + else { + // If we are overriding the camera there is a potential problem in the editor: + // gizmos BEHIND the override camera will not be drawn. + // As this should be editor only and performance is not critical, we will just disable + // frustum culling for global objects when the camera is overriden. + for (uint32_t n = 0; n < num_globals; n++) { + const PortalRenderer::Moving &moving = _portal_renderer->get_moving_global(n); + + if (VSG::scene->_instance_cull_check(moving.instance, p_mask)) { + p_result_array[current_result++] = moving.instance; + + // full up? + if (current_result >= p_result_max) { + return current_result; + } + } + } + } // if override camera return current_result; } diff --git a/servers/visual/portals/portal_tracer.h b/servers/visual/portals/portal_tracer.h index 7f0de7856a7..12861a93211 100644 --- a/servers/visual/portals/portal_tracer.h +++ b/servers/visual/portals/portal_tracer.h @@ -105,7 +105,7 @@ public: void trace(PortalRenderer &p_portal_renderer, const Vector3 &p_pos, const LocalVector &p_planes, int p_start_room_id, TraceResult &r_result); // globals are handled separately as they don't care about the rooms - int trace_globals(const LocalVector &p_planes, VSInstance **p_result_array, int first_result, int p_result_max, uint32_t p_mask); + int trace_globals(const LocalVector &p_planes, VSInstance **p_result_array, int first_result, int p_result_max, uint32_t p_mask, bool p_override_camera); void set_depth_limit(int p_limit) { _depth_limit = p_limit; }