diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.cpp b/3d-viewer/3d_canvas/eda_3d_canvas.cpp index f01bcb7b3f..1442563bea 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.cpp +++ b/3d-viewer/3d_canvas/eda_3d_canvas.cpp @@ -73,6 +73,11 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS ) EVT_MOTION( EDA_3D_CANVAS::OnMouseMove ) EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify ) + // touch gesture events + EVT_GESTURE_ZOOM( wxID_ANY, EDA_3D_CANVAS::OnZoomGesture ) + EVT_GESTURE_PAN( wxID_ANY, EDA_3D_CANVAS::OnPanGesture ) + EVT_GESTURE_ROTATE( wxID_ANY, EDA_3D_CANVAS::OnRotateGesture ) + // other events EVT_ERASE_BACKGROUND( EDA_3D_CANVAS::OnEraseBackground ) EVT_CUSTOM(wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest ) @@ -144,6 +149,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib wxASSERT( a3DCachePointer != nullptr ); m_boardAdapter.Set3dCacheManager( a3DCachePointer ); + EnableTouchEvents( wxTOUCH_ZOOM_GESTURE | wxTOUCH_PAN_GESTURES | wxTOUCH_ROTATE_GESTURE ); + const wxEventType events[] = { // Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events, @@ -631,6 +638,75 @@ void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event ) } +void EDA_3D_CANVAS::OnZoomGesture( wxZoomGestureEvent& aEvent ) +{ + SetFocus(); + + if( aEvent.IsGestureStart() ) + { + m_gestureLastZoomFactor = 1.0; + m_camera.SetCurMousePosition( aEvent.GetPosition() ); + } + + if( m_camera_is_moving ) + return; + + restart_editingTimeOut_Timer(); + + m_camera.Pan( aEvent.GetPosition() ); + m_camera.SetCurMousePosition( aEvent.GetPosition() ); + + m_camera.Zoom( aEvent.GetZoomFactor() / m_gestureLastZoomFactor ); + + m_gestureLastZoomFactor = aEvent.GetZoomFactor(); + + DisplayStatus(); + Request_refresh(); +} + + +void EDA_3D_CANVAS::OnPanGesture( wxPanGestureEvent& aEvent ) +{ + SetFocus(); + + if( aEvent.IsGestureStart() ) + m_camera.SetCurMousePosition( aEvent.GetPosition() ); + + if( m_camera_is_moving ) + return; + + m_camera.Pan( aEvent.GetPosition() ); + m_camera.SetCurMousePosition( aEvent.GetPosition() ); + + DisplayStatus(); + Request_refresh(); +} + + +void EDA_3D_CANVAS::OnRotateGesture( wxRotateGestureEvent& aEvent ) +{ + SetFocus(); + + if( aEvent.IsGestureStart() ) + { + m_gestureLastAngle = 0; + m_camera.SetCurMousePosition( aEvent.GetPosition() ); + + // We don't want to process the first angle + return; + } + + if( m_camera_is_moving ) + return; + + m_camera.RotateScreen( m_gestureLastAngle - aEvent.GetRotationAngle() ); + m_gestureLastAngle = aEvent.GetRotationAngle(); + + DisplayStatus(); + Request_refresh(); +} + + void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event ) { if( m_3d_render && m_3d_render->IsReloadRequestPending() ) diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.h b/3d-viewer/3d_canvas/eda_3d_canvas.h index 6eef97c641..77834f0fdc 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.h +++ b/3d-viewer/3d_canvas/eda_3d_canvas.h @@ -237,6 +237,10 @@ private: void OnResize( wxSizeEvent& event ); void OnTimerTimeout_Redraw( wxTimerEvent& event ); + void OnZoomGesture( wxZoomGestureEvent& event ); + void OnPanGesture( wxPanGestureEvent& event ); + void OnRotateGesture( wxRotateGestureEvent& event ); + DECLARE_EVENT_TABLE() /** @@ -324,6 +328,10 @@ private: bool m_render3dmousePivot = false; // Render the 3dmouse pivot SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot + ///< Used to track gesture events. + double m_gestureLastZoomFactor = 1.0; + double m_gestureLastAngle = 0.0; + /** * Trace mask used to enable or disable the trace output of this class. * The debug output can be turned on by setting the WXTRACE environment variable to diff --git a/common/gal/3d/camera.cpp b/common/gal/3d/camera.cpp index 7035af2322..a8361e98f5 100644 --- a/common/gal/3d/camera.cpp +++ b/common/gal/3d/camera.cpp @@ -647,6 +647,14 @@ bool CAMERA::Zoom_T1( float aFactor ) } +void CAMERA::RotateScreen( float aAngleInRadians ) +{ + glm::mat4 matrix = GetRotationMatrix(); + SetRotationMatrix( glm::rotate( matrix, aAngleInRadians, GetDir() ) ); + updateRotationMatrix(); +} + + void CAMERA::RotateX( float aAngleInRadians ) { m_rotate_aux.x += aAngleInRadians; diff --git a/include/gal/3d/camera.h b/include/gal/3d/camera.h index 7e2060089e..b7736e2d32 100644 --- a/include/gal/3d/camera.h +++ b/include/gal/3d/camera.h @@ -236,6 +236,11 @@ public: bool ViewCommand_T1( VIEW3D_TYPE aRequestedView ); + /** + * Rotates the camera in screen plane. + */ + void RotateScreen( float aAngleInRadians ); + void RotateX( float aAngleInRadians ); void RotateY( float aAngleInRadians ); void RotateZ( float aAngleInRadians );