Patch - Improves camera controls and movement. - V14.5.33

Refactors camera input handling for smoother and more intuitive control.

This change introduces a dedicated CameraInput structure and updates the
camera class to use it for movement and rotation based on user input.
It removes the old position class camera related logic and integrates mouse
delta for precise rotation control and scroll wheel for speed adjustments.

Updates ImGui layout to reflect the new size for the docked space.
This commit is contained in:
2025-10-10 17:16:10 +02:00
parent b31b242775
commit 295b7354d9
10 changed files with 171 additions and 242 deletions

View File

@@ -1,6 +1,6 @@
[Window][DockSpace]
Pos=0,0
Size=1584,861
Size=1584,845
Collapsed=0
[Window][Debug##Default]
@@ -57,7 +57,7 @@ Collapsed=0
DockId=0x00000002,0
[Docking][Data]
DockSpace ID=0xCCBD8CF7 Window=0x3DA2F1DE Pos=0,19 Size=1584,842 Split=X
DockSpace ID=0xCCBD8CF7 Window=0x3DA2F1DE Pos=0,19 Size=1584,826 Split=X
DockNode ID=0x00000001 Parent=0xCCBD8CF7 SizeRef=1350,842 Split=X
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=1265,842 Split=Y
DockNode ID=0x00000003 Parent=0x00000005 SizeRef=1584,609 Split=X

View File

@@ -717,6 +717,7 @@ private :
input inputs_;
bool tab_was_pressed_;
std::shared_ptr<CameraInput> camera_input_;
// ------------------------------------------------- //
// ------------------- SOUND ----------------------- //

View File

@@ -129,10 +129,35 @@ public:
* @param float deltaTime : time since last frame
* @return void
*/
void move(float deltatime);
void move(float deltatime, float delta_x, float delta_y);
/**
* Rotate the camera
* @param float delta_x : mouse delta x
* @param float delta_y : mouse delta y
* @return void
*/
void rotate(float delta_x, float delta_y);
/**
* Update the camera input states based on the provided input_class instance.
* This method updates the internal state of the camera's input handling.
* @param imputs A pointer to an input_class instance containing the current input states.
*/
void update_camera_inputs_states(input_class* imputs);
/**
* Set the camera inputs structure.
* @param inputs A shared pointer to a CameraInput structure containing the input states.
*/
void set_camera_inputs(std::shared_ptr<CameraInput> inputs) { inputs_ = inputs; }
/**
* Get the camera inputs structure.
* @return A shared pointer to the CameraInput structure containing the input states.
*/
std::shared_ptr<CameraInput> get_camera_inputs() { return inputs_; }
private:
float position_x_, position_y_, position_z_;
float rotation_x_, rotation_y_, rotation_z_;
@@ -141,6 +166,7 @@ private:
float camera_speed_;
std::shared_ptr<CameraInput> inputs_;
float camera_sensitivity_ = 0.1f;
};
#endif

View File

