* unzoom from mouse pointer in 2D and 3D

This commit is contained in:
Garux 2020-06-13 20:58:10 +03:00
parent cc1f7ecd76
commit 5977a04550
5 changed files with 69 additions and 54 deletions

View File

@ -76,6 +76,7 @@ struct camwindow_globals_private_t
int m_nMoveSpeed; int m_nMoveSpeed;
int m_time_toMaxSpeed; int m_time_toMaxSpeed;
int m_nScrollMoveSpeed; int m_nScrollMoveSpeed;
bool m_bZoomToPointer;
float m_strafeSpeed; float m_strafeSpeed;
float m_angleSpeed; float m_angleSpeed;
bool m_bCamInverseMouse; bool m_bCamInverseMouse;
@ -92,6 +93,7 @@ struct camwindow_globals_private_t
m_nMoveSpeed( 500 ), m_nMoveSpeed( 500 ),
m_time_toMaxSpeed( 200 ), m_time_toMaxSpeed( 200 ),
m_nScrollMoveSpeed( 100 ), m_nScrollMoveSpeed( 100 ),
m_bZoomToPointer( true ),
m_strafeSpeed( 1.f ), m_strafeSpeed( 1.f ),
m_angleSpeed( 9.f ), m_angleSpeed( 9.f ),
m_bCamInverseMouse( false ), m_bCamInverseMouse( false ),
@ -1314,6 +1316,49 @@ void camera_orbit_scroll( camera_t& camera ){
Camera_setOrigin( camera, camera.m_orbit_center - viewvector * offset ); 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<float>( cam.width ) - 1.0f;
normalized[1] = 2.0f * y / static_cast<float>( 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 ){ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){
//gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget ); //gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget );
gtk_widget_grab_focus( 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 ); Camera_Freemove_updateAxes( cam );
if( camwnd->m_bFreeMove || !g_camwindow_globals.m_bZoomInToPointer ){ camera_zoom( *camwnd, event->x, event->y, g_camwindow_globals_private.m_nScrollMoveSpeed );
Camera_setOrigin( *camwnd, Camera_getOrigin( *camwnd ) + cam.forward * static_cast<float>( 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<float>( event->x );
float y = static_cast<float>( event->y );
Vector3 normalized;
normalized[0] = 2.0f * ( x ) / static_cast<float>( cam.width ) - 1.0f;
normalized[1] = 2.0f * ( y )/ static_cast<float>( 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<float>( g_camwindow_globals_private.m_nScrollMoveSpeed ) );
}
} }
else if ( event->direction == GDK_SCROLL_DOWN ) { else if ( event->direction == GDK_SCROLL_DOWN ) {
if ( cam.movementflags & MOVE_FOCUS ) { if ( cam.movementflags & MOVE_FOCUS ) {
@ -1373,7 +1393,7 @@ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* cam
} }
Camera_Freemove_updateAxes( cam ); Camera_Freemove_updateAxes( cam );
Camera_setOrigin( *camwnd, Camera_getOrigin( *camwnd ) - cam.forward * static_cast<float>( g_camwindow_globals_private.m_nScrollMoveSpeed ) ); camera_zoom( *camwnd, event->x, event->y, -g_camwindow_globals_private.m_nScrollMoveSpeed );
} }
return FALSE; 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( "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.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( "", "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( page.appendCheckBox(
"", "Discrete movement", "", "Discrete movement",
FreeCaller1<bool, CamWnd_Move_Discrete_Import>(), FreeCaller1<bool, CamWnd_Move_Discrete_Import>(),
@ -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( "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( "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( "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( "fieldOfView", FloatImportStringCaller( camera_t::fieldOfView ), FloatExportStringCaller( camera_t::fieldOfView ) );
GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) ); GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) );

View File

@ -72,15 +72,12 @@ struct camwindow_globals_t
int m_nCubicScale; int m_nCubicScale;
bool m_bZoomInToPointer;
bool m_showStats; bool m_showStats;
camwindow_globals_t() : camwindow_globals_t() :
color_cameraback( 0.25f, 0.25f, 0.25f ), color_cameraback( 0.25f, 0.25f, 0.25f ),
color_selbrushes3d( 1.0f, 0.f, 0.f ), color_selbrushes3d( 1.0f, 0.f, 0.f ),
m_nCubicScale( 14 ), m_nCubicScale( 14 ),
m_bZoomInToPointer( true ),
m_showStats( false ){ m_showStats( false ){
} }

View File

@ -59,18 +59,6 @@ void Global_constructPreferences( PreferencesPage& page ){
void Interface_constructPreferences( PreferencesPage& page ){ void Interface_constructPreferences( PreferencesPage& page ){
page.appendPathEntry( "Shader Editor Command", g_TextEditor_editorCommand, false ); 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<PreferenceGroup&, Mouse_constructPage>() );
}
#endif
/*! /*!
========================================================= =========================================================
@ -667,7 +655,6 @@ PreferencesPage createPage( const char* treeName, const char* frameName ){
GtkWindow* PrefsDlg::BuildDialog(){ GtkWindow* PrefsDlg::BuildDialog(){
PreferencesDialog_addInterfacePreferences( FreeCaller1<PreferencesPage&, Interface_constructPreferences>() ); PreferencesDialog_addInterfacePreferences( FreeCaller1<PreferencesPage&, Interface_constructPreferences>() );
//Mouse_registerPreferencesPage();
GtkWindow* dialog = create_floating_window( "NetRadiant Preferences", m_parent ); GtkWindow* dialog = create_floating_window( "NetRadiant Preferences", m_parent );

View File

@ -95,6 +95,8 @@ struct xywindow_globals_private_t
int m_MSAA; int m_MSAA;
bool m_bZoomToPointer;
xywindow_globals_private_t() : xywindow_globals_private_t() :
d_showgrid( true ), d_showgrid( true ),
@ -110,7 +112,8 @@ struct xywindow_globals_private_t
m_bChaseMouse( true ), m_bChaseMouse( true ),
m_bShowSize( 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 ){ void XYWnd::ZoomInWithMouse( int x, int y ){
const float old_scale = Scale(); const float old_scale = Scale();
ZoomIn(); 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(); const float scale_diff = 1.0 / old_scale - 1.0 / Scale();
NDIM1NDIM2( m_viewType ) NDIM1NDIM2( m_viewType )
Vector3 origin = GetOrigin(); 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 ); xywnd->ZoomInWithMouse( (int)event->x, (int)event->y );
} }
else if ( event->direction == GDK_SCROLL_DOWN ) { else if ( event->direction == GDK_SCROLL_DOWN ) {
xywnd->ZoomOut(); xywnd->ZoomOutWithMouse( (int)event->x, (int)event->y );
} }
return FALSE; return FALSE;
} }
@ -1095,7 +1106,7 @@ void XYWnd_zoomDelta( int x, int y, unsigned int state, void* data ){
while ( abs( g_dragZoom ) > threshold ) while ( abs( g_dragZoom ) > threshold )
{ {
if ( g_dragZoom > 0 ) { if ( g_dragZoom > 0 ) {
reinterpret_cast<XYWnd*>( data )->ZoomOut(); reinterpret_cast<XYWnd*>( data )->ZoomOutWithMouse( g_zoom2x, g_zoom2y );
g_dragZoom -= threshold; g_dragZoom -= threshold;
} }
else else
@ -2459,7 +2470,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){
page.appendCheckBox( "", "Solid selection boxes ( no stipple )", g_xywindow_globals.m_bNoStipple ); 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( "", "Display size info", g_xywindow_globals_private.m_bShowSize );
page.appendCheckBox( "", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse ); 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 ){ if( GlobalOpenGL().support_ARB_framebuffer_object ){
const char* samples[] = { "0", "2", "4", "8", "16", "32" }; const char* samples[] = { "0", "2", "4", "8", "16", "32" };
@ -2500,7 +2511,7 @@ void XYWindow_Construct(){
GlobalCommands_insert( "XYFocusOnSelected", FreeCaller<XY_Focus>(), Accelerator( GDK_KEY_grave ) ); GlobalCommands_insert( "XYFocusOnSelected", FreeCaller<XY_Focus>(), Accelerator( GDK_KEY_grave ) );
GlobalPreferenceSystem().registerPreference( "XYMSAA", IntImportStringCaller( g_xywindow_globals_private.m_MSAA ), IntExportStringCaller( g_xywindow_globals_private.m_MSAA ) ); 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( "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( "ShowSize2d", BoolImportStringCaller( g_xywindow_globals_private.m_bShowSize ), BoolExportStringCaller( g_xywindow_globals_private.m_bShowSize ) );
GlobalPreferenceSystem().registerPreference( "ShowCrosshair", BoolImportStringCaller( g_bCrossHairs ), BoolExportStringCaller( g_bCrossHairs ) ); GlobalPreferenceSystem().registerPreference( "ShowCrosshair", BoolImportStringCaller( g_bCrossHairs ), BoolExportStringCaller( g_bCrossHairs ) );

View File

@ -153,6 +153,8 @@ guint m_zoom_focusOut;
void ZoomIn(); void ZoomIn();
void ZoomOut(); void ZoomOut();
void ZoomInWithMouse( int x, int y ); 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 FocusOnBounds( const AABB& bounds );
void SetActive( bool b ){ void SetActive( bool b ){
@ -279,7 +281,6 @@ struct xywindow_globals_t
Vector3 AxisColorZ; Vector3 AxisColorZ;
bool m_bNoStipple; bool m_bNoStipple;
bool m_bZoomInToPointer;
xywindow_globals_t() : xywindow_globals_t() :
color_gridback( 0.77f, 0.77f, 0.77f ), color_gridback( 0.77f, 0.77f, 0.77f ),
@ -295,8 +296,7 @@ struct xywindow_globals_t
AxisColorX( 1.f, 0.f, 0.f ), AxisColorX( 1.f, 0.f, 0.f ),
AxisColorY( 0.f, 1.f, 0.f ), AxisColorY( 0.f, 1.f, 0.f ),
AxisColorZ( 0.f, 0.f, 1.f ), AxisColorZ( 0.f, 0.f, 1.f ),
m_bNoStipple( true ), m_bNoStipple( true ){
m_bZoomInToPointer( true ){
} }
}; };