Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenricoturri1966 <enricoturri@seznam.cz>2022-06-29 13:14:41 +0300
committerenricoturri1966 <enricoturri@seznam.cz>2022-06-29 13:14:41 +0300
commit39b1222b220c5f4aa14354b1c9fff807d8094b1d (patch)
tree191cbee928ae941af02cf567eebaf8b7faed4b5d
parentae76468f7c844ef442bebb00421589918752bdde (diff)
Tech ENABLE_RAYCAST_PICKING - Rendering for rectangle selection made only inside the rectangle, on systems supporting framebufferset_raycast_picking_rebase
-rw-r--r--src/slic3r/GUI/Camera.cpp125
-rw-r--r--src/slic3r/GUI/Camera.hpp18
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp147
-rw-r--r--src/slic3r/GUI/GLCanvas3D.hpp4
4 files changed, 294 insertions, 0 deletions
diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp
index 1370484c3..56980c43a 100644
--- a/src/slic3r/GUI/Camera.cpp
+++ b/src/slic3r/GUI/Camera.cpp
@@ -91,6 +91,80 @@ void Camera::select_view(const std::string& direction)
look_at(m_target + m_distance * Vec3d::UnitY(), m_target, Vec3d::UnitZ());
}
+#if ENABLE_RAYCAST_PICKING
+double Camera::get_near_left() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) - 1.0) / m_projection_matrix.matrix()(0, 0);
+ default:
+ case EType::Ortho:
+ return -1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
+ }
+}
+
+double Camera::get_near_right() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) + 1.0) / m_projection_matrix.matrix()(0, 0);
+ default:
+ case EType::Ortho:
+ return 1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
+ }
+}
+
+double Camera::get_near_top() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) + 1.0) / m_projection_matrix.matrix()(1, 1);
+ default:
+ case EType::Ortho:
+ return 1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
+ }
+}
+
+double Camera::get_near_bottom() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) - 1.0) / m_projection_matrix.matrix()(1, 1);
+ default:
+ case EType::Ortho:
+ return -1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
+ }
+}
+
+double Camera::get_near_width() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(0, 0);
+ default:
+ case EType::Ortho:
+ return 2.0 / m_projection_matrix.matrix()(0, 0);
+ }
+}
+
+double Camera::get_near_height() const
+{
+ switch (m_type)
+ {
+ case EType::Perspective:
+ return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(1, 1);
+ default:
+ case EType::Ortho:
+ return 2.0 / m_projection_matrix.matrix()(1, 1);
+ }
+}
+#endif // ENABLE_RAYCAST_PICKING
+
double Camera::get_fov() const
{
switch (m_type)
@@ -103,6 +177,21 @@ double Camera::get_fov() const
};
}
+#if ENABLE_RAYCAST_PICKING
+void Camera::set_viewport(int x, int y, unsigned int w, unsigned int h)
+{
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ m_viewport = { 0, 0, int(w), int(h) };
+#else
+ glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+}
+
+void Camera::apply_viewport() const
+{
+ glsafe(::glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]));
+}
+#else
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
{
glsafe(::glViewport(0, 0, w, h));
@@ -112,6 +201,7 @@ void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
+#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void Camera::apply_view_matrix()
@@ -170,6 +260,9 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_RAYCAST_PICKING
+ apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second);
+#else
switch (m_type)
{
default:
@@ -197,6 +290,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
break;
}
}
+#endif // ENABLE_RAYCAST_PICKING
#else
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
@@ -221,6 +315,37 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
+#if ENABLE_RAYCAST_PICKING
+void Camera::apply_projection(double left, double right, double bottom, double top, double near_z, double far_z)
+{
+ assert(left != right && bottom != top && near_z != far_z);
+ const double inv_dx = 1.0 / (right - left);
+ const double inv_dy = 1.0 / (top - bottom);
+ const double inv_dz = 1.0 / (far_z - near_z);
+
+ switch (m_type)
+ {
+ default:
+ case EType::Ortho:
+ {
+ m_projection_matrix.matrix() << 2.0 * inv_dx, 0.0, 0.0, -(left + right) * inv_dx,
+ 0.0, 2.0 * inv_dy, 0.0, -(bottom + top) * inv_dy,
+ 0.0, 0.0, -2.0 * inv_dz, -(near_z + far_z) * inv_dz,
+ 0.0, 0.0, 0.0, 1.0;
+ break;
+ }
+ case EType::Perspective:
+ {
+ m_projection_matrix.matrix() << 2.0 * near_z * inv_dx, 0.0, (left + right) * inv_dx, 0.0,
+ 0.0, 2.0 * near_z * inv_dy, (bottom + top) * inv_dy, 0.0,
+ 0.0, 0.0, -(near_z + far_z) * inv_dz, -2.0 * near_z * far_z * inv_dz,
+ 0.0, 0.0, -1.0, 0.0;
+ break;
+ }
+ }
+}
+#endif // ENABLE_RAYCAST_PICKING
+
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
{
// Calculate the zoom factor needed to adjust the view around the given box.
diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp
index a1d742688..b2672e14e 100644
--- a/src/slic3r/GUI/Camera.hpp
+++ b/src/slic3r/GUI/Camera.hpp
@@ -89,9 +89,23 @@ public:
double get_far_z() const { return m_frustrum_zs.second; }
const std::pair<double, double>& get_z_range() const { return m_frustrum_zs; }
+#if ENABLE_RAYCAST_PICKING
+ double get_near_left() const;
+ double get_near_right() const;
+ double get_near_top() const;
+ double get_near_bottom() const;
+ double get_near_width() const;
+ double get_near_height() const;
+#endif // ENABLE_RAYCAST_PICKING
+
double get_fov() const;
+#if ENABLE_RAYCAST_PICKING
+ void set_viewport(int x, int y, unsigned int w, unsigned int h);
+ void apply_viewport() const;
+#else
void apply_viewport(int x, int y, unsigned int w, unsigned int h);
+#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
@@ -99,6 +113,10 @@ public:
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);
+#if ENABLE_RAYCAST_PICKING
+ void apply_projection(double left, double right, double bottom, double top, double near_z, double far_z);
+#endif // ENABLE_RAYCAST_PICKING
+
void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor);
void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor);
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 582c6349a..4b3dd163f 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1628,7 +1628,12 @@ void GLCanvas3D::render()
// and the viewport was set incorrectly, leading to tripping glAsserts further down
// the road (in apply_projection). That's why the minimum size is forced to 10.
Camera& camera = wxGetApp().plater()->get_camera();
+#if ENABLE_RAYCAST_PICKING
+ camera.set_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
+ camera.apply_viewport();
+#else
camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
+#endif // ENABLE_RAYCAST_PICKING
if (camera.requires_zoom_to_bed) {
zoom_to_bed();
@@ -4606,7 +4611,12 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
Camera camera;
camera.set_type(camera_type);
camera.set_scene_box(scene_bounding_box());
+#if ENABLE_RAYCAST_PICKING
+ camera.set_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
+ camera.apply_viewport();
+#else
camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
+#endif // ENABLE_RAYCAST_PICKING
camera.zoom_to_box(volumes_box);
#if ENABLE_LEGACY_OPENGL_REMOVAL
@@ -4908,7 +4918,11 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
// restore the default framebuffer size to avoid flickering on the 3D scene
+#if ENABLE_RAYCAST_PICKING
+ wxGetApp().plater()->get_camera().apply_viewport();
+#else
wxGetApp().plater()->get_camera().apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height());
+#endif // ENABLE_RAYCAST_PICKING
}
bool GLCanvas3D::_init_toolbars()
@@ -5567,6 +5581,58 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
std::set<int> idxs;
if (m_picking_enabled) {
+#if ENABLE_RAYCAST_PICKING
+ const size_t width = std::max<size_t>(m_rectangle_selection.get_width(), 1);
+ const size_t height = std::max<size_t>(m_rectangle_selection.get_height(), 1);
+
+ const OpenGLManager::EFramebufferType framebuffers_type = OpenGLManager::get_framebuffers_type();
+ bool use_framebuffer = framebuffers_type != OpenGLManager::EFramebufferType::Unknown;
+
+ GLuint render_fbo = 0;
+ GLuint render_tex = 0;
+ GLuint render_depth = 0;
+ if (use_framebuffer) {
+ // setup a framebuffer which covers only the selection rectangle
+ if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
+ glsafe(::glGenFramebuffers(1, &render_fbo));
+ glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, render_fbo));
+ }
+ else {
+ glsafe(::glGenFramebuffersEXT(1, &render_fbo));
+ glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, render_fbo));
+ }
+ glsafe(::glGenTextures(1, &render_tex));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+ if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
+ glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0));
+ glsafe(::glGenRenderbuffers(1, &render_depth));
+ glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth));
+ glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height));
+ glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth));
+ }
+ else {
+ glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, render_tex, 0));
+ glsafe(::glGenRenderbuffersEXT(1, &render_depth));
+ glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_depth));
+ glsafe(::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height));
+ glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_depth));
+ }
+ const GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 };
+ glsafe(::glDrawBuffers(1, drawBufs));
+ if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
+ if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ use_framebuffer = false;
+ }
+ else {
+ if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
+ use_framebuffer = false;
+ }
+ }
+#endif // ENABLE_RAYCAST_PICKING
+
if (m_multisample_allowed)
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
glsafe(::glDisable(GL_MULTISAMPLE));
@@ -5576,10 +5642,49 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
+#if ENABLE_RAYCAST_PICKING
+ const Camera& main_camera = wxGetApp().plater()->get_camera();
+ Camera framebuffer_camera;
+ const Camera* camera = &main_camera;
+ if (use_framebuffer) {
+ // setup a camera which covers only the selection rectangle
+ const std::array<int, 4>& viewport = camera->get_viewport();
+ const double near_left = camera->get_near_left();
+ const double near_bottom = camera->get_near_bottom();
+ const double near_width = camera->get_near_width();
+ const double near_height = camera->get_near_height();
+
+ const double ratio_x = near_width / double(viewport[2]);
+ const double ratio_y = near_height / double(viewport[3]);
+
+ const double rect_near_left = near_left + double(m_rectangle_selection.get_left()) * ratio_x;
+ const double rect_near_bottom = near_bottom + (double(viewport[3]) - double(m_rectangle_selection.get_bottom())) * ratio_y;
+ double rect_near_right = near_left + double(m_rectangle_selection.get_right()) * ratio_x;
+ double rect_near_top = near_bottom + (double(viewport[3]) - double(m_rectangle_selection.get_top())) * ratio_y;
+
+ if (rect_near_left == rect_near_right)
+ rect_near_right = rect_near_left + ratio_x;
+ if (rect_near_bottom == rect_near_top)
+ rect_near_top = rect_near_bottom + ratio_y;
+
+ framebuffer_camera.look_at(camera->get_position(), camera->get_target(), camera->get_dir_up());
+ framebuffer_camera.apply_projection(rect_near_left, rect_near_right, rect_near_bottom, rect_near_top, camera->get_near_z(), camera->get_far_z());
+ framebuffer_camera.set_viewport(0, 0, width, height);
+ framebuffer_camera.apply_viewport();
+ camera = &framebuffer_camera;
+ }
+
+ _render_volumes_for_picking(*camera);
+#else
_render_volumes_for_picking();
+#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_RAYCAST_PICKING
+ _render_bed_for_picking(camera->get_view_matrix(), camera->get_projection_matrix(), !camera->is_looking_downward());
+#else
const Camera& camera = wxGetApp().plater()->get_camera();
_render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward());
+#endif // ENABLE_RAYCAST_PICKING
#else
_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
@@ -5587,6 +5692,12 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
if (m_multisample_allowed)
glsafe(::glEnable(GL_MULTISAMPLE));
+#if ENABLE_RAYCAST_PICKING
+ const size_t px_count = width * height;
+
+ const size_t left = use_framebuffer ? 0 : (size_t)m_rectangle_selection.get_left();
+ const size_t top = use_framebuffer ? 0 : (size_t)get_canvas_size().get_height() - (size_t)m_rectangle_selection.get_top();
+#else
int width = std::max((int)m_rectangle_selection.get_width(), 1);
int height = std::max((int)m_rectangle_selection.get_height(), 1);
int px_count = width * height;
@@ -5594,6 +5705,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
int left = (int)m_rectangle_selection.get_left();
int top = get_canvas_size().get_height() - (int)m_rectangle_selection.get_top();
if (left >= 0 && top >= 0) {
+#endif // ENABLE_RAYCAST_PICKING
#define USE_PARALLEL 1
#if USE_PARALLEL
struct Pixel
@@ -5635,7 +5747,30 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
idxs.insert(volume_id);
}
#endif // USE_PARALLEL
+#if ENABLE_RAYCAST_PICKING
+ if (camera != &main_camera)
+ main_camera.apply_viewport();
+
+ if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
+ glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
+ if (render_depth != 0)
+ glsafe(::glDeleteRenderbuffers(1, &render_depth));
+ if (render_fbo != 0)
+ glsafe(::glDeleteFramebuffers(1, &render_fbo));
+ }
+ else if (framebuffers_type == OpenGLManager::EFramebufferType::Ext) {
+ glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+ if (render_depth != 0)
+ glsafe(::glDeleteRenderbuffersEXT(1, &render_depth));
+ if (render_fbo != 0)
+ glsafe(::glDeleteFramebuffersEXT(1, &render_fbo));
+ }
+
+ if (render_tex != 0)
+ glsafe(::glDeleteTextures(1, &render_tex));
+#else
}
+#endif // ENABLE_RAYCAST_PICKING
}
m_hover_volume_idxs.assign(idxs.begin(), idxs.end());
@@ -6038,7 +6173,11 @@ void GLCanvas3D::_render_overlays()
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
+#if ENABLE_RAYCAST_PICKING
+void GLCanvas3D::_render_volumes_for_picking(const Camera& camera) const
+#else
void GLCanvas3D::_render_volumes_for_picking() const
+#endif // ENABLE_RAYCAST_PICKING
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat_clip");
@@ -6054,7 +6193,11 @@ void GLCanvas3D::_render_volumes_for_picking() const
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_RAYCAST_PICKING
+ const Transform3d& view_matrix = camera.get_view_matrix();
+#else
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
+#endif // ENABLE_RAYCAST_PICKING
for (size_t type = 0; type < 2; ++ type) {
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
for (const GLVolumeWithIdAndZ& volume : to_render)
@@ -6066,8 +6209,12 @@ void GLCanvas3D::_render_volumes_for_picking() const
#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.first->model.set_color(picking_decode(id));
shader->start_using();
+#if ENABLE_RAYCAST_PICKING
+ shader->set_uniform("view_model_matrix", view_matrix * volume.first->world_matrix());
+#else
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix());
+#endif // ENABLE_RAYCAST_PICKING
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
shader->set_uniform("z_range", m_volumes.get_z_range());
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 22c237e29..8f4efffd8 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -997,7 +997,11 @@ private:
#endif // ENABLE_RENDER_SELECTION_CENTER
void _check_and_update_toolbar_icon_scale();
void _render_overlays();
+#if ENABLE_RAYCAST_PICKING
+ void _render_volumes_for_picking(const Camera& camera) const;
+#else
void _render_volumes_for_picking() const;
+#endif // ENABLE_RAYCAST_PICKING
void _render_current_gizmo() const;
void _render_gizmos_overlay();
void _render_main_toolbar();