Implementing mouse look in my 3D Engine

Started by
26 comments, last by snisarenko 21 years, 3 months ago
Ok those people who have done this please give me a clue what i am doing wrong. And propose an alternative on how to do this. Heres what I do when i get a message WM_MOUSEMOVE case WM_MOUSEMOVE: { mouseRotY+=(LOWORD(lParam)-mouseCenter.x)*mouseSpeed; mouseRotX+=(HIWORD(lParam)-mouseCenter.y)*mouseSpeed; SetCursorPos(mouseCenter.x,mouseCenter.y); return 0; } When i run the program it doesn''t Swap Buffers. I figured out why. When I call SetCursorPos It automaticly sends a WM_MOUSEMOVE message which causes it to send it again and again recursivly. So those of you who have done this point me in the right direction. Tell me how you implemented this.
Advertisement
ok first of all every time the mouse is moved 1 pixel you will get a WM_MOUSEMOVE message. so what you must do is record the old rotation and the place that the mouse was pressed. then use them to opdate the rotation like this.

    case WM_LBUTTONDOWN:    {      mouseCenter.x = LOWORD(lParam);      mouseCenter.y = HIWORD(lParam);      mouseRotYold = mouseRotY;      mouseRotXold = mouseRotX;      return 0;    }    case WM_MOUSEMOVE:    {      mouseRotY = mouseRotYold + (LOWORD(lParam)-mouseCenter.x) * mouseSpeed;      mouseRotX = mouseRotXold + (HIWORD(lParam)-mouseCenter.y) * mouseSpeed;      return 0;    }


this will set the rotation to equal the rotation before the drag pluss a bit based on the distance draged. have a thing about what happens when and the exact values that are passed.

eg. assumeing the mouse was pressed in the middel of your screen:
   MOUSEMOVE: x=321 y=240 rotY=1  rotX=0   rotYold=0 rotXold=0   MOUSEMOVE: x=322 y=240 rotY=2  rotX=0   rotYold=0 rotXold=0   MOUSEMOVE: x=334 y=241 rotY=4  rotX=1   rotYold=0 rotXold=0


the above is a good eg of the output you should get in a detailed debug log. youll need to have a globally opened file that a buggy function can write is call paramiters and intermediate values to. just remember to write some text and new lines to the file as well or it will be useless. writeing to a file will slow your program down a lot but can help a lot with some bugs.

-Jono AH

[edited by - jonox on December 26, 2002 12:48:08 AM]
- JonoRule #1: If you build it, they will come -- to hack and cheat.
I don't think u understood me.

First of all I am not dragging.
I just want the camera to move with the mouse.

mouseCenter is the center of my screen.

the only reason i am putting the mouse in the center of the screen is because if I wouldn't then the cursor would collide with an edge of the screen and wont be able to move anymore.

What I looking for is somehow to get mouse displacement no matter where the cursor is. But there is no function (as far as I know) that will give me that. So I have to place the mouse in the center after each movement. But SetCursorPos sends another mouse move message ang goes into recursion infinetly.

Get it now ?

Basicaly I am trying to get the mouse movement no matter where the cursor is on the screen.

This is just my way of doing mouse-camera movement. I am doing this for the first time.

Somebody please post yours if you can.

[edited by - snisarenko on December 27, 2002 2:06:01 AM]
case WM_MOUSEMOVE:{MouseX = HIWORD(lParam);MouseY = LOWORD(lParam);if(MouseX != MouseCenter.x && MouseY != MouseCenterY){MouseRotX += (MouseX - MouseCenter.y) * MouseSpeed;MouseRotY += (MouseY - MouseCenter.x) * MouseSpeed;SetCursorPos(MouseCenter.x, MouseCenter.y);return 0;} 


can you do that?
Do what I do :

Every frame get the mouse position,
rotate the cam accordingly and,
finally put the cursor position back to the center of the screen.
"THE INFORMATION CONTAINED IN THIS REPORT IS CLASSIFIED; DO NOT GO TO FOX NEWS TO READ OR OBTAIN A COPY." , the pentagon
I think you should simply use a global bool variable to avoid the recursion.

case WM_MOUSEMOVE
if (!g_bRotated) {
...
g_bRotated=true;
}

And after you swapped the buffers you set the variable to false again.
1°/ Put the cursor in the center of the screen only if it''s not already there. There''s no point moving it to where it is already. So before doing any modifications, check if the mouse has moved away from the center, and if it is still there, don''t SetCursorPos. (This part will also solve your problem).

2°/ As an optional optimization, instead of re-setting the mouse each time it moves, only re-set it when it exits a certain rectangle (for instance, 200 pixels wide, at the center of the screen). Use a variable to track the previous position of the mouse, and use it to calculate by how much it moved.

3°/ Smoothing advice : by using your method, if the mouse moves 3.5 pixels, you''ll only get 3 pixels. That is going to make your looking around quite sharp (moving by 0.1° on a frame, then 0.2° on the next one). To smooth out the mouse, keep track of the average mouse velocity, and average it (instead of sudden changes). The formula I like to use is :

Velocity = Velocity / kappa + MouseMoveThisFrame;
Angles = Angles + Velocity;

Where kappa is a constant you choose (I use 8). The smaller it is, the smoother the movement.

Good luck!

ToohrVyk
-------------
Extatica - a free 3d game engine
Available soon!
Click here to learn more
[qoute]
2°/ As an optional optimization, instead of re-setting the mouse each time it moves, only re-set it when it exits a certain rectangle (for instance, 200 pixels wide, at the center of the screen). Use a variable to track the previous position of the mouse, and use it to calculate by how much it moved.


Is it really an optimisation? Now you not only have to move mouse, but also check whether it is in the rectangle?
GUYS YOU ALL MISSED A VERY IMPORTANT THING. SetCursorPos Sends antoher WM_MOUSEMOVE Message Before it exits handling the first. Going into an infinite recursion.

Ximmer: Your solution might work. But I am doubtfull.

George2: Thats exactly what i am trying to do, but I am having the problem with SetCursorPos, like i said above. Please post your code.

Emin3m: I tried that, but my rotation for some reason becomes supper fast, weird, and only goes into one direction.

ToohVyk: I am not even gonna go into what u said.


[edited by - snisarenko on December 27, 2002 12:19:14 PM]

[edited by - snisarenko on December 27, 2002 12:22:51 PM]
Ximmer''s code works fine. I use it in my project with no problems. Comparing the current position to the last position keeps the infinite recursion from happening.

This topic is closed to new replies.

Advertisement