From a9c0756da4d49391d6db77a113641870b74eb30e Mon Sep 17 00:00:00 2001 From: Josue Date: Fri, 21 Jul 2023 17:45:59 -0500 Subject: [PATCH] Improve calculation of min and max zoom From master branch. Fix: https://gitlab.com/kicad/code/kicad/-/issues/15078 --- .../3d_rendering/raytracing/create_scene.cpp | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/3d-viewer/3d_rendering/raytracing/create_scene.cpp b/3d-viewer/3d_rendering/raytracing/create_scene.cpp index 9d51214eac..f2b0d852fe 100644 --- a/3d-viewer/3d_rendering/raytracing/create_scene.cpp +++ b/3d-viewer/3d_rendering/raytracing/create_scene.cpp @@ -931,10 +931,33 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe { float ratio = std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D ); - m_camera.SetMaxZoom( CAMERA::DEFAULT_MAX_ZOOM * ratio ); - m_camera.SetMinZoom( static_cast( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits() - / -m_camera.GetCameraInitPos().z ) ); + float max_zoom = CAMERA::DEFAULT_MAX_ZOOM * ratio; + float min_zoom = static_cast( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits() + / -m_camera.GetCameraInitPos().z ); + + if( min_zoom > max_zoom ) + std::swap( min_zoom, max_zoom ); + + float zoom_ratio = max_zoom / min_zoom; + + // Set the minimum number of zoom 'steps' between max and min. + int steps = 3 * 3; + steps -= static_cast( ceil( log( zoom_ratio ) / log( 1.26f ) ) ); + steps = std::max( steps, 0 ); + + // Resize max and min zoom to accomplish the number of steps. + float increased_zoom = pow( 1.26f, steps / 2 ); + max_zoom *= increased_zoom; + min_zoom /= increased_zoom; + + if( steps & 1 ) + min_zoom /= 1.26f; + + min_zoom = std::min( min_zoom, 1.0f ); + + m_camera.SetMaxZoom( max_zoom ); + m_camera.SetMinZoom( min_zoom ); } // Create an accelerator