Camera: Fix shooting line offsets (#9681)
authorSmallJoker <SmallJoker@users.noreply.github.com>
Thu, 16 Apr 2020 16:32:07 +0000 (18:32 +0200)
committerGitHub <noreply@github.com>
Thu, 16 Apr 2020 16:32:07 +0000 (18:32 +0200)
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
src/client/camera.h
src/client/game.cpp
src/client/localplayer.h

index 871ea709d066b86674adf108e9632a06ba544ee6..fb1c3ff56138ed1442b7b0683e7d53d5aaa9696f 100644 (file)
@@ -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;
-
-       // 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();
+       // 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
+               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);
index 88de3570ae25779ccf65ff6e8dbec570e19f554f..6ec37fe103e7a5a2349d4c0cec854e15382c7499 100644 (file)
@@ -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
index f7234eea622b8481f13cfc0dff12743ddf43066a..4b2d7c6521721ea3588676fb65861b019c7fbc5b 100644 (file)
@@ -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<f32> shootline;
 
        if (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT) {
-               shootline = core::line3d<f32>(player_eye_position,
-                       player_eye_position + camera_direction * BS * d);
+               shootline = core::line3d<f32>(head_position,
+                       head_position + camera_direction * BS * d);
        } else {
                // prevent player pointing anything in front-view
-               shootline = core::line3d<f32>(camera_position, camera_position);
+               shootline = core::line3d<f32>(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
index d88ae17acc6f9e3fc9bc09125b835714b0697ccd..345aec9d99e10321a3634a57899cedc50f792a79 100644 (file)
@@ -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; }