@@ -164,6 +164,7 @@ inline bool TestPlaneCorner(
// ---------------------------------------------- //
// --- Macros for the camera input processing --- //
// ---------------------------------------------- //
#define TO_RAD 0.0174532925f
struct CameraInput {
bool move_forward = false;

View File

@@ -22,16 +22,10 @@ public:
void GetRotation(float&, float&) const;
void GetPosition(float&, float&, float&) const;
void TurnLeft(bool);
void TurnRight(bool);
void TurnMouse(float, float, float, bool);
void MoveCamera(bool, bool, bool, bool, bool, bool, bool, bool, bool);
private:
float m_frameTime;
float m_rotationY, m_rotationX;
float m_positionX, m_positionY, m_positionZ;
float m_leftTurnSpeed, m_rightTurnSpeed, m_horizontalTurnSpeed, m_verticalTurnSpeed, m_cameraSpeed, m_speed;
};
#endif

View File

@@ -46,6 +46,7 @@ application_class::application_class() : should_quit_(false)
render_count_ = 0;
tab_was_pressed_ = false;
sound_system_ = nullptr;
camera_input_ = nullptr;
}
application_class::~application_class()
@@ -115,6 +116,9 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd,
LOG_ERROR("Could not create the camera object");
R_FALSE
}
// Init the CameraInput structure
camera_input_ = std::make_shared<CameraInput>();
camera_->set_camera_inputs(camera_input_);
sun_camera_ = new camera_class;
if (!sun_camera_)
@@ -770,9 +774,18 @@ void application_class::shutdown()
}
if (shadow_map_) {
LOG_SHUTDOWN("Releasing the shadow map object");
shadow_map_->shutdown();
delete shadow_map_;
shadow_map_ = nullptr;
LOG_SHUTDOWN("Shadow map object released");
}
if (stats_) {
LOG_SHUTDOWN("Releasing the stats object");
delete stats_;
stats_ = nullptr;
LOG_SHUTDOWN("Stats object released");
}
LOG_SHUTDOWN("Application class shut down");
@@ -783,8 +796,7 @@ bool application_class::frame(input_class* Input)
stats_->reset_draw_call_count();
int mouseX, mouseY, currentMouseX, currentMouseY;
bool result, leftMouseDown, rightMouseDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE, scrollUp, scrollDown;
float rotationY, rotationX, positionX, positionY, positionZ;
bool result, leftMouseDown;
static float textureTranslation = 0.0f;
float frameTime;
@@ -811,10 +823,7 @@ bool application_class::frame(input_class* Input)
// Get the location of the mouse from the input object,
Input->GetMouseLocation(mouseX, mouseY);
// Check if the mouse has been pressed.
leftMouseDown = Input->IsLeftMousePressed();
rightMouseDown = Input->IsRightMousePressed();
currentMouseX = mouseX;
@@ -826,27 +835,9 @@ bool application_class::frame(input_class* Input)
int deltaY = currentMouseY - lastMouseY; // Calculate the mouse movement.
lastMouseY = currentMouseY; // Update the last mouse position for the next frame
// Set the frame time for calculating the updated position.
position_->SetFrameTime(timer_->GetTime());
position_->TurnMouse((float)deltaX, (float)deltaY, 0.1f, rightMouseDown);
// Get the current view point rotation.
position_->GetRotation(rotationY, rotationX);
scrollUp = Input->IsScrollUp();
scrollDown = Input->IsScrollDown();
// Check if the a(q), d, w(z), s, q(a), e have been pressed, if so move the camera accordingly.
buttonQ = Input->is_key_pressed(DIK_A);
buttonD = Input->is_key_pressed(DIK_D);
buttonZ = Input->is_key_pressed(DIK_W);
buttonS = Input->is_key_pressed(DIK_S);
buttonA = Input->is_key_pressed(DIK_Q);
buttonE = Input->is_key_pressed(DIK_E);
position_->MoveCamera(buttonZ, buttonS, buttonQ, buttonD, buttonE, buttonA, scrollUp, scrollDown, rightMouseDown);
position_->GetPosition(positionX, positionY, positionZ);
// New input processing
camera_->update_camera_inputs_states(Input);
camera_->move(frameTime, deltaX, deltaY);
XMFLOAT3 dir = sun_light_->GetDirection();
float pitch = asinf(-dir.y) * (180.0f / XM_PI); // en degr<67>s
@@ -868,8 +859,8 @@ bool application_class::frame(input_class* Input)
if (active_camera_ == camera_) {
// Update the camera position and rotation based on the position class.
camera_->set_position(positionX, positionY, positionZ);
camera_->set_rotation(rotationX, rotationY, 0.0f);
//camera_->set_position(positionX, positionY, positionZ);
//camera_->set_rotation(rotationX, rotationY, 0.0f);
} else {
// Update the sun camera position and rotation based on the light position.
sun_camera_->set_position(sun_light_->GetPosition().x, sun_light_->GetPosition().y, sun_light_->GetPosition().z);

View File

@@ -14,7 +14,10 @@ camera_class::camera_class()
rotation_y_ = 0.0f;
rotation_z_ = 0.0f;
camera_speed_ = 1.0f;
camera_speed_ = 4.0f;
view_matrix_ = XMMatrixIdentity();
reflection_view_matrix_ = XMMatrixIdentity();
LOG_INIT("Camera class initialized");
}
@@ -176,8 +179,117 @@ void camera_class::get_reflection_view_matrix(XMMATRIX& reflectionViewMatrix) co
return;
}
void camera_class::move(float deltatime)
void camera_class::move(float deltatime, float delta_x, float delta_y)
{
if (!inputs_) return;
float speed;
float radiansY = rotation_y_ * TO_RAD;
float radiansX = rotation_x_ * TO_RAD;
rotate(delta_x, delta_y);
if (inputs_->scroll_up && inputs_->right_click)
{
camera_speed_ *= 1.1f;
}
if (inputs_->scroll_down && inputs_->right_click)
{
camera_speed_ *= 0.9f;
if (camera_speed_ < 0.25f) // Minimum speed.
{
camera_speed_ = 0.25f;
}
}
if (inputs_->scroll_up && !inputs_->right_click)
{
speed = camera_speed_ * 20 * deltatime;
position_x_ += sinf(radiansY) * cosf(radiansX) * speed;
position_z_ += cosf(radiansY) * cosf(radiansX) * speed;
position_y_ -= sinf(radiansX) * speed;
}
if (inputs_->scroll_up && !inputs_->right_click)
{
speed = camera_speed_ * 20 * deltatime;
position_x_ -= sinf(radiansY) * cosf(radiansX) * speed;
position_z_ -= cosf(radiansY) * cosf(radiansX) * speed;
position_y_ += sinf(radiansX) * speed;
}
speed = camera_speed_ * deltatime;
if (inputs_->move_forward)
{
position_x_ += sinf(radiansY) * cosf(radiansX) * speed;
position_z_ += cosf(radiansY) * cosf(radiansX) * speed;
position_y_ -= sinf(radiansX) * speed;
}
if (inputs_->move_backward)
{
position_x_ -= sinf(radiansY) * cosf(radiansX) * speed;
position_z_ -= cosf(radiansY) * cosf(radiansX) * speed;
position_y_ += sinf(radiansX) * speed;
}
if (inputs_->move_left)
{
position_x_ -= cosf(radiansY) * speed;
position_z_ += sinf(radiansY) * speed;
}
if (inputs_->move_right)
{
position_x_ += cosf(radiansY) * speed;
position_z_ -= sinf(radiansY) * speed;
}
if (inputs_->move_up)
{
position_y_ += speed;
}
if (inputs_->move_down)
{
position_y_ -= speed;
}
return;
}
void camera_class::rotate(float delta_x, float delta_y)
{
if (inputs_ == nullptr) return;
float delta_yaw = delta_x * camera_sensitivity_;
float delta_pitch = delta_y * camera_sensitivity_;
if (inputs_->right_click)
{
rotation_y_ += delta_yaw;
if (rotation_y_ < 0.0f)
{
rotation_y_ += 360.0f;
}
else if (rotation_y_ > 360.0f)
{
rotation_y_ -= 360.0f;
}
rotation_x_ += delta_pitch;
if (rotation_x_ < -90.0f)
{
rotation_x_ = -90.0f;
}
else if (rotation_x_ > 90.0f)
{
rotation_x_ = 90.0f;
}
}
return;
}
void camera_class::update_camera_inputs_states(input_class* inputs)
@@ -188,4 +300,7 @@ void camera_class::update_camera_inputs_states(input_class* inputs)
inputs_->move_right = inputs->is_key_pressed(DIK_D);
inputs_->move_up = inputs->is_key_pressed(DIK_E);
inputs_->move_down = inputs->is_key_pressed(DIK_Q);
inputs_->scroll_up = inputs->IsScrollUp();
inputs_->scroll_down = inputs->IsScrollDown();
inputs_->right_click = inputs->IsRightMousePressed();
}

