Sign in to follow this  

Camera Questions (DirectX)

This topic is 3340 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am using a flexible camera class that I built with the help of a tutorial. I used my wrapper to link the camera's yaw to Mouse.lX, and pitch to Mouse.lY. It works, but it's headache inducing to move around. The camera "snaps" to each and every new look position and it makes things unpleasant to look at. I have 3 questions I think will help close the case, and then some. 1. How do I smooth my camera movement in general? 2. How can I have my camera smoothly move into the speed the player is moving the mouse? Kind of like entering a freeway. It just feels like the camera in most games is attentive enough to the mouse to match it's speed while mine snaps to absolute values regardless of my speed. 3. (Slightly irrelevant) My mouse is displayed on screen with free movement everywhere. How do I lock the mouse to the center of my view like most games, and hide it? If you need to see my code, ask. But I'm hoping this is a question that can get an effective answer without it.

Share this post


Link to post
Share on other sites
Quote:
Original post by zyrolasting

3. (Slightly irrelevant) My mouse is displayed on screen with free movement everywhere. How do I lock the mouse to the center of my view like most games, and hide it?


Assuming windows, SetCursorPos() & ShowCursor().

Share this post


Link to post
Share on other sites
Noted. Thanks! Still hoping to get the other solutions soon...

Do I have to use an acceleration of some kind to start working on the other issues? I have no idea, and I would appreciate a push in the right direction.

Share this post


Link to post
Share on other sites
Quote:
Original post by zyrolasting
Noted. Thanks! Still hoping to get the other solutions soon...

Do I have to use an acceleration of some kind to start working on the other issues? I have no idea, and I would appreciate a push in the right direction.


You're on the right track with the acceleration.

Try this on the function in which you handle per-frame input:


//acceleration and position should be preserved between frames, so declare these outside the input update function
float accX, accY, posX, posY;

accX = accX + mouse.deltaX; //delta = instantaneous rate of movement
accY = accY + mouse.deltaY;

accX *= 0.9f; //to dampen the motion over time, simulating air friction
accY *= 0.9f;

posX += accX; //update position with dampened acceleration values
posY += accY;

//now do something with posX and posY; for example, update your camera angles


In practice, you should scale your acceleration values with the timestep duration (the time between adjacent frames) so that the effective result of the simulation is the same regardless of the frame rate.

Share this post


Link to post
Share on other sites
Quote:

accX = accX + mouse.deltaX; //delta = instantaneous rate of movement
accY = accY + mouse.deltaY;


I'm not too sure what you are trying to tell me with delta. Ok, instant rate of movement... But what exactly is the numerical equivalent of that? How is it found?
I'm just using a DirectInput mouse interface, so I know there is no delta x or y members.

In a nutshell, could you clarify these lines a little more?

Share this post


Link to post
Share on other sites
mouse.deltaX & mouse.deltaY

may also be called as mouse mickeys. It indicates the movement of mouse.
The value changes intantly when you move the mouse but when you keep
it still it will be zero. usually values are [0,1] float or somthin'

Share this post


Link to post
Share on other sites
My code example was somewhat abstract, and just illustrated the concept of using mouse's data to feed the acceleration algorithm.

By default, DirectInput will report the absolute position of the mouse, in that it remembers its previous position frame by frame. You can specify that you want the movement vector (or deltas) instead, by calling IDirectInputDevice::SetProperty with DIPROP_AXISMODE as the first parameter, and setting the parameter structure's dwData member to DIPROPAXISMODE_REL in addition to the required standard contents of the structure (see SetProperty documentation in the SDK). After you've set this property, the mouse coordinate data contains the instantaneous movement vector instead of the absolute position.

That said, for mouse input, Microsoft recommends using standard Windows mouse functions instead of DI, because of less hassle and same or lighter overhead than DI. In Win32, you can determine the mouse's rate of movement by calling GetCursorPos or handling the WM_MOUSEMOVE to get the current mouse position, getting it again on the next timestep, and subtracting the previous position from the current one. You can also use mouse hooks, but this is somewhat more difficult to get right.

Share this post


Link to post
Share on other sites
EDIT: I changed my mind and went with the DI method. My camera now moves appropriately, but at the speed of holy god. You weren't kidding about absolute in the sense that when I twitch my wrist the world flipped upside down. (No caps set yet) I understand I am going from LONG to float, and I did typecast that. It's still fighting me.

Before I get to other details, did I set the properties correctly? I was basing it off another topic in this forum.


oid InitDirectInput(HINSTANCE hInstance, GAMEWINDOW* gw)
{
DirectInput8Create(hInstance,
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void**)&din,
NULL);

din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL);
din->CreateDevice(GUID_SysMouse, &dinmouse, NULL);

dinkeyboard->SetDataFormat(&c_dfDIKeyboard);
dinmouse->SetDataFormat(&c_dfDIMouse);

DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = DIPROPAXISMODE_REL;

dinmouse->SetProperty(DIPROP_AXISMODE , &dipdw.diph);


dinkeyboard->SetCooperativeLevel(gw->hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
dinmouse->SetCooperativeLevel(gw->hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

dinmouse->Acquire();

return;
}




[Edited by - zyrolasting on October 23, 2008 6:10:01 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by zyrolasting
EDIT: I changed my mind and went with the DI method. My camera now moves appropriately, but at the speed of holy god. You weren't kidding about absolute in the sense that when I twitch my wrist the world flipped upside down. (No caps set yet) I understand I am going from LONG to float, and I did typecast that. It's still fighting me.

Before I get to other details, did I set the properties correctly? I was basing it off another topic in this forum.

*** Source Snippet Removed ***



The property setting is correct.

Note that the mouse movement vector could well be over 100 distance units long, so you should scale the values appropriately (try value*0.01) before using them as your acceleration vector.

Share this post


Link to post
Share on other sites

This topic is 3340 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this