From 45999b74e610b13e8cda20c0c420e152b9837ea6 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 16 Apr 2020 18:32:07 +0200 Subject: [PATCH] Camera: Fix shooting line offsets (#9681) Removes duplicated offset calculations from Game and use whatever the Camera class returns. This keeps the eye position nicely in sync, and gets rid of duplicated code. --- src/client/camera.cpp | 24 ++++++++++++++---------- src/client/camera.h | 6 ++++++ src/client/game.cpp | 20 +++++++------------- src/client/localplayer.h | 3 +++ 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/client/camera.cpp b/src/client/camera.cpp index 871ea709d..fb1c3ff56 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -333,17 +333,21 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r fall_bobbing *= m_cache_fall_bobbing_amount; } - // Calculate players eye offset for different camera modes - v3f PlayerEyeOffset = player->getEyeOffset(); - if (m_camera_mode == CAMERA_MODE_FIRST) - PlayerEyeOffset += player->eye_offset_first; - else - PlayerEyeOffset += player->eye_offset_third; + // Calculate and translate the head SceneNode offsets + { + v3f eye_offset = player->getEyeOffset(); + if (m_camera_mode == CAMERA_MODE_FIRST) + eye_offset += player->eye_offset_first; + else + eye_offset += player->eye_offset_third; - // Set head node transformation - m_headnode->setPosition(PlayerEyeOffset+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0)); - m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength)); - m_headnode->updateAbsolutePosition(); + // Set head node transformation + eye_offset.Y += cameratilt * -player->hurt_tilt_strength + fall_bobbing; + m_headnode->setPosition(eye_offset); + m_headnode->setRotation(v3f(player->getPitch(), 0, + cameratilt * player->hurt_tilt_strength)); + m_headnode->updateAbsolutePosition(); + } // Compute relative camera position and target v3f rel_cam_pos = v3f(0,0,0); diff --git a/src/client/camera.h b/src/client/camera.h index 88de3570a..6ec37fe10 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -75,6 +75,12 @@ public: return m_camera_position; } + // Returns the absolute position of the head SceneNode in the world + inline v3f getHeadPosition() const + { + return m_headnode->getAbsolutePosition(); + } + // Get the camera direction (in absolute camera coordinates). // This has view bobbing applied. inline v3f getDirection() const diff --git a/src/client/game.cpp b/src/client/game.cpp index f7234eea6..4b2d7c652 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3029,16 +3029,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) { LocalPlayer *player = client->getEnv().getLocalPlayer(); - v3f player_position = player->getPosition(); - v3f player_eye_position = player->getEyePosition(); - v3f camera_position = camera->getPosition(); - v3f camera_direction = camera->getDirection(); - v3s16 camera_offset = camera->getOffset(); - - if (camera->getCameraMode() == CAMERA_MODE_FIRST) - player_eye_position += player->eye_offset_first; - else - player_eye_position += player->eye_offset_third; + const v3f head_position = camera->getHeadPosition(); + const v3f camera_direction = camera->getDirection(); + const v3s16 camera_offset = camera->getOffset(); /* Calculate what block is the crosshair pointing to @@ -3053,11 +3046,11 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) core::line3d shootline; if (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT) { - shootline = core::line3d(player_eye_position, - player_eye_position + camera_direction * BS * d); + shootline = core::line3d(head_position, + head_position + camera_direction * BS * d); } else { // prevent player pointing anything in front-view - shootline = core::line3d(camera_position, camera_position); + shootline = core::line3d(head_position, head_position); } #ifdef HAVE_TOUCHSCREENGUI @@ -3145,6 +3138,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) } else if (pointed.type == POINTEDTHING_NODE) { handlePointingAtNode(pointed, selected_item, hand_item, dtime); } else if (pointed.type == POINTEDTHING_OBJECT) { + v3f player_position = player->getPosition(); handlePointingAtObject(pointed, tool_item, player_position, show_debug); } else if (input->getLeftState()) { // When button is held down in air, show continuous animation diff --git a/src/client/localplayer.h b/src/client/localplayer.h index d88ae17ac..345aec9d9 100644 --- a/src/client/localplayer.h +++ b/src/client/localplayer.h @@ -135,6 +135,9 @@ public: } v3f getPosition() const { return m_position; } + + // Non-transformed eye offset getters + // For accurate positions, use the Camera functions v3f getEyePosition() const { return m_position + getEyeOffset(); } v3f getEyeOffset() const; void setEyeHeight(float eye_height) { m_eye_height = eye_height; }