From df40159ce76d734bf69c0d0649c6789d5bce1410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ignacio=20Romero?= Date: Tue, 6 Sep 2016 18:43:15 -0500 Subject: [PATCH] Pixel perfect panning for the 3D viewer Use the correct math to unproject the mouse movement from screen space to the Z=0 plane on the camera space. This handles both perspective and orthographic projection at any window size or zoom level. --- 3d-viewer/3d_rendering/ctrack_ball.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/3d-viewer/3d_rendering/ctrack_ball.cpp b/3d-viewer/3d_rendering/ctrack_ball.cpp index 95ddb71245..f908c806bb 100644 --- a/3d-viewer/3d_rendering/ctrack_ball.cpp +++ b/3d-viewer/3d_rendering/ctrack_ball.cpp @@ -96,14 +96,20 @@ void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition ) { m_parametersChanged = true; - // Current zoom and an additional factor are taken into account - // for the amount of panning. - - const float zoom = std::min( m_zoom, 1.0f ); - const float panFactor = m_range_scale * zoom * (zoom * 4.0f); - - m_camera_pos.x -= panFactor * ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x; - m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y; + if( m_projectionType == PROJECTION_ORTHO ) + { + // With the ortographic projection, there is just a zoom factor + const float panFactor = m_zoom / 37.5f; // Magic number from CCAMERA::rebuildProjection + m_camera_pos.x -= panFactor * ( m_lastPosition.x - aNewMousePosition.x ); + m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ); + } + else // PROJECTION_PERSPECTIVE + { + // Unproject the coordinates using the precomputed frustum tangent (zoom level dependent) + const float panFactor = -m_camera_pos.z * m_frustum.tang * 2; + m_camera_pos.x -= panFactor * m_frustum.ratio * ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x; + m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y; + } updateViewMatrix(); updateFrustum();