Mouse position not correctly registered with freelook
by Judy L Tyrer · in Torque 3D Professional · 09/10/2009 (12:11 pm) · 7 replies
I use the following code to enable a freelook camera (use the right mouse button to look around the scene).
This works for the right mouse button and I can look around the scene correctly BUT, after that, the mouse position on left mouse clicks is WAY off. I'm in window mode and the way to solve it is to click outside the window and then back inside the game window at which time the mouse clicks are where they are supposed to be positioned.
Clearly this is not an acceptable choice. Is there something I'm doing wrong or some better way to enable the freelook camera?
Judy
function freelook( %val ) {
if( %val )
canvas.cursorOff();
else
canvas.cursorOn();
}
globalActionMap.bind( mouse, button1, freelook );This works for the right mouse button and I can look around the scene correctly BUT, after that, the mouse position on left mouse clicks is WAY off. I'm in window mode and the way to solve it is to click outside the window and then back inside the game window at which time the mouse clicks are where they are supposed to be positioned.
Clearly this is not an acceptable choice. Is there something I'm doing wrong or some better way to enable the freelook camera?
Judy
#2
I bet this is the mouse tracking code in GuiCanvas messing up again. GuiCanvas is accumulating incremental mouse position updates to keep track of the current cursor positon--which IMO is a really, really bad idea. The position frequently gets out of step with where the cursor actually is. The code really should just get passed absolute mouse coordinates from the input system and work off them.
Hope to be looking some more into this soon.
09/11/2009 (2:49 am)
I bet this is the mouse tracking code in GuiCanvas messing up again. GuiCanvas is accumulating incremental mouse position updates to keep track of the current cursor positon--which IMO is a really, really bad idea. The position frequently gets out of step with where the cursor actually is. The code really should just get passed absolute mouse coordinates from the input system and work off them.
Hope to be looking some more into this soon.
#3
The code that tracks the position of the mouse gets coordinates on move and translates those coordinates and stores them in mLastCursorPt (it stores both floating point and non-floating point for some reason). But the mouse press doesn't pass those coordinates into the method so it has to use the last ones passed in with the mouse move.
What I haven't figured out is how frequently the mouse is being polled for MOVE.
SO either we need to figure a way to translate the coordinates between what the mouse input from the inputcontroller (in my case windows) gives to the coordinates passed in when the mouse is simply moved. I plan on finding where those coordinates come from tonight.
If I solve this I'll post the solution, though if GG manages to solve it first that would be even better since it's the last bug in my current prototype and I've got 3 more waiting to be done.
09/11/2009 (9:51 pm)
I tried that. The problem is that the direct inputs use a different coordinate system. For example, the mouse coordinate system through gui canvas was 176, 473 but using the inputcontroller->getPosition call the coordinates were 277, 186. The code that tracks the position of the mouse gets coordinates on move and translates those coordinates and stores them in mLastCursorPt (it stores both floating point and non-floating point for some reason). But the mouse press doesn't pass those coordinates into the method so it has to use the last ones passed in with the mouse move.
What I haven't figured out is how frequently the mouse is being polled for MOVE.
SO either we need to figure a way to translate the coordinates between what the mouse input from the inputcontroller (in my case windows) gives to the coordinates passed in when the mouse is simply moved. I plan on finding where those coordinates come from tonight.
If I solve this I'll post the solution, though if GG manages to solve it first that would be even better since it's the last bug in my current prototype and I've got 3 more waiting to be done.
#4
Translating the pcontroller->getCursorPos position to the window coordinates might be possible. I haven't looked into that yet.
09/12/2009 (2:03 am)
Well I dug into the code and the most correct solution would be to pass the X,Y coordinates with the mouse button event, but the signal template seems designed to only handle a limited interface (hence mouse move actually translates the windows mouse event into two T3D events, one for the X axis and one for the Y axis). I have no idea how complex it would be to change this, but it's so pervasive that I am loathe to attempt it without a full test bed at my disposal to make sure I didn't break something. That is definitely a Garage Games task.Translating the pcontroller->getCursorPos position to the window coordinates might be possible. I haven't looked into that yet.
#5
Changing the way the input events get passed along is what I meant. Any GUI system will pass along in mouse coordinates (and not incremental mouse position changes) so we should just relay this down to Torque's GUI code as either screen or client space coordinates.
The mCursorPt coordinates in GuiCanvas are kept in GuiCanvas' coordinate space which is where the difference to the underlying input code comes from (screen coordinates here). Translating cursor coordinates between spaces is simple. Best done with the platform's screen->client and client->screen functions. Have added these for the next release. (Used with getCursorPos/setCursorPos now)
The frequency of mouse movement events depends on how the mouse is sampled by the system's GUI. Updates are usually small and fired in rapid succession.
I'll be looking into this some more for 1.1. Hope to completely rip out mCursorPt. Other than possibly minor changes to input event structures and the relevant changes in platform code, this change should pretty much only affect GuiCanvas. Torque's own GUI already uses mouse events with client space mouse coordinates.
For a temporary hackish solution, one could force a fresh update of mCursorPt from the current on-screen mouse position and trigger that manually or automatically on certain events.
09/12/2009 (1:52 pm)
Changing the way the input events get passed along is what I meant. Any GUI system will pass along in mouse coordinates (and not incremental mouse position changes) so we should just relay this down to Torque's GUI code as either screen or client space coordinates.
The mCursorPt coordinates in GuiCanvas are kept in GuiCanvas' coordinate space which is where the difference to the underlying input code comes from (screen coordinates here). Translating cursor coordinates between spaces is simple. Best done with the platform's screen->client and client->screen functions. Have added these for the next release. (Used with getCursorPos/setCursorPos now)
The frequency of mouse movement events depends on how the mouse is sampled by the system's GUI. Updates are usually small and fired in rapid succession.
I'll be looking into this some more for 1.1. Hope to completely rip out mCursorPt. Other than possibly minor changes to input event structures and the relevant changes in platform code, this change should pretty much only affect GuiCanvas. Torque's own GUI already uses mouse events with client space mouse coordinates.
For a temporary hackish solution, one could force a fresh update of mCursorPt from the current on-screen mouse position and trigger that manually or automatically on certain events.
#6
I did try to hack the force refresh for mCursorPt by calling the mouse move events before the button event, very hacky. It helped a bit, but not a fix since there were still cases where the button event came in before the correct positional event, but at least a second click would register correctly. Better than having to change window focus. I can live with it until the next release at least.
That said, what's the difference between "Torque's own GUI" and GuiCanvas. Am I using the wrong GUI? Is there a better one for what I'm dong (see above)?
Thanks for the help on this.
09/13/2009 (12:48 am)
Great, if this is fixed in the next release that would be terrific. I did try to hack the force refresh for mCursorPt by calling the mouse move events before the button event, very hacky. It helped a bit, but not a fix since there were still cases where the button event came in before the correct positional event, but at least a second click would register correctly. Better than having to change window focus. I can live with it until the next release at least.
That said, what's the difference between "Torque's own GUI" and GuiCanvas. Am I using the wrong GUI? Is there a better one for what I'm dong (see above)?
Thanks for the help on this.
#7
No, sorry, was a bit misleading what I wrote. What I meant is the entire GuiControl-based code. GuiCanvas is the only control doing this kind of thing whereas GuiControl passes around root-relative coordinates (i.e. GuiCanvas client space coordinates).
09/13/2009 (3:14 pm)
No, sorry, was a bit misleading what I wrote. What I meant is the entire GuiControl-based code. GuiCanvas is the only control doing this kind of thing whereas GuiControl passes around root-relative coordinates (i.e. GuiCanvas client space coordinates).
Torque 3D Owner Judy L Tyrer
The problem is in the way the cursor is registering its position after it's been turned off and the camera has moved. If I do not move the camera, but simply right click the mouse and hold the button down a minute then release it, the position is correctly registering.
I am getting the location from the inputcontroller in WindowInputGenerator::generateInputEvent.
It also seems to have something to do with where the mouse is placed and how much looking around has taken place. To get it to break consistently, place it at the opposite corner and look more than 45 degrees around. It happens far more often than not, and in fact you have to really try to NOT have it happen.