Controlling the camera with the mouse
created: 2025-03-15 18:38:33 UTClast updated: 2025-03-15 18:38:49 UTC
The newest feature I have implemented is a change in controls. So far in this engine, and all projects I've done before, the camera has been controlled completely with the keyboard. Well, camera and the player. Using the w and s key to move forward and backwards. Then using the an and s keys to rotate the player, or camera.
At first, I thought it would be quite a bit of code and trying to figure it out. Probably some complicated calculations. After all, with keys, I just set a static value and apply that as a sort of rotation to the viewing angle. A mouse is a little different though. You have an x and y coordinate. Those are values that range from 0 to some number in either axis. Do I need to track current and last position and get a delta? Can I just get the delta? How do I handle mouse sensitivity?
Turns out, SDL makes this extremely easy. I just set the mouse to give the relative position, which is the delta between polling of the mouse data. I can then pass that to my input handling and actually just apply it to my turn direction. At least so far. It ended up being less code than I thought.
At first, I thought it would be quite a bit of code and trying to figure it out. Probably some complicated calculations. After all, with keys, I just set a static value and apply that as a sort of rotation to the viewing angle. A mouse is a little different though. You have an x and y coordinate. Those are values that range from 0 to some number in either axis. Do I need to track current and last position and get a delta? Can I just get the delta? How do I handle mouse sensitivity?
Turns out, SDL makes this extremely easy. I just set the mouse to give the relative position, which is the delta between polling of the mouse data. I can then pass that to my input handling and actually just apply it to my turn direction. At least so far. It ended up being less code than I thought.
float mouseX; float mouseY; // SDL_GetMouseState(&x, &y); SDL_MouseButtonFlags mouseFlags = SDL_GetRelativeMouseState(&mouseX, &mouseY);
The call above gets the relative mouse state as described by the function call. I pass in a pointer for the x and y values which will populate that delta between polls in both axises. It return an integer with flags that represent different things like left or right mouse click. However, the mouse clicks are not being implemented for anything.
You do have to specifically tell SDL to put the mouse in relative mode, otherwise it will give you the current X and Y position of the mouse. Not necessarily something I want.
// set relative mouse mode if (!SDL_SetWindowRelativeMouseMode(window, true)) { SDL_Log("SDL_Error: %s\n", SDL_GetError()); return false; }
That is called during SDL initialization in order to set SDL to use the relative mode. Relative mode will automatically capture the mouse.
void InputComponent::ProcessInput(const bool *key, SDL_MouseButtonFlags mouseFlags, float mouseX, float mouseY) { float walkDirection = 0.0f; float turnDirection = 0.0f; if (key[forwardKey]) { walkDirection += 1.0f; } if (key[backwardKey]) { walkDirection -= 1.0f; } // if (key[clockwiseKey]) { // turnDirection += 1.0f; // } // if (key[counterClockwiseKey]) { // turnDirection -= 1.0f; // } turnDirection += mouseX * MOUSE_SENSITIVITY; SetTurnDirection(turnDirection); SetWalkDirection(walkDirection); }
Currently, this is what the InputComponent looks like with regards to processing input. The flags and relative positions are being passed in. As we can see, when using the keys, just adjust the turn direction by 1 in the positive or negative direction. Using the mouse, can just apply the mouseX to the turn direction. The turn direction is reset to 0 on every iteration.
I did have to add a MOUSE_SENSITIVITY constant. Well, right now it is a constant. The camera moved too fast. Applying the sensitivity constant makes it much more natural feeling and bearable. As mentioned, right now it is a constant, but in the future could allow a player to adjust that value via settings.