Question

I have a problem when I try to update my camera.

I want to change the pitch and yaw of the the camera (where its looking) via the mouse But I want the mouse to stay positioned to the center of the window.

//where MouseP.x .y is the mouse position 
//(which is centered to the current window)

//get old position of the mouse
OldP.x = MouseP.x;
OldP.y = MouseP.y;

//work out the distance traveled
Delta.x = MouseP.x - OldP.x;
Delta.y = MouseP.y - OldP.y;

//update the camera(using  distance traveled)
Rot.Yaw -=Delta.x/5;
Rot.Pitch -= Delta.y/5;

//move mouse to the center of the screen
SetCursorPos(CENTER_SCREEN_X,CENTER_SCREEN_Y);

the problem is the camera snaps back to a certain point as the mouse is set to return to the origin.

I want to update the camera by the distance traveled from the origin but not the distance back to the origin.

If I take it out, it works wonderfully but the then mouse can go out of the window.

Was it helpful?

Solution

I believe the issue here is that your block of code probably is inside the catch of a WM_MOUSEMOVE event?

When you call SetCursorPos, it itself generates another WM_MOUSEMOVE event, so you process this block of code once when you move the mouse, and once again when you call SetCursorPos and it does the opposite of this.

You probably don't want to put SetCursorPos inside of a WM_MOUSEMOVE event catch, or else you'll generate an endless loop of messages (every SetCursorPos generates another one).

Perhaps you can move this code outside of the message pump, and just run it once per frame in your update loop: query the current mouse position, make your camera transform, then set the cursor back to the origin.

OTHER TIPS

One has to be careful with cursor and 3D mouse movement. People tend to think it is related, but in fact it is not. read the article from the msdn: http://msdn.microsoft.com/en-us/library/windows/desktop/ee418864%28v=vs.85%29.aspx "Taking Advantage of High-Definition Mouse Movement" this is how one must get mouse input in a 3D application. the cursor should be hidden.

If you try to recenter it, it will create a horrible jaggy feeling where the cursor is trying to escape the center with the user moving the mouse but is kept in place by an invisible spring. Which doesn't look very profesional. You can't fight that because your application is not scheduled before mouse cursor display.

if(g_States::Instance().MouseLook())
{
    //Test the mouse input
    POINT mousePos;
    GetCursorPos(&mousePos);

    mouseX = mousePos.x; //g_InputEngine::Instance().GetX();
    mouseY = mousePos.y; //g_InputEngine::Instance().GetY();

    mouseX = mouseX - m_HalfWidth;
    mouseY = mouseY - m_HalfHeight;

    mouseFloat = mouseX * C_MOUSESMOOTHINGFACTOR;
    g_Scene::Instance().GetCamera()->RotateYaw(-mouseFloat);

    mouseFloat = mouseY * C_MOUSESMOOTHINGFACTOR;
    g_Scene::Instance().GetCamera()->RotatePitch(mouseFloat);

    //Reset mouse to center on the screen
    SetCursorPos(m_HalfWidth,m_HalfHeight);
}

So this is the Mouselook function of a spacegame prototype I was developing for fun a while back what I did was change it to use GetCursorPos(&mousePos); instead. This will get the current position of the cursor no matter when your input code updates the mouse cursor location. The rest of the math in the function is just for the sensitivity and actually rotating the camera. Hopefully this code helps a little getting yours working.

Let me know if you need more explanation.

Edit: I just remembered the reason i did this. It was because the screen was flickering it would move but then the input engine would get updated by the SetCursorPos() call because i was using WM_MOUSEMOVE to update the input engine. I'm not sure how your getting your input but this should still help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top