From 5977a04550dd09dc6b969ef106bffc4e30702f6e Mon Sep 17 00:00:00 2001 From: Garux Date: Sat, 13 Jun 2020 20:58:10 +0300 Subject: [PATCH] * unzoom from mouse pointer in 2D and 3D --- radiant/camwindow.cpp | 78 ++++++++++++++++++++++++++--------------- radiant/camwindow.h | 3 -- radiant/preferences.cpp | 13 ------- radiant/xywindow.cpp | 23 ++++++++---- radiant/xywindow.h | 6 ++-- 5 files changed, 69 insertions(+), 54 deletions(-) diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index f91bac29..cceef1ee 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -76,6 +76,7 @@ struct camwindow_globals_private_t int m_nMoveSpeed; int m_time_toMaxSpeed; int m_nScrollMoveSpeed; + bool m_bZoomToPointer; float m_strafeSpeed; float m_angleSpeed; bool m_bCamInverseMouse; @@ -92,6 +93,7 @@ struct camwindow_globals_private_t m_nMoveSpeed( 500 ), m_time_toMaxSpeed( 200 ), m_nScrollMoveSpeed( 100 ), + m_bZoomToPointer( true ), m_strafeSpeed( 1.f ), m_angleSpeed( 9.f ), m_bCamInverseMouse( false ), @@ -1314,6 +1316,49 @@ void camera_orbit_scroll( camera_t& camera ){ Camera_setOrigin( camera, camera.m_orbit_center - viewvector * offset ); } +/* +two alt solutions: + const Matrix4 screen2world = matrix4_affine_inverse( cam.m_view->GetViewMatrix() ); + Vector3 normalized; + normalized[0] = ( ( 2.0f * x ) / cam.width ) - 1.0f; // window_to_normalised_device + normalized[1] = ( ( 2.0f * ( cam.height - 1 - y ) ) / cam.height ) - 1.0f; + normalized[2] = 1.f; + normalized = vector4_projected( matrix4_transformed_vector4( screen2world, Vector4( normalized, 1 ) ) ); + + const Matrix4 screen2world = matrix4_full_inverse( cam.m_view->GetViewMatrix() ); + Vector3 normalized; + normalized[0] = ( ( 2.0f * x ) / cam.width ) - 1.0f; // window_to_normalised_device + normalized[1] = ( ( 2.0f * ( cam.height - 1 - y ) ) / cam.height ) - 1.0f; + normalized[2] = -1.f; + normalized = vector4_projected( matrix4_transformed_vector4( screen2world, Vector4( normalized, 1 ) ) ); +*/ +static void camera_zoom( CamWnd& camwnd, float x, float y, float step ){ + const camera_t& cam = camwnd.getCamera(); + if( camwnd.m_bFreeMove || !g_camwindow_globals_private.m_bZoomToPointer ){ + Camera_setOrigin( camwnd, Camera_getOrigin( camwnd ) + cam.forward * step ); + } + else{ + //const Matrix4 screen2world = matrix4_affine_inverse( matrix4_multiplied_by_matrix4( cam.projection, cam.modelview ) ); + const Matrix4 screen2world = matrix4_affine_inverse( cam.m_view->GetViewMatrix() ); + + Vector3 normalized; + + normalized[0] = 2.0f * x / static_cast( cam.width ) - 1.0f; + normalized[1] = 2.0f * y / static_cast( cam.height ) - 1.0f; + normalized[1] *= -1.f; + normalized[2] = 0.f; + + normalized *= ( camera_t::near_z * 2.f ); + //globalOutputStream() << normalized << " normalized "; + matrix4_transform_point( screen2world, normalized ); + //globalOutputStream() << normalized << "\n"; + const Vector3 norm = vector3_normalised( normalized - Camera_getOrigin( camwnd ) ); + //globalOutputStream() << normalized - Camera_getOrigin( *camwnd ) << " normalized - Camera_getOrigin( *camwnd )\n"; + //globalOutputStream() << norm << " norm\n"; + Camera_setOrigin( camwnd, Camera_getOrigin( camwnd ) + norm * step ); + } +} + gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){ //gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget ); gtk_widget_grab_focus( camwnd->m_gl_widget ); @@ -1334,32 +1379,7 @@ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* cam } Camera_Freemove_updateAxes( cam ); - if( camwnd->m_bFreeMove || !g_camwindow_globals.m_bZoomInToPointer ){ - Camera_setOrigin( *camwnd, Camera_getOrigin( *camwnd ) + cam.forward * static_cast( g_camwindow_globals_private.m_nScrollMoveSpeed ) ); - } - else{ - //Matrix4 maa = matrix4_multiplied_by_matrix4( cam.projection, cam.modelview ); - Matrix4 maa = cam.m_view->GetViewMatrix(); - matrix4_affine_invert( maa ); - - float x = static_cast( event->x ); - float y = static_cast( event->y ); - Vector3 normalized; - - normalized[0] = 2.0f * ( x ) / static_cast( cam.width ) - 1.0f; - normalized[1] = 2.0f * ( y )/ static_cast( cam.height ) - 1.0f; - normalized[1] *= -1.f; - normalized[2] = 0.f; - - normalized *= ( camera_t::near_z * 2.f ); - //globalOutputStream() << normalized << " normalized "; - matrix4_transform_point( maa, normalized ); - //globalOutputStream() << normalized << "\n"; - Vector3 norm = vector3_normalised( normalized - Camera_getOrigin( *camwnd ) ); - //globalOutputStream() << normalized - Camera_getOrigin( *camwnd ) << " normalized - Camera_getOrigin( *camwnd )\n"; - //globalOutputStream() << norm << " norm\n"; - Camera_setOrigin( *camwnd, Camera_getOrigin( *camwnd ) + norm * static_cast( g_camwindow_globals_private.m_nScrollMoveSpeed ) ); - } + camera_zoom( *camwnd, event->x, event->y, g_camwindow_globals_private.m_nScrollMoveSpeed ); } else if ( event->direction == GDK_SCROLL_DOWN ) { if ( cam.movementflags & MOVE_FOCUS ) { @@ -1373,7 +1393,7 @@ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* cam } Camera_Freemove_updateAxes( cam ); - Camera_setOrigin( *camwnd, Camera_getOrigin( *camwnd ) - cam.forward * static_cast( g_camwindow_globals_private.m_nScrollMoveSpeed ) ); + camera_zoom( *camwnd, event->x, event->y, -g_camwindow_globals_private.m_nScrollMoveSpeed ); } return FALSE; @@ -2474,7 +2494,7 @@ void Camera_constructPreferences( PreferencesPage& page ){ page.appendSlider( "Strafe Speed", g_camwindow_globals_private.m_strafeSpeed, TRUE, 0, 0, 1, 0.1, 10, 0.1, 1 ); page.appendSlider( "Mouse Sensitivity", g_camwindow_globals_private.m_angleSpeed, TRUE, 0, 0, 9, 0.1, 180, 0.1, 1 ); page.appendCheckBox( "", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse ); - page.appendCheckBox( "", "Zoom In to Mouse pointer", g_camwindow_globals.m_bZoomInToPointer ); + page.appendCheckBox( "", "Zoom to Mouse pointer", g_camwindow_globals_private.m_bZoomToPointer ); page.appendCheckBox( "", "Discrete movement", FreeCaller1(), @@ -2630,7 +2650,7 @@ void CamWnd_Construct(){ GlobalPreferenceSystem().registerPreference( "StrafeMode", IntImportStringCaller( g_camwindow_globals_private.m_strafeMode ), IntExportStringCaller( g_camwindow_globals_private.m_strafeMode ) ); GlobalPreferenceSystem().registerPreference( "CameraFaceWire", BoolImportStringCaller( g_camwindow_globals_private.m_bFaceWire ), BoolExportStringCaller( g_camwindow_globals_private.m_bFaceWire ) ); GlobalPreferenceSystem().registerPreference( "CameraFaceFill", BoolImportStringCaller( g_camwindow_globals_private.m_bFaceFill ), BoolExportStringCaller( g_camwindow_globals_private.m_bFaceFill ) ); - GlobalPreferenceSystem().registerPreference( "3DZoomInToPointer", BoolImportStringCaller( g_camwindow_globals.m_bZoomInToPointer ), BoolExportStringCaller( g_camwindow_globals.m_bZoomInToPointer ) ); + GlobalPreferenceSystem().registerPreference( "3DZoomInToPointer", BoolImportStringCaller( g_camwindow_globals_private.m_bZoomToPointer ), BoolExportStringCaller( g_camwindow_globals_private.m_bZoomToPointer ) ); GlobalPreferenceSystem().registerPreference( "fieldOfView", FloatImportStringCaller( camera_t::fieldOfView ), FloatExportStringCaller( camera_t::fieldOfView ) ); GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) ); diff --git a/radiant/camwindow.h b/radiant/camwindow.h index 134c5153..609f67c3 100644 --- a/radiant/camwindow.h +++ b/radiant/camwindow.h @@ -72,15 +72,12 @@ struct camwindow_globals_t int m_nCubicScale; - bool m_bZoomInToPointer; - bool m_showStats; camwindow_globals_t() : color_cameraback( 0.25f, 0.25f, 0.25f ), color_selbrushes3d( 1.0f, 0.f, 0.f ), m_nCubicScale( 14 ), - m_bZoomInToPointer( true ), m_showStats( false ){ } diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 5c9f2355..3a7738be 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -59,18 +59,6 @@ void Global_constructPreferences( PreferencesPage& page ){ void Interface_constructPreferences( PreferencesPage& page ){ page.appendPathEntry( "Shader Editor Command", g_TextEditor_editorCommand, false ); } -#if 0 -void Mouse_constructPreferences( PreferencesPage& page ){ - page.appendCheckBox( "", "Zoom to mouse pointer", g_xywindow_globals.m_bZoomInToPointer ); -} -void Mouse_constructPage( PreferenceGroup& group ){ - PreferencesPage page( group.createPage( "Mouse", "Mouse Preferences" ) ); - Mouse_constructPreferences( page ); -} -void Mouse_registerPreferencesPage(){ - PreferencesDialog_addInterfacePage( FreeCaller1() ); -} -#endif /*! ========================================================= @@ -667,7 +655,6 @@ PreferencesPage createPage( const char* treeName, const char* frameName ){ GtkWindow* PrefsDlg::BuildDialog(){ PreferencesDialog_addInterfacePreferences( FreeCaller1() ); - //Mouse_registerPreferencesPage(); GtkWindow* dialog = create_floating_window( "NetRadiant Preferences", m_parent ); diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index b7435e0e..9692e794 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -95,6 +95,8 @@ struct xywindow_globals_private_t int m_MSAA; + bool m_bZoomToPointer; + xywindow_globals_private_t() : d_showgrid( true ), @@ -110,7 +112,8 @@ struct xywindow_globals_private_t m_bChaseMouse( true ), m_bShowSize( true ), - m_MSAA( 8 ){ + m_MSAA( 8 ), + m_bZoomToPointer( true ){ } }; @@ -264,7 +267,15 @@ void XYWnd::ZoomOut(){ void XYWnd::ZoomInWithMouse( int x, int y ){ const float old_scale = Scale(); ZoomIn(); - if ( g_xywindow_globals.m_bZoomInToPointer && old_scale != Scale() ) { + ZoomCompensateOrigin( x, y, old_scale ); +} +void XYWnd::ZoomOutWithMouse( int x, int y ){ + const float old_scale = Scale(); + ZoomOut(); + ZoomCompensateOrigin( x, y, old_scale ); +} +void XYWnd::ZoomCompensateOrigin( int x, int y, float old_scale ){ + if ( g_xywindow_globals_private.m_bZoomToPointer && old_scale != Scale() ) { const float scale_diff = 1.0 / old_scale - 1.0 / Scale(); NDIM1NDIM2( m_viewType ) Vector3 origin = GetOrigin(); @@ -634,7 +645,7 @@ gboolean xywnd_wheel_scroll( GtkWidget* widget, GdkEventScroll* event, XYWnd* xy xywnd->ZoomInWithMouse( (int)event->x, (int)event->y ); } else if ( event->direction == GDK_SCROLL_DOWN ) { - xywnd->ZoomOut(); + xywnd->ZoomOutWithMouse( (int)event->x, (int)event->y ); } return FALSE; } @@ -1095,7 +1106,7 @@ void XYWnd_zoomDelta( int x, int y, unsigned int state, void* data ){ while ( abs( g_dragZoom ) > threshold ) { if ( g_dragZoom > 0 ) { - reinterpret_cast( data )->ZoomOut(); + reinterpret_cast( data )->ZoomOutWithMouse( g_zoom2x, g_zoom2y ); g_dragZoom -= threshold; } else @@ -2459,7 +2470,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Solid selection boxes ( no stipple )", g_xywindow_globals.m_bNoStipple ); //page.appendCheckBox( "", "Display size info", g_xywindow_globals_private.m_bShowSize ); page.appendCheckBox( "", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse ); - page.appendCheckBox( "", "Zoom In to Mouse pointer", g_xywindow_globals.m_bZoomInToPointer ); + page.appendCheckBox( "", "Zoom to Mouse pointer", g_xywindow_globals_private.m_bZoomToPointer ); if( GlobalOpenGL().support_ARB_framebuffer_object ){ const char* samples[] = { "0", "2", "4", "8", "16", "32" }; @@ -2500,7 +2511,7 @@ void XYWindow_Construct(){ GlobalCommands_insert( "XYFocusOnSelected", FreeCaller(), Accelerator( GDK_KEY_grave ) ); GlobalPreferenceSystem().registerPreference( "XYMSAA", IntImportStringCaller( g_xywindow_globals_private.m_MSAA ), IntExportStringCaller( g_xywindow_globals_private.m_MSAA ) ); - GlobalPreferenceSystem().registerPreference( "2DZoomInToPointer", BoolImportStringCaller( g_xywindow_globals.m_bZoomInToPointer ), BoolExportStringCaller( g_xywindow_globals.m_bZoomInToPointer ) ); + GlobalPreferenceSystem().registerPreference( "2DZoomInToPointer", BoolImportStringCaller( g_xywindow_globals_private.m_bZoomToPointer ), BoolExportStringCaller( g_xywindow_globals_private.m_bZoomToPointer ) ); GlobalPreferenceSystem().registerPreference( "ChaseMouse", BoolImportStringCaller( g_xywindow_globals_private.m_bChaseMouse ), BoolExportStringCaller( g_xywindow_globals_private.m_bChaseMouse ) ); GlobalPreferenceSystem().registerPreference( "ShowSize2d", BoolImportStringCaller( g_xywindow_globals_private.m_bShowSize ), BoolExportStringCaller( g_xywindow_globals_private.m_bShowSize ) ); GlobalPreferenceSystem().registerPreference( "ShowCrosshair", BoolImportStringCaller( g_bCrossHairs ), BoolExportStringCaller( g_bCrossHairs ) ); diff --git a/radiant/xywindow.h b/radiant/xywindow.h index 84d03a16..2b2c3abb 100644 --- a/radiant/xywindow.h +++ b/radiant/xywindow.h @@ -153,6 +153,8 @@ guint m_zoom_focusOut; void ZoomIn(); void ZoomOut(); void ZoomInWithMouse( int x, int y ); +void ZoomOutWithMouse( int x, int y ); +void ZoomCompensateOrigin( int x, int y, float old_scale ); void FocusOnBounds( const AABB& bounds ); void SetActive( bool b ){ @@ -279,7 +281,6 @@ struct xywindow_globals_t Vector3 AxisColorZ; bool m_bNoStipple; - bool m_bZoomInToPointer; xywindow_globals_t() : color_gridback( 0.77f, 0.77f, 0.77f ), @@ -295,8 +296,7 @@ struct xywindow_globals_t AxisColorX( 1.f, 0.f, 0.f ), AxisColorY( 0.f, 1.f, 0.f ), AxisColorZ( 0.f, 0.f, 1.f ), - m_bNoStipple( true ), - m_bZoomInToPointer( true ){ + m_bNoStipple( true ){ } };