View File

@@ -8,12 +8,6 @@ position_class::position_class()
m_positionX = 0.0f;
m_positionY = 0.0f;
m_positionZ = 0.0f;
m_leftTurnSpeed = 0.0f;
m_rightTurnSpeed = 0.0f;
m_horizontalTurnSpeed = 0.0f;
m_verticalTurnSpeed = 0.0f;
m_cameraSpeed = 4.0f;
m_speed = m_cameraSpeed;
}
@@ -46,196 +40,3 @@ void position_class::GetPosition(float& x, float& y, float& z) const
z = m_positionZ;
return;
}
void position_class::TurnLeft(bool keydown)
{
// If the key is pressed increase the speed at which the camera turns left. If not slow down the turn speed.
if (keydown)
{
m_leftTurnSpeed += m_frameTime * 1.5f;
if (m_leftTurnSpeed > (m_frameTime * 200.0f))
{
m_leftTurnSpeed = m_frameTime * 200.0f;
}
}
else
{
m_leftTurnSpeed -= m_frameTime * 1.0f;
if (m_leftTurnSpeed < 0.0f)
{
m_leftTurnSpeed = 0.0f;
}
}
// Update the rotation using the turning speed.
m_rotationY -= m_leftTurnSpeed;
if (m_rotationY < 0.0f)
{
m_rotationY += 360.0f;
}
return;
}
void position_class::TurnRight(bool keydown)
{
// If the key is pressed increase the speed at which the camera turns right. If not slow down the turn speed.
if (keydown)
{
m_rightTurnSpeed += m_frameTime * 1.5f;
if (m_rightTurnSpeed > (m_frameTime * 200.0f))
{
m_rightTurnSpeed = m_frameTime * 200.0f;
}
}
else
{
m_rightTurnSpeed -= m_frameTime * 1.0f;
if (m_rightTurnSpeed < 0.0f)
{
m_rightTurnSpeed = 0.0f;
}
}
// Update the rotation using the turning speed.
m_rotationY += m_rightTurnSpeed;
if (m_rotationY > 360.0f)
{
m_rotationY -= 360.0f;
}
return;
}
void position_class::TurnMouse(float deltaX, float deltaY, float sensitivity, bool rightMouseDown)
{
// The turning speed is proportional to the horizontal mouse movement
m_horizontalTurnSpeed = deltaX * sensitivity;
if (rightMouseDown)
{
// Update the rotation using the turning speed
m_rotationY += m_horizontalTurnSpeed;
if (m_rotationY < 0.0f)
{
m_rotationY += 360.0f;
}
else if (m_rotationY > 360.0f)
{
m_rotationY -= 360.0f;
}
// The turning speed is proportional to the vertical mouse movement
m_verticalTurnSpeed = deltaY * sensitivity;
// Update the rotation using the turning speed
m_rotationX += m_verticalTurnSpeed;
if (m_rotationX < -90.0f)
{
m_rotationX = -90.0f;
}
else if (m_rotationX > 90.0f)
{
m_rotationX = 90.0f;
}
}
return;
}
void position_class::MoveCamera(bool forward, bool backward, bool left, bool right, bool up, bool down, bool scrollUp, bool scrollDown, bool rightClick)
{
float radiansY, radiansX, speed;
// Set the speed of the camera if the right click is down.
if (scrollUp && rightClick)
{
m_cameraSpeed *= 1.1f;
}
if (scrollDown && rightClick)
{
m_cameraSpeed *= 0.9f;
if (m_cameraSpeed < 0.25f) // Minimum speed.
{
m_cameraSpeed = 0.25f;
}
}
// Convert degrees to radians.
radiansY = m_rotationY * 0.0174532925f;
radiansX = m_rotationX * 0.0174532925f;
//////////////////////////
// Update the position. //
//////////////////////////
// Moves the camera forward on a greater scale than the arrows.
if (scrollUp && !rightClick)
{
speed = m_speed * 20 * m_frameTime;
m_positionX += sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ += cosf(radiansY) * cosf(radiansX) * speed;
m_positionY -= sinf(radiansX) * speed;
}
// Moves the camera backward on a greater scale than the arrows.
if (scrollDown && !rightClick)
{
speed = m_speed * 20 * m_frameTime;
m_positionX -= sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ -= cosf(radiansY) * cosf(radiansX) * speed;
m_positionY += sinf(radiansX) * speed;
}
// Set the speed of the camera.
speed = m_cameraSpeed * m_frameTime;
// If moving forward, the position moves in the direction of the camera and accordingly to its angle.
if (forward)
{
m_positionX += sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ += cosf(radiansY) * cosf(radiansX) * speed;
m_positionY -= sinf(radiansX) * speed;
}
// If moving backward, the position moves in the opposite direction of the camera and accordingly to its angle.
if (backward)
{
m_positionX -= sinf(radiansY) * cosf(radiansX) * speed;
m_positionZ -= cosf(radiansY) * cosf(radiansX) * speed;
m_positionY += sinf(radiansX) * speed;
}
// If moving left, the position moves to the left of the camera and accordingly to its angle.
if (left)
{
m_positionX -= cosf(radiansY) * speed;
m_positionZ += sinf(radiansY) * speed;
}
// If moving right, the position moves to the right of the camera and accordingly to its angle.
if (right)
{
m_positionX += cosf(radiansY) * speed;
m_positionZ -= sinf(radiansY) * speed;
}
// If moving up, the position moves up.
if (up)
{
m_positionY += speed;
}
// If moving down, the position moves down.
if (down)
{
m_positionY -= speed;
}
return;
}

BIN
x64/Debug/config.txt (Stored with Git LFS)

Binary file not shown.

BIN
x64/Release/config.txt (Stored with Git LFS)

Binary file not shown.