From 63266928a5e2b6f4b712695eb56cb1de3899ba21 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 15 Sep 2011 00:32:11 +0200 Subject: [PATCH] Made wielded tool move slightly (and smoothly) during view bobbing. Making the tool be a child node of an empty scene node instead of the camera scene node seemingly fixed the uncontrollable tool jitter, too. --- src/camera.cpp | 33 ++++++++++++++++++++++++++++----- src/camera.h | 15 +++++++++++++-- src/game.cpp | 12 ++---------- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index a84ee953c..2cc27fd6e 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -30,6 +30,7 @@ const s32 BOBFRAMES = 0x1000000; // must be a power of two Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_smgr(smgr), m_playernode(NULL), + m_headnode(NULL), m_cameranode(NULL), m_draw_control(draw_control), m_viewing_range_min(5.0), @@ -59,6 +60,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): // note: making the camera node a child of the player node // would lead to unexpected behaviour, so we don't do that. m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode()); + m_headnode = smgr->addEmptySceneNode(m_playernode); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode->bindTargetAndRotation(true); @@ -69,6 +71,26 @@ Camera::~Camera() { } +bool Camera::successfullyCreated(std::wstring& error_message) +{ + if (m_playernode == NULL) + { + error_message = L"Failed to create the player scene node"; + return false; + } + if (m_headnode == NULL) + { + error_message = L"Failed to create the head scene node"; + return false; + } + if (m_cameranode == NULL) + { + error_message = L"Failed to create the camera scene node"; + return false; + } + return true; +} + void Camera::step(f32 dtime) { if (m_view_bobbing_state != 0) @@ -90,16 +112,18 @@ void Camera::step(f32 dtime) void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) { - if (m_playernode == NULL || m_cameranode == NULL) - return; - // Set player node transformation m_playernode->setPosition(player->getPosition()); m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0)); m_playernode->updateAbsolutePosition(); + // Set head node transformation + v3f eye_offset = player->getEyePosition() - player->getPosition(); + m_headnode->setPosition(eye_offset); + m_headnode->setRotation(v3f(player->getPitch(), 0, 0)); + // Compute relative camera position and target - v3f relative_cam_pos = player->getEyePosition() - player->getPosition(); + v3f relative_cam_pos = eye_offset; v3f relative_cam_target = v3f(0,0,1); relative_cam_target.rotateYZBy(player->getPitch()); relative_cam_target += relative_cam_pos; @@ -128,7 +152,6 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) m_cameranode->setPosition(m_camera_position); // *100.0 helps in large map coordinates m_cameranode->setTarget(m_camera_position + 100.0 * m_camera_direction); - // FOV and and aspect ratio m_aspect = (f32)screensize.X / (f32) screensize.Y; m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y)); diff --git a/src/camera.h b/src/camera.h index ba5d72bf4..a6dd7476f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -39,14 +39,21 @@ public: // Get player scene node. // This node is positioned at the player's torso (without any view bobbing), // as given by Player::m_position. Yaw is applied but not pitch. - // Things like wielded tools should be positioned relative to this node. inline scene::ISceneNode* getPlayerNode() const { return m_playernode; } + // Get head scene node. + // It has the eye transformation and pitch applied, + // but no view bobbing. + inline scene::ISceneNode* getHeadNode() const + { + return m_headnode; + } + // Get camera scene node. - // It has the eye transformation and view bobbing applied. + // It has the eye transformation, pitch and view bobbing applied. inline scene::ICameraSceneNode* getCameraNode() const { return m_cameranode; @@ -84,6 +91,9 @@ public: return MYMAX(m_fov_x, m_fov_y); } + // Checks if the constructor was able to create the scene nodes + bool successfullyCreated(std::wstring& error_message); + // Step the camera: updates the viewing range and view bobbing. void step(f32 dtime); @@ -101,6 +111,7 @@ private: // Scene manager and nodes scene::ISceneManager* m_smgr; scene::ISceneNode* m_playernode; + scene::ISceneNode* m_headnode; scene::ICameraSceneNode* m_cameranode; // draw control diff --git a/src/game.cpp b/src/game.cpp index cb7594c30..a712323b5 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -813,16 +813,8 @@ void the_game( Create the camera node */ Camera camera(smgr, draw_control); - if (camera.getPlayerNode() == NULL) - { - error_message = L"Failed to create the player node"; + if (!camera.successfullyCreated(error_message)) return; - } - if (camera.getCameraNode() == NULL) - { - error_message = L"Failed to create the camera node"; - return; - } f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" @@ -856,7 +848,7 @@ void the_game( mesh->addMeshBuffer(buf); buf->drop(); - tool_wield = smgr->addMeshSceneNode(mesh, camera.getCameraNode()); + tool_wield = smgr->addMeshSceneNode(mesh, camera.getHeadNode()); mesh->drop(); } tool_wield->setVisible(false);