* 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_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<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 ){
//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<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 ) );
}
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<float>( 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<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( "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 ) ) );

View File

@ -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 ){
}

View File

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

View File

@ -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<XYWnd*>( data )->ZoomOut();
reinterpret_cast<XYWnd*>( 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<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( "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 ) );

View File

@ -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 ){
}
};