ProjectPhysX / FluidX3D

The fastest and most memory efficient lattice Boltzmann CFD software, running on all GPUs via OpenCL. Free for non-commercial use.
https://youtube.com/@ProjectPhysX
Other
3.77k stars 300 forks source link

Mouse control problem with Remote Desktop Connection (windows) #131

Closed rodionstepanov closed 4 months ago

rodionstepanov commented 9 months ago

When I connect to a Windows PC with Remote Desktop, it is not possible to control the camera view with a mouse. Any very slight movement of the mouse causes a crazy response. I/J/J/L keyboard control works well.

ProjectPhysX commented 9 months ago

Hi @rodionstepanov,

thanks for reporting this. It's the age-old poor design choice of Microsoft's SetCursorPos itself triggering a WM_MOUSEMOVE event, when setting the cursor back to the center of the screen. Usually in my implementation this is not an issue, as screen_width/2 ad screen_height/2 are subtracted and the resulting movement upon cursor centering is 0/0.

However, in another poor design choice by Microsoft, when the remote screen resolution is different and/or off-set compared to the client screen resolution, SetCursorPos(width/2, height/2) works on client and the reported position from WM_MOUSEMOVE is on remote, and when they mismatch, it adds the off-set mouse movement 60 times a second and rotates the camera very fast.

I have now changed the mouse input routine on Windows to avoid WM_MOUSEMOVE alltogether. Please test this new version on your remote setup and tell me if it resolves the bug!

Kind regards, Moritz

rodionstepanov commented 9 months ago

I'm sorry but it does not resolve the bug. I've test with setup for 3D Taylor-Green vortices; Looks like sensitivity is very high.

ProjectPhysX commented 8 months ago

@rodionstepanov can you try if reducing the mouse_sensitivity constant helps?

rodionstepanov commented 8 months ago

@ProjectPhysX I took mouse_sensitivity = 0.01. It looks like the reaction is getting slower but I still cannot control a view angle properly.

SLGY commented 4 months ago

I'm probably telling you something you already know here but you just turn off mouse-input with the "u" key and alt-tab in/out of the program where required to avoid clicking the app window and re-enabling the mouse. I do a lot of remote desktop stuff to the workstation and just turn down the multipliers for I/J/K/L keys, using the mouse is a write-off on remote sessions for me.

ProjectPhysX commented 4 months ago

Hi @rodionstepanov and @SLGY,

I think the root cause here is that the Windows Remote Desktop client fails to execute the SetCursorPos WinAPI command correctly, so it does not center the cursor after reading the distance between cursor and screen center and you see super fast uncontrollable rotation.

I've written an alternative mouse input method that does not rely on SetCursorPos and should work better on remote systems. Please replace the entire LRESULT CALLBACK WndProc(...) {...} function with this code:

LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) {
    if(message==WM_DESTROY) {
        running = false;
        PostQuitMessage(0);
        exit(0);
    } else if(message==WM_MOUSEMOVE) {
        static int last_x=(int)camera.width/2, last_y=(int)camera.height/2;
        const int new_x=(int)LOWORD(lParam), new_y=(int)HIWORD(lParam);
        camera.input_mouse_dragged(new_x-last_x, new_y-last_y);
        last_x = new_x;
        last_y = new_y;
    } else if(message==WM_MOUSEWHEEL) {
        if((short)HIWORD(wParam)>0) camera.input_scroll_up(); else camera.input_scroll_down();
    } else if(message==WM_LBUTTONDOWN||message==WM_MBUTTONDOWN||message==WM_RBUTTONDOWN) {
        ShowCursor(!camera.lockmouse); // show/hide cursor
        camera.input_key('U');
    } else if(message==WM_KEYDOWN) {
        int key = key_windows((int)wParam);
        if(key=='U') ShowCursor(!camera.lockmouse); // show/hide cursor
        camera.set_key_state(key, true);
        key_bindings(key);
    } else if(message==WM_KEYUP) {
        int key = key_windows((int)wParam);
        camera.set_key_state(key, false);
    }
    return DefWindowProc(window, message, wParam, lParam);
}

This workaround is not a suitable general solution however, as rotation stops as soon as the cursor hits the screen boundaries and on small screens you can't fully rotate ±90° vertically and 360° horizontally. So I put this code only here and not in the repo.

As 2 alternatives with the mouse input version in the repo, you can try:

Kind regards, Moritz

rodionstepanov commented 4 months ago

Hi @ProjectPhysX! Both recipes work but I stay with first one. No issue any more. Thanks a lot. I express my deepest gratitude and respect to you. It is very cool what you are doing.