From baf7da9d4a7fc0566840b159903999d76d99a228 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 01:08:47 +0200 Subject: Collected and moved existing camera infrastructure from game.cpp to camera.cpp and camera.h. Introduced configuration settings 'fov' which chooses the camera's (vertical) field of view and 'view_bobbing' which currently does nothing. Other code refactored to not expect the FOV to be a build time constant. --- src/camera.cpp | 243 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 src/camera.cpp (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 000000000..30df439ed --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,243 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "camera.h" +#include "debug.h" +#include "main.h" // for g_settings +#include "map.h" +#include "player.h" +#include "utility.h" +#include + +Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): + m_smgr(smgr), + m_playernode(NULL), + m_cameranode(NULL), + m_draw_control(draw_control), + m_viewing_range_min(5.0), + m_viewing_range_max(5.0), + + m_camera_position(0,0,0), + m_camera_direction(0,0,0), + + m_aspect(1.0), + m_fov_x(1.0), + m_fov_y(1.0), + + m_wanted_frametime(0.0), + m_added_frametime(0), + m_added_frames(0), + m_range_old(0), + m_frametime_old(0), + m_frametime_counter(0), + m_time_per_range(30. / 50), // a sane default of 30ms per 50 nodes of range + + m_view_bobbing_anim(0), + m_view_bobbing_anim_left(0) +{ + dstream<<__FUNCTION_NAME<addEmptySceneNode(smgr->getRootSceneNode()); + m_cameranode = smgr->addCameraSceneNode(m_playernode); + + updateSettings(); +} + +Camera::~Camera() +{ +} + +void Camera::step(f32 dtime) +{ +} + +void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) +{ + if (m_playernode == NULL || m_cameranode == NULL) + return; + + // 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)); + m_cameranode->setAspectRatio(m_aspect); + m_cameranode->setFOV(m_fov_y); + + // Just so big a value that everything rendered is visible + // Some more allowance that m_viewing_range_max * BS because of active objects etc. + m_cameranode->setFarValue(m_viewing_range_max * BS * 10); + + m_camera_position = player->getEyePosition(); // TODO bobbing + m_cameranode->setPosition(m_camera_position); + + m_camera_direction = v3f(0,0,1); + m_camera_direction.rotateYZBy(player->getPitch()); + m_camera_direction.rotateXZBy(player->getYaw()); + // *100.0 helps in large map coordinates + m_cameranode->setTarget(m_camera_position + m_camera_direction * 100.0); + + // Render distance feedback loop + updateViewingRange(frametime); + + // Check if view bobbing is active + v3f speed = player->getSpeed(); + f32 epsilon = BS / 1000.0; + if (speed.X * speed.X + speed.Z * speed.Z > epsilon*epsilon && + speed.Y < epsilon && + g_settings.getBool("view_bobbing") == true && + g_settings.getBool("free_move") == false) + { + // The player seems to be walking on solid ground. + // Enable view bobbing. + //dstream << "View bobbing active" << std::endl; + } + else + { + //dstream << "View bobbing inactive" << std::endl; + } +} + +void Camera::updateViewingRange(f32 frametime_in) +{ + if (m_draw_control.range_all) + return; + + m_added_frametime += frametime_in; + m_added_frames += 1; + + // Actually this counter kind of sucks because frametime is busytime + m_frametime_counter -= frametime_in; + if (m_frametime_counter > 0) + return; + m_frametime_counter = 0.2; + + dstream<<__FUNCTION_NAME + <<": Collected "< Date: Thu, 8 Sep 2011 01:24:47 +0200 Subject: Commented out debug statements again --- src/camera.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 30df439ed..9eb8f1a69 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -51,7 +51,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_view_bobbing_anim(0), m_view_bobbing_anim_left(0) { - dstream<<__FUNCTION_NAME<addEmptySceneNode(smgr->getRootSceneNode()); m_cameranode = smgr->addCameraSceneNode(m_playernode); @@ -126,7 +126,7 @@ void Camera::updateViewingRange(f32 frametime_in) return; m_frametime_counter = 0.2; - dstream<<__FUNCTION_NAME + /*dstream<<__FUNCTION_NAME <<": Collected "< Date: Thu, 8 Sep 2011 13:03:55 +0200 Subject: Implemented view bobbing (testing simple lemniscate shape) --- src/camera.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 23 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 9eb8f1a69..16fad6132 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -49,12 +49,15 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_time_per_range(30. / 50), // a sane default of 30ms per 50 nodes of range m_view_bobbing_anim(0), - m_view_bobbing_anim_left(0) + m_view_bobbing_state(0) { //dstream<<__FUNCTION_NAME<addEmptySceneNode(smgr->getRootSceneNode()); - m_cameranode = smgr->addCameraSceneNode(m_playernode); + m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); + m_cameranode->bindTargetAndRotation(true); updateSettings(); } @@ -65,6 +68,21 @@ Camera::~Camera() void Camera::step(f32 dtime) { + if (m_view_bobbing_state != 0) + { + const f32 bobspeed = 0x1000000; + s32 offset = MYMAX(dtime * bobspeed, 1); + if (m_view_bobbing_state == 2) + { + // Animation is getting turned off + s32 subanim = (m_view_bobbing_anim & 0x7fffff); + if (subanim < 0x400000) + offset = -1 * MYMIN(offset, subanim); + else + offset = MYMIN(offset, 0x800000 - subanim); + } + m_view_bobbing_anim = (m_view_bobbing_anim + offset) & 0xffffff; + } } void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) @@ -72,43 +90,66 @@ 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(player->getPitch(), -1 * player->getYaw(), 0)); + m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0)); + m_playernode->updateAbsolutePosition(); + + // Compute relative camera position and target + v3f relative_cam_pos = player->getEyePosition() - player->getPosition(); + v3f relative_cam_target = v3f(0,0,1); + relative_cam_target.rotateYZBy(player->getPitch()); + relative_cam_target += relative_cam_pos; + + f32 bobangle = m_view_bobbing_anim * 2 * M_PI / 0x1000000; + f32 bobangle_s = sin(bobangle); + f32 bobangle_c = cos(bobangle); + f32 bobwidth = 0.03 * cos(player->getPitch() * M_PI / 180) + / (bobangle_c * bobangle_c + 1); + f32 bobheight = bobwidth; + relative_cam_pos.X += bobwidth * bobangle_s; + relative_cam_pos.Y += bobheight * bobangle_s * bobangle_c; + + // Compute absolute camera position and target + m_playernode->getAbsoluteTransformation().transformVect(m_camera_position, relative_cam_pos); + m_playernode->getAbsoluteTransformation().transformVect(m_camera_direction, relative_cam_target); + m_camera_direction -= m_camera_position; + + // Set camera node transformation + 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)); m_cameranode->setAspectRatio(m_aspect); m_cameranode->setFOV(m_fov_y); - // Just so big a value that everything rendered is visible // Some more allowance that m_viewing_range_max * BS because of active objects etc. m_cameranode->setFarValue(m_viewing_range_max * BS * 10); - m_camera_position = player->getEyePosition(); // TODO bobbing - m_cameranode->setPosition(m_camera_position); - - m_camera_direction = v3f(0,0,1); - m_camera_direction.rotateYZBy(player->getPitch()); - m_camera_direction.rotateXZBy(player->getYaw()); - // *100.0 helps in large map coordinates - m_cameranode->setTarget(m_camera_position + m_camera_direction * 100.0); - // Render distance feedback loop updateViewingRange(frametime); - // Check if view bobbing is active + // If the player seems to be walking on solid ground, + // view bobbing is enabled and free_move is off, + // start (or continue) the view bobbing animation. v3f speed = player->getSpeed(); - f32 epsilon = BS / 1000.0; - if (speed.X * speed.X + speed.Z * speed.Z > epsilon*epsilon && - speed.Y < epsilon && - g_settings.getBool("view_bobbing") == true && - g_settings.getBool("free_move") == false) + //dstream<<"speed: ("< BS) && + (fabs(speed.Y) < BS/10) && + (g_settings.getBool("view_bobbing") == true) && + (g_settings.getBool("free_move") == false)) { - // The player seems to be walking on solid ground. - // Enable view bobbing. - //dstream << "View bobbing active" << std::endl; + // Start animation + m_view_bobbing_state = 1; } - else + else if (m_view_bobbing_state == 1) { - //dstream << "View bobbing inactive" << std::endl; + // Stop animation + m_view_bobbing_state = 2; } } -- cgit v1.2.3 From 0931d4b7ff95dc9b51bee28851c3780b2648ffd0 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 13:14:59 +0200 Subject: make it slightly less annoying :o) --- src/camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 16fad6132..bdfbc88c2 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -105,7 +105,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) f32 bobangle = m_view_bobbing_anim * 2 * M_PI / 0x1000000; f32 bobangle_s = sin(bobangle); f32 bobangle_c = cos(bobangle); - f32 bobwidth = 0.03 * cos(player->getPitch() * M_PI / 180) + f32 bobwidth = 0.02 * cos(player->getPitch() * M_PI / 180) / (bobangle_c * bobangle_c + 1); f32 bobheight = bobwidth; relative_cam_pos.X += bobwidth * bobangle_s; -- cgit v1.2.3 From f2ec2265216f4621558003dcbd8974f76063576b Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 13:34:28 +0200 Subject: minor view bobbing improvements --- src/camera.cpp | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index bdfbc88c2..7c3dfda3c 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include +const s32 BOBFRAMES = 0x1000000; // must be a power of two + Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_smgr(smgr), m_playernode(NULL), @@ -70,18 +72,17 @@ void Camera::step(f32 dtime) { if (m_view_bobbing_state != 0) { - const f32 bobspeed = 0x1000000; - s32 offset = MYMAX(dtime * bobspeed, 1); + s32 offset = MYMAX(dtime * BOBFRAMES, 1); if (m_view_bobbing_state == 2) { // Animation is getting turned off - s32 subanim = (m_view_bobbing_anim & 0x7fffff); - if (subanim < 0x400000) + s32 subanim = (m_view_bobbing_anim & (BOBFRAMES/2-1)); + if (subanim < BOBFRAMES/4) offset = -1 * MYMIN(offset, subanim); else - offset = MYMIN(offset, 0x800000 - subanim); + offset = MYMIN(offset, BOBFRAMES/2 - subanim); } - m_view_bobbing_anim = (m_view_bobbing_anim + offset) & 0xffffff; + m_view_bobbing_anim = (m_view_bobbing_anim + offset) & (BOBFRAMES-1); } } @@ -102,14 +103,20 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) relative_cam_target.rotateYZBy(player->getPitch()); relative_cam_target += relative_cam_pos; - f32 bobangle = m_view_bobbing_anim * 2 * M_PI / 0x1000000; - f32 bobangle_s = sin(bobangle); - f32 bobangle_c = cos(bobangle); - f32 bobwidth = 0.02 * cos(player->getPitch() * M_PI / 180) - / (bobangle_c * bobangle_c + 1); - f32 bobheight = bobwidth; - relative_cam_pos.X += bobwidth * bobangle_s; - relative_cam_pos.Y += bobheight * bobangle_s * bobangle_c; + if ((m_view_bobbing_anim & (BOBFRAMES/2-1)) != 0) + { + f32 bobamount = cos(player->getPitch() * M_PI / 180); + bobamount = 2 * MYMIN(bobamount, 0.5); + + f32 bobangle = m_view_bobbing_anim * 2 * M_PI / BOBFRAMES; + f32 bobangle_s = sin(bobangle); + f32 bobangle_c = cos(bobangle); + f32 bobwidth = 0.02 * bobamount / (bobangle_c * bobangle_c + 1); + f32 bobheight = 1.5 * bobwidth; + + relative_cam_pos.X += bobwidth * bobangle_s; + relative_cam_pos.Y += bobheight * bobangle_s * bobangle_c; + } // Compute absolute camera position and target m_playernode->getAbsoluteTransformation().transformVect(m_camera_position, relative_cam_pos); -- cgit v1.2.3 From e4cb0044602f2dc5eb92c8955797b628c158a0d9 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 16:10:44 +0200 Subject: trying something else... also replaced M_PI by PI everywhere --- src/camera.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 7c3dfda3c..8dc1af02b 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -105,10 +105,10 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) if ((m_view_bobbing_anim & (BOBFRAMES/2-1)) != 0) { - f32 bobamount = cos(player->getPitch() * M_PI / 180); + f32 bobamount = cos(player->getPitch() * PI / 180); bobamount = 2 * MYMIN(bobamount, 0.5); - f32 bobangle = m_view_bobbing_anim * 2 * M_PI / BOBFRAMES; + f32 bobangle = m_view_bobbing_anim * 2 * PI / BOBFRAMES; f32 bobangle_s = sin(bobangle); f32 bobangle_c = cos(bobangle); f32 bobwidth = 0.02 * bobamount / (bobangle_c * bobangle_c + 1); @@ -282,7 +282,7 @@ void Camera::updateSettings() f32 fov_degrees = g_settings.getFloat("fov"); fov_degrees = MYMAX(fov_degrees, 10.0); fov_degrees = MYMIN(fov_degrees, 170.0); - m_fov_y = fov_degrees * M_PI / 180.0; + m_fov_y = fov_degrees * PI / 180.0; f32 wanted_fps = g_settings.getFloat("wanted_fps"); wanted_fps = MYMAX(wanted_fps, 1.0); -- cgit v1.2.3 From fc92da432401051a8cc17618941625aec6b12d20 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 23:31:48 +0200 Subject: View bobbing is slower in the water. --- src/camera.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 8dc1af02b..a84ee953c 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -19,10 +19,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "camera.h" #include "debug.h" +#include "client.h" #include "main.h" // for g_settings #include "map.h" #include "player.h" -#include "utility.h" #include const s32 BOBFRAMES = 0x1000000; // must be a power of two @@ -51,7 +51,8 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_time_per_range(30. / 50), // a sane default of 30ms per 50 nodes of range m_view_bobbing_anim(0), - m_view_bobbing_state(0) + m_view_bobbing_state(0), + m_view_bobbing_slow(false) { //dstream<<__FUNCTION_NAME<setPosition(player->getPosition()); - //m_playernode->setRotation(v3f(player->getPitch(), -1 * player->getYaw(), 0)); m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0)); m_playernode->updateAbsolutePosition(); @@ -144,9 +145,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) // view bobbing is enabled and free_move is off, // start (or continue) the view bobbing animation. v3f speed = player->getSpeed(); - //dstream<<"speed: ("< BS) && - (fabs(speed.Y) < BS/10) && + (player->touching_ground) && (g_settings.getBool("view_bobbing") == true) && (g_settings.getBool("free_move") == false)) { @@ -158,6 +158,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) // Stop animation m_view_bobbing_state = 2; } + m_view_bobbing_slow = player->in_water_stable; } void Camera::updateViewingRange(f32 frametime_in) -- cgit v1.2.3 From 63266928a5e2b6f4b712695eb56cb1de3899ba21 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 15 Sep 2011 00:32:11 +0200 Subject: 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 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'src/camera.cpp') 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)); -- cgit v1.2.3 From ae66d611f2020e0fddb45f40af2d42c13e7ba585 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Sun, 18 Sep 2011 02:17:39 +0200 Subject: This looks more like MC view bobbing, but still not even close --- src/camera.cpp | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 2cc27fd6e..0c6fe1df5 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -53,7 +53,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_view_bobbing_anim(0), m_view_bobbing_state(0), - m_view_bobbing_slow(false) + m_view_bobbing_speed(0) { //dstream<<__FUNCTION_NAME<setRotation(v3f(player->getPitch(), 0, 0)); // Compute relative camera position and target - 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; + v3f rel_cam_pos = v3f(0,0,0); + v3f rel_cam_target = v3f(0,0,1); - if ((m_view_bobbing_anim & (BOBFRAMES/2-1)) != 0) + s32 bobframe = m_view_bobbing_anim & (BOBFRAMES/2-1); + if (bobframe != 0) { - f32 bobamount = cos(player->getPitch() * PI / 180); - bobamount = 2 * MYMIN(bobamount, 0.5); + f32 bobfrac = (f32) bobframe / (BOBFRAMES/2); + f32 bobdir = (m_view_bobbing_anim < (BOBFRAMES/2)) ? 1.0 : -1.0; - f32 bobangle = m_view_bobbing_anim * 2 * PI / BOBFRAMES; - f32 bobangle_s = sin(bobangle); - f32 bobangle_c = cos(bobangle); - f32 bobwidth = 0.02 * bobamount / (bobangle_c * bobangle_c + 1); - f32 bobheight = 1.5 * bobwidth; + f32 bobknob = 1.2; + f32 bobtmp = sin(pow(bobfrac, bobknob) * PI); - relative_cam_pos.X += bobwidth * bobangle_s; - relative_cam_pos.Y += bobheight * bobangle_s * bobangle_c; + v3f bobvec = v3f( + 0.01 * bobdir * sin(bobfrac * PI), + 0.005 * bobtmp * bobtmp, + 0.); + + rel_cam_pos += bobvec * 3.; + rel_cam_target += bobvec * 1.5; } // Compute absolute camera position and target - m_playernode->getAbsoluteTransformation().transformVect(m_camera_position, relative_cam_pos); - m_playernode->getAbsoluteTransformation().transformVect(m_camera_direction, relative_cam_target); + m_headnode->getAbsoluteTransformation().transformVect(m_camera_position, rel_cam_pos); + m_headnode->getAbsoluteTransformation().transformVect(m_camera_direction, rel_cam_target); m_camera_direction -= m_camera_position; // Set camera node transformation m_cameranode->setPosition(m_camera_position); - // *100.0 helps in large map coordinates - m_cameranode->setTarget(m_camera_position + 100.0 * m_camera_direction); + m_cameranode->setTarget(m_camera_position + 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)); @@ -175,13 +175,19 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) { // Start animation m_view_bobbing_state = 1; + m_view_bobbing_speed = MYMIN(speed.getLength(), 40); } else if (m_view_bobbing_state == 1) { // Stop animation m_view_bobbing_state = 2; + m_view_bobbing_speed = 100; + } + else if (m_view_bobbing_state == 2 && bobframe == 0) + { + // Stop animation completed + m_view_bobbing_state = 0; } - m_view_bobbing_slow = player->in_water_stable; } void Camera::updateViewingRange(f32 frametime_in) -- cgit v1.2.3 From 54f3796f9105cb220c95aa6c2e80516cdd4e4a00 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Sun, 18 Sep 2011 02:24:43 +0200 Subject: Oops, up vector is needed. --- src/camera.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 0c6fe1df5..a9497152b 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -120,10 +120,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) v3f eye_offset = player->getEyePosition() - player->getPosition(); m_headnode->setPosition(eye_offset); m_headnode->setRotation(v3f(player->getPitch(), 0, 0)); + m_headnode->updateAbsolutePosition(); // Compute relative camera position and target v3f rel_cam_pos = v3f(0,0,0); v3f rel_cam_target = v3f(0,0,1); + v3f rel_cam_up = v3f(0,1,0); s32 bobframe = m_view_bobbing_anim & (BOBFRAMES/2-1); if (bobframe != 0) @@ -140,7 +142,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) 0.); rel_cam_pos += bobvec * 3.; - rel_cam_target += bobvec * 1.5; + rel_cam_target += bobvec * 4.5; } // Compute absolute camera position and target @@ -148,8 +150,13 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) m_headnode->getAbsoluteTransformation().transformVect(m_camera_direction, rel_cam_target); m_camera_direction -= m_camera_position; + v3f abs_cam_up; + m_headnode->getAbsoluteTransformation().transformVect(abs_cam_up, rel_cam_pos + rel_cam_up); + abs_cam_up -= m_camera_position; + // Set camera node transformation m_cameranode->setPosition(m_camera_position); + m_cameranode->setUpVector(abs_cam_up); m_cameranode->setTarget(m_camera_position + m_camera_direction); // FOV and and aspect ratio -- cgit v1.2.3 From 4ed837bcfa2d9601c6b5c3d2e8d37ad9f5a6e2a6 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Sun, 18 Sep 2011 17:02:30 +0200 Subject: trying some view bobbing changes --- src/camera.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index a9497152b..43009bd7c 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -133,16 +133,31 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) f32 bobfrac = (f32) bobframe / (BOBFRAMES/2); f32 bobdir = (m_view_bobbing_anim < (BOBFRAMES/2)) ? 1.0 : -1.0; + #if 1 f32 bobknob = 1.2; f32 bobtmp = sin(pow(bobfrac, bobknob) * PI); v3f bobvec = v3f( - 0.01 * bobdir * sin(bobfrac * PI), - 0.005 * bobtmp * bobtmp, + bobdir * sin(bobfrac * PI), + 0.8 * bobtmp * bobtmp, 0.); - rel_cam_pos += bobvec * 3.; - rel_cam_target += bobvec * 4.5; + rel_cam_pos += 0.03 * bobvec; + rel_cam_target += 0.045 * bobvec; + rel_cam_up.rotateXYBy(0.03 * bobdir * bobtmp * PI); + #else + f32 angle_deg = 1 * bobdir * sin(bobfrac * PI); + f32 angle_rad = angle_deg * PI / 180; + f32 r = 0.05; + v3f off = v3f( + r * sin(angle_rad), + r * (cos(angle_rad) - 1), + 0); + rel_cam_pos += off; + //rel_cam_target += off; + rel_cam_up.rotateXYBy(angle_deg); + #endif + } // Compute absolute camera position and target -- cgit v1.2.3 From 36bcbca9acabbc47976d3d7625ffb1c9396b8fdc Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Sep 2011 03:01:11 +0200 Subject: Added sprite extruder --- src/camera.cpp | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 43009bd7c..aae36c512 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -63,6 +63,8 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_headnode = smgr->addEmptySceneNode(m_playernode); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode->bindTargetAndRotation(true); + m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1, v3f(0, 120, 10), v3f(0, 0, 0), v3f(100, 100, 100)); + //m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1); updateSettings(); } @@ -341,3 +343,350 @@ void Camera::updateSettings() m_wanted_frametime = 1.0 / wanted_fps; } +void Camera::wield(InventoryItem* item) +{ + if (item != NULL) + { + dstream << "wield item: " << item->getName() << std::endl; + m_wieldnode->setSprite(item->getImageRaw()); + m_wieldnode->setVisible(true); + } + else + { + dstream << "wield item: none" << std::endl; + m_wieldnode->setVisible(false); + } +} + +void Camera::setDigging(bool digging) +{ + // TODO +} + + +ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode( + scene::ISceneNode* parent, + scene::ISceneManager* mgr, + s32 id, + const v3f& position, + const v3f& rotation, + const v3f& scale +): + ISceneNode(parent, mgr, id, position, rotation, scale) +{ + m_meshnode = mgr->addMeshSceneNode(NULL, this, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true); + m_thickness = 0.1; + m_cubemesh = NULL; + m_is_cube = false; +} + +ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode() +{ + removeChild(m_meshnode); + if (m_cubemesh) + m_cubemesh->drop(); +} + +void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) +{ + if (texture == NULL) + { + m_meshnode->setVisible(false); + return; + } + + io::path name = getExtrudedName(texture); + scene::IMeshCache* cache = SceneManager->getMeshCache(); + scene::IAnimatedMesh* mesh = cache->getMeshByName(name); + if (mesh != NULL) + { + // Extruded texture has been found in cache. + m_meshnode->setMesh(mesh); + } + else + { + // Texture was not yet extruded, do it now and save in cache + mesh = extrude(texture); + if (mesh == NULL) + { + dstream << "Warning: failed to extrude sprite" << std::endl; + m_meshnode->setVisible(false); + return; + } + cache->addMesh(name, mesh); + m_meshnode->setMesh(mesh); + mesh->drop(); + } + + m_meshnode->setScale(v3f(1, 1, m_thickness)); + m_meshnode->getMaterial(0).setTexture(0, texture); + m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false); + m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false); + m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + m_meshnode->setVisible(true); + m_is_cube = false; +} + +void ExtrudedSpriteSceneNode::setCube(video::ITexture* texture) +{ + if (texture == NULL) + { + m_meshnode->setVisible(false); + return; + } + + if (m_cubemesh == NULL) + m_cubemesh = SceneManager->getGeometryCreator()->createCubeMesh(v3f(1)); + + m_meshnode->setMesh(m_cubemesh); + m_meshnode->setScale(v3f(1)); + m_meshnode->getMaterial(0).setTexture(0, texture); + m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false); + m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false); + m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + m_meshnode->setVisible(true); + m_is_cube = true; +} + +void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture) +{ + scene::IMeshCache* cache = SceneManager->getMeshCache(); + scene::IAnimatedMesh* mesh = cache->getMeshByName(getExtrudedName(texture)); + if (mesh != NULL) + cache->removeMesh(mesh); +} + +void ExtrudedSpriteSceneNode::setSpriteThickness(f32 thickness) +{ + m_thickness = thickness; + if (!m_is_cube) + m_meshnode->setScale(v3f(1, 1, thickness)); +} + +const core::aabbox3d& ExtrudedSpriteSceneNode::getBoundingBox() const +{ + return m_meshnode->getBoundingBox(); +} + +void ExtrudedSpriteSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); +} + +void ExtrudedSpriteSceneNode::render() +{ + // do nothing +} + +io::path ExtrudedSpriteSceneNode::getExtrudedName(video::ITexture* texture) +{ + io::path path = texture->getName(); + path.append("/[extruded]"); + return path; +} + +scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height, u8* data) +{ + const s32 argb_wstep = 4 * width; + const s32 alpha_threshold = 1; + + scene::IMeshBuffer* buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + + // Front and back + { + video::S3DVertex vertices[8] = + { + video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), + video::S3DVertex(-0.5,0.5,-0.5, 0,0,-1, c, 0,0), + video::S3DVertex(0.5,0.5,-0.5, 0,0,-1, c, 1,0), + video::S3DVertex(0.5,-0.5,-0.5, 0,0,-1, c, 1,1), + video::S3DVertex(0.5,-0.5,0.5, 0,0,1, c, 1,1), + video::S3DVertex(0.5,0.5,0.5, 0,0,1, c, 1,0), + video::S3DVertex(-0.5,0.5,0.5, 0,0,1, c, 0,0), + video::S3DVertex(-0.5,-0.5,0.5, 0,0,1, c, 0,1), + }; + u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; + buf->append(vertices, 8, indices, 12); + } + + // "Interior" + // (add faces where a solid pixel is next to a transparent one) + u8* solidity = new u8[(width+2) * (height+2)]; + u32 wstep = width + 2; + for (u32 y = 0; y < height + 2; ++y) + { + u8* scanline = solidity + y * wstep; + if (y == 0 || y == height + 1) + { + for (u32 x = 0; x < width + 2; ++x) + scanline[x] = 0; + } + else + { + scanline[0] = 0; + u8* argb_scanline = data + (y - 1) * argb_wstep; + for (u32 x = 0; x < width; ++x) + scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold); + scanline[width + 1] = 0; + } + } + + // without this, there would be occasional "holes" in the mesh + f32 eps = 0.01; + + for (u32 y = 0; y <= height; ++y) + { + u8* scanline = solidity + y * wstep + 1; + for (u32 x = 0; x <= width; ++x) + { + if (scanline[x] && !scanline[x + wstep]) + { + u32 xx = x + 1; + while (scanline[xx] && !scanline[xx + wstep]) + ++xx; + f32 vx1 = (x - eps) / (f32) width - 0.5; + f32 vx2 = (xx + eps) / (f32) width - 0.5; + f32 vy = 0.5 - (y - eps) / (f32) height; + f32 tx1 = x / (f32) width; + f32 tx2 = xx / (f32) width; + f32 ty = (y - 0.5) / (f32) height; + video::S3DVertex vertices[8] = + { + video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty), + video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty), + video::S3DVertex(vx2,vy,0.5, 0,-1,0, c, tx2,ty), + video::S3DVertex(vx1,vy,0.5, 0,-1,0, c, tx1,ty), + }; + u16 indices[6] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + x = xx - 1; + } + if (!scanline[x] && scanline[x + wstep]) + { + u32 xx = x + 1; + while (!scanline[xx] && scanline[xx + wstep]) + ++xx; + f32 vx1 = (x - eps) / (f32) width - 0.5; + f32 vx2 = (xx + eps) / (f32) width - 0.5; + f32 vy = 0.5 - (y + eps) / (f32) height; + f32 tx1 = x / (f32) width; + f32 tx2 = xx / (f32) width; + f32 ty = (y + 0.5) / (f32) height; + video::S3DVertex vertices[8] = + { + video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty), + video::S3DVertex(vx1,vy,0.5, 0,1,0, c, tx1,ty), + video::S3DVertex(vx2,vy,0.5, 0,1,0, c, tx2,ty), + video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty), + }; + u16 indices[6] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + x = xx - 1; + } + } + } + + for (u32 x = 0; x <= width; ++x) + { + u8* scancol = solidity + x + wstep; + for (u32 y = 0; y <= height; ++y) + { + if (scancol[y * wstep] && !scancol[y * wstep + 1]) + { + u32 yy = y + 1; + while (scancol[yy * wstep] && !scancol[yy * wstep + 1]) + ++yy; + f32 vx = (x - eps) / (f32) width - 0.5; + f32 vy1 = 0.5 - (y - eps) / (f32) height; + f32 vy2 = 0.5 - (yy + eps) / (f32) height; + f32 tx = (x - 0.5) / (f32) width; + f32 ty1 = y / (f32) height; + f32 ty2 = yy / (f32) height; + video::S3DVertex vertices[8] = + { + video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1), + video::S3DVertex(vx,vy1,0.5, 1,0,0, c, tx,ty1), + video::S3DVertex(vx,vy2,0.5, 1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2), + }; + u16 indices[6] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + y = yy - 1; + } + if (!scancol[y * wstep] && scancol[y * wstep + 1]) + { + u32 yy = y + 1; + while (!scancol[yy * wstep] && scancol[yy * wstep + 1]) + ++yy; + f32 vx = (x + eps) / (f32) width - 0.5; + f32 vy1 = 0.5 - (y - eps) / (f32) height; + f32 vy2 = 0.5 - (yy + eps) / (f32) height; + f32 tx = (x + 0.5) / (f32) width; + f32 ty1 = y / (f32) height; + f32 ty2 = yy / (f32) height; + video::S3DVertex vertices[8] = + { + video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1), + video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy2,0.5, -1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy1,0.5, -1,0,0, c, tx,ty1), + }; + u16 indices[6] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + y = yy - 1; + } + } + } + + // Add to mesh + scene::SMesh* mesh = new scene::SMesh(); + mesh->addMeshBuffer(buf); + buf->drop(); + mesh->recalculateBoundingBox(); + scene::SAnimatedMesh* anim_mesh = new scene::SAnimatedMesh(mesh); + mesh->drop(); + return anim_mesh; +} + +scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture) +{ + scene::IAnimatedMesh* mesh = NULL; + core::dimension2d size = texture->getSize(); + video::ECOLOR_FORMAT format = texture->getColorFormat(); + if (format == video::ECF_A8R8G8B8) + { + // Texture is in the correct color format, we can pass it + // to extrudeARGB right away. + void* data = texture->lock(true); + if (data == NULL) + return NULL; + mesh = extrudeARGB(size.Width, size.Height, (u8*) data); + texture->unlock(); + } + else + { + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + video::IImage* img1 = driver->createImageFromData(format, size, texture->lock(true)); + if (img1 == NULL) + return NULL; + + // img1 is in the texture's color format, convert to 8-bit ARGB + video::IImage* img2 = driver->createImage(video::ECF_A8R8G8B8, size); + if (img2 != NULL) + { + img1->copyTo(img2); + img1->drop(); + + mesh = extrudeARGB(size.Width, size.Height, (u8*) img2->lock()); + img2->unlock(); + img2->drop(); + } + img1->drop(); + } + return mesh; +} + -- cgit v1.2.3 From 02726f00031c8ffadf5298b037b595372be202ef Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Sep 2011 06:37:24 +0200 Subject: Convert any inventory item into a mesh, bring back InventoryItem::getImageRay(), some const-correctness fixes --- src/camera.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 31 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index aae36c512..e7d506177 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // for g_settings #include "map.h" #include "player.h" +#include "tile.h" #include const s32 BOBFRAMES = 0x1000000; // must be a power of two @@ -343,17 +344,37 @@ void Camera::updateSettings() m_wanted_frametime = 1.0 / wanted_fps; } -void Camera::wield(InventoryItem* item) +void Camera::wield(const InventoryItem* item) { if (item != NULL) { - dstream << "wield item: " << item->getName() << std::endl; - m_wieldnode->setSprite(item->getImageRaw()); + bool isCube = false; + + // Try to make a MaterialItem cube. + if (std::string(item->getName()) == "MaterialItem") + { + // A block-type material + MaterialItem* mat_item = (MaterialItem*) item; + content_t content = mat_item->getMaterial(); + if (content_features(content).solidness) + { + m_wieldnode->setCube(content_features(content).tiles); + isCube = true; + } + } + + // If that failed, make an extruded sprite. + if (!isCube) + { + m_wieldnode->setSprite(item->getImageRaw()); + } + m_wieldnode->setVisible(true); } else { - dstream << "wield item: none" << std::endl; + // Bare hands + dstream << "bare hands" << std::endl; m_wieldnode->setVisible(false); } } @@ -427,23 +448,37 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) m_is_cube = false; } -void ExtrudedSpriteSceneNode::setCube(video::ITexture* texture) +void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6]) { - if (texture == NULL) - { - m_meshnode->setVisible(false); - return; - } - if (m_cubemesh == NULL) - m_cubemesh = SceneManager->getGeometryCreator()->createCubeMesh(v3f(1)); + m_cubemesh = createCubeMesh(); m_meshnode->setMesh(m_cubemesh); m_meshnode->setScale(v3f(1)); - m_meshnode->getMaterial(0).setTexture(0, texture); - m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false); - m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false); - m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + for (int i = 0; i < 6; ++i) + { + // Get the tile texture and atlas transformation + u32 texture_id = tiles[i].texture.id; + video::ITexture* atlas = NULL; + v2f pos(0,0); + v2f size(1,1); + if (g_texturesource) + { + AtlasPointer ap = g_texturesource->getTexture(texture_id); + atlas = ap.atlas; + pos = ap.pos; + size = ap.size; + } + + // Set material flags and texture + video::SMaterial& material = m_meshnode->getMaterial(i); + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + tiles[i].applyMaterialOptions(material); + material.setTexture(0, atlas); + material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y); + material.getTextureMatrix(0).setTextureScale(size.X, size.Y); + } m_meshnode->setVisible(true); m_is_cube = true; } @@ -500,13 +535,13 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height video::S3DVertex vertices[8] = { video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), - video::S3DVertex(-0.5,0.5,-0.5, 0,0,-1, c, 0,0), - video::S3DVertex(0.5,0.5,-0.5, 0,0,-1, c, 1,0), - video::S3DVertex(0.5,-0.5,-0.5, 0,0,-1, c, 1,1), - video::S3DVertex(0.5,-0.5,0.5, 0,0,1, c, 1,1), - video::S3DVertex(0.5,0.5,0.5, 0,0,1, c, 1,0), - video::S3DVertex(-0.5,0.5,0.5, 0,0,1, c, 0,0), - video::S3DVertex(-0.5,-0.5,0.5, 0,0,1, c, 0,1), + video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0), + video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0), + video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1), + video::S3DVertex(+0.5,-0.5,+0.5, 0,0,+1, c, 1,1), + video::S3DVertex(+0.5,+0.5,+0.5, 0,0,+1, c, 1,0), + video::S3DVertex(-0.5,+0.5,+0.5, 0,0,+1, c, 0,0), + video::S3DVertex(-0.5,-0.5,+0.5, 0,0,+1, c, 0,1), }; u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; buf->append(vertices, 8, indices, 12); @@ -557,8 +592,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height { video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty), video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty), - video::S3DVertex(vx2,vy,0.5, 0,-1,0, c, tx2,ty), - video::S3DVertex(vx1,vy,0.5, 0,-1,0, c, tx1,ty), + video::S3DVertex(vx2,vy,+0.5, 0,-1,0, c, tx2,ty), + video::S3DVertex(vx1,vy,+0.5, 0,-1,0, c, tx1,ty), }; u16 indices[6] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); @@ -578,8 +613,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height video::S3DVertex vertices[8] = { video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty), - video::S3DVertex(vx1,vy,0.5, 0,1,0, c, tx1,ty), - video::S3DVertex(vx2,vy,0.5, 0,1,0, c, tx2,ty), + video::S3DVertex(vx1,vy,+0.5, 0,1,0, c, tx1,ty), + video::S3DVertex(vx2,vy,+0.5, 0,1,0, c, tx2,ty), video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty), }; u16 indices[6] = {0,1,2,2,3,0}; @@ -608,8 +643,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height video::S3DVertex vertices[8] = { video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1), - video::S3DVertex(vx,vy1,0.5, 1,0,0, c, tx,ty1), - video::S3DVertex(vx,vy2,0.5, 1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy1,+0.5, 1,0,0, c, tx,ty1), + video::S3DVertex(vx,vy2,+0.5, 1,0,0, c, tx,ty2), video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2), }; u16 indices[6] = {0,1,2,2,3,0}; @@ -631,8 +666,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height { video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1), video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2), - video::S3DVertex(vx,vy2,0.5, -1,0,0, c, tx,ty2), - video::S3DVertex(vx,vy1,0.5, -1,0,0, c, tx,ty1), + video::S3DVertex(vx,vy2,+0.5, -1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy1,+0.5, -1,0,0, c, tx,ty1), }; u16 indices[6] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); @@ -643,6 +678,7 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height // Add to mesh scene::SMesh* mesh = new scene::SMesh(); + buf->recalculateBoundingBox(); mesh->addMeshBuffer(buf); buf->drop(); mesh->recalculateBoundingBox(); @@ -690,3 +726,54 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture) return mesh; } +scene::IMesh* ExtrudedSpriteSceneNode::createCubeMesh() +{ + video::SColor c(255,255,255,255); + video::S3DVertex vertices[24] = + { + // Up + video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1), + video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0), + video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0), + video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1), + // Down + video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0), + video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0), + video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1), + video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1), + // Right + video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1), + video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0), + video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0), + video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1), + // Left + video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1), + video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1), + video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0), + video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0), + // Back + video::S3DVertex(-0.5,-0.5,+0.5, 0,0,-1, c, 1,1), + video::S3DVertex(+0.5,-0.5,+0.5, 0,0,-1, c, 0,1), + video::S3DVertex(+0.5,+0.5,+0.5, 0,0,-1, c, 0,0), + video::S3DVertex(-0.5,+0.5,+0.5, 0,0,-1, c, 1,0), + // Front + video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), + video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0), + video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0), + video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1), + }; + + u16 indices[6] = {0,1,2,2,3,0}; + + scene::SMesh* mesh = new scene::SMesh(); + for (u32 i=0; i<6; ++i) + { + scene::IMeshBuffer* buf = new scene::SMeshBuffer(); + buf->append(vertices + 4 * i, 4, indices, 6); + buf->recalculateBoundingBox(); + mesh->addMeshBuffer(buf); + buf->drop(); + } + mesh->recalculateBoundingBox(); + return mesh; +} -- cgit v1.2.3 From ab42549b1e48ede22d96e9f4ac017bb5d1853724 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Sep 2011 17:08:42 +0200 Subject: Wielded tool updates, leaves and glass work now --- src/camera.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index e7d506177..c5c40f5c5 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -54,7 +54,10 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_view_bobbing_anim(0), m_view_bobbing_state(0), - m_view_bobbing_speed(0) + m_view_bobbing_speed(0), + + m_digging_anim(0), + m_digging_speed(0) { //dstream<<__FUNCTION_NAME<addEmptySceneNode(m_playernode); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode->bindTargetAndRotation(true); - m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1, v3f(0, 120, 10), v3f(0, 0, 0), v3f(100, 100, 100)); - //m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1); + m_wieldnode = new ExtrudedSpriteSceneNode(m_headnode, smgr, -1, v3f(1.3, -1, 2), v3f(-20, -100, 20), v3f(1)); updateSettings(); } @@ -356,9 +358,10 @@ void Camera::wield(const InventoryItem* item) // A block-type material MaterialItem* mat_item = (MaterialItem*) item; content_t content = mat_item->getMaterial(); - if (content_features(content).solidness) + if (content_features(content).solidness || content_features(content).visual_solidness) { m_wieldnode->setCube(content_features(content).tiles); + m_wieldnode->setScale(v3f(0.9)); isCube = true; } } @@ -367,6 +370,7 @@ void Camera::wield(const InventoryItem* item) if (!isCube) { m_wieldnode->setSprite(item->getImageRaw()); + m_wieldnode->setScale(v3f(1.2)); } m_wieldnode->setVisible(true); @@ -458,17 +462,9 @@ void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6]) for (int i = 0; i < 6; ++i) { // Get the tile texture and atlas transformation - u32 texture_id = tiles[i].texture.id; - video::ITexture* atlas = NULL; - v2f pos(0,0); - v2f size(1,1); - if (g_texturesource) - { - AtlasPointer ap = g_texturesource->getTexture(texture_id); - atlas = ap.atlas; - pos = ap.pos; - size = ap.size; - } + video::ITexture* atlas = tiles[i].texture.atlas; + v2f pos = tiles[i].texture.pos; + v2f size = tiles[i].texture.size; // Set material flags and texture video::SMaterial& material = m_meshnode->getMaterial(i); -- cgit v1.2.3 From eaff4616adadf991a2bde66b9e1f1ab693c94c6d Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Sep 2011 17:11:53 +0200 Subject: fix some normals --- src/camera.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index c5c40f5c5..7f5931bdd 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -748,10 +748,10 @@ scene::IMesh* ExtrudedSpriteSceneNode::createCubeMesh() video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0), video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0), // Back - video::S3DVertex(-0.5,-0.5,+0.5, 0,0,-1, c, 1,1), - video::S3DVertex(+0.5,-0.5,+0.5, 0,0,-1, c, 0,1), - video::S3DVertex(+0.5,+0.5,+0.5, 0,0,-1, c, 0,0), - video::S3DVertex(-0.5,+0.5,+0.5, 0,0,-1, c, 1,0), + video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1), + video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1), + video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0), + video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0), // Front video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0), -- cgit v1.2.3 From 01f3ae1c5089f36f1f2a164bcaa36fb2fc8642be Mon Sep 17 00:00:00 2001 From: Kahrl Date: Tue, 20 Sep 2011 11:06:16 +0200 Subject: Digging animation --- src/camera.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 23 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 7f5931bdd..a1830fcfc 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -26,13 +26,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include -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_wieldnode(NULL), m_draw_control(draw_control), m_viewing_range_min(5.0), m_viewing_range_max(5.0), @@ -57,7 +56,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_view_bobbing_speed(0), m_digging_anim(0), - m_digging_speed(0) + m_digging_button(-1) { //dstream<<__FUNCTION_NAME<addEmptySceneNode(m_playernode); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode->bindTargetAndRotation(true); - m_wieldnode = new ExtrudedSpriteSceneNode(m_headnode, smgr, -1, v3f(1.3, -1, 2), v3f(-20, -100, 20), v3f(1)); + m_wieldnode = new ExtrudedSpriteSceneNode(m_headnode, smgr); updateSettings(); } @@ -93,24 +92,54 @@ bool Camera::successfullyCreated(std::wstring& error_message) error_message = L"Failed to create the camera scene node"; return false; } + if (m_wieldnode == NULL) + { + error_message = L"Failed to create the wielded item scene node"; + return false; + } return true; } +// Returns the fractional part of x +inline f32 my_modf(f32 x) +{ + double dummy; + return modf(x, &dummy); +} + void Camera::step(f32 dtime) { if (m_view_bobbing_state != 0) { - s32 offset = MYMAX(dtime * m_view_bobbing_speed * 0.035 * BOBFRAMES, 1); + f32 offset = dtime * m_view_bobbing_speed * 0.035; if (m_view_bobbing_state == 2) { // Animation is getting turned off - s32 subanim = (m_view_bobbing_anim & (BOBFRAMES/2-1)); - if (subanim < BOBFRAMES/4) - offset = -1 * MYMIN(offset, subanim); + if (m_view_bobbing_anim < 0.5) + m_view_bobbing_anim -= offset; else - offset = MYMIN(offset, BOBFRAMES/2 - subanim); + m_view_bobbing_anim += offset; + if (m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1) + { + m_view_bobbing_anim = 0; + m_view_bobbing_state = 0; + } + } + else + { + m_view_bobbing_anim = my_modf(m_view_bobbing_anim + offset); + } + } + + if (m_digging_button != -1) + { + f32 offset = dtime * 3.5; + m_digging_anim += offset; + if (m_digging_anim >= 1) + { + m_digging_anim = 0; + m_digging_button = -1; } - m_view_bobbing_anim = (m_view_bobbing_anim + offset) & (BOBFRAMES-1); } } @@ -132,11 +161,10 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) v3f rel_cam_target = v3f(0,0,1); v3f rel_cam_up = v3f(0,1,0); - s32 bobframe = m_view_bobbing_anim & (BOBFRAMES/2-1); - if (bobframe != 0) + if (m_view_bobbing_anim != 0) { - f32 bobfrac = (f32) bobframe / (BOBFRAMES/2); - f32 bobdir = (m_view_bobbing_anim < (BOBFRAMES/2)) ? 1.0 : -1.0; + f32 bobfrac = my_modf(m_view_bobbing_anim * 2); + f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0; #if 1 f32 bobknob = 1.2; @@ -188,6 +216,27 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) // Some more allowance that m_viewing_range_max * BS because of active objects etc. m_cameranode->setFarValue(m_viewing_range_max * BS * 10); + // Position the wielded item + v3f wield_position = v3f(1.3, -1.1, 2); + v3f wield_rotation = v3f(90, -90, -90); + if (m_digging_button != -1) + { + f32 digfrac = m_digging_anim; + wield_position.X -= sin(pow(digfrac, 0.8) * PI); + wield_position.Y += 0.5 * sin(digfrac * 2 * PI); + wield_position.Z += 0.2 * digfrac; + + // Euler angles are PURE EVIL, so why not use quaternions? + core::quaternion quat_begin(wield_rotation * core::DEGTORAD); + core::quaternion quat_end(v3f(90, 20, -130) * core::DEGTORAD); + core::quaternion quat_slerp; + quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * PI)); + quat_slerp.toEuler(wield_rotation); + wield_rotation *= core::RADTODEG; + } + m_wieldnode->setPosition(wield_position); + m_wieldnode->setRotation(wield_rotation); + // Render distance feedback loop updateViewingRange(frametime); @@ -208,12 +257,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) { // Stop animation m_view_bobbing_state = 2; - m_view_bobbing_speed = 100; - } - else if (m_view_bobbing_state == 2 && bobframe == 0) - { - // Stop animation completed - m_view_bobbing_state = 0; + m_view_bobbing_speed = 60; } } @@ -378,14 +422,14 @@ void Camera::wield(const InventoryItem* item) else { // Bare hands - dstream << "bare hands" << std::endl; m_wieldnode->setVisible(false); } } -void Camera::setDigging(bool digging) +void Camera::setDigging(s32 button) { - // TODO + if (m_digging_button == -1) + m_digging_button = button; } -- cgit v1.2.3 From cbd2bcf102bd338ba1d97ad54bd257913f4dcd36 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Tue, 20 Sep 2011 18:19:26 +0200 Subject: Fix jittery view bobbing at large map coordinates again. Wielded tool still has problems there --- src/camera.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index a1830fcfc..316a3f70a 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -195,17 +195,16 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) // Compute absolute camera position and target m_headnode->getAbsoluteTransformation().transformVect(m_camera_position, rel_cam_pos); - m_headnode->getAbsoluteTransformation().transformVect(m_camera_direction, rel_cam_target); - m_camera_direction -= m_camera_position; + m_headnode->getAbsoluteTransformation().rotateVect(m_camera_direction, rel_cam_target - rel_cam_pos); v3f abs_cam_up; - m_headnode->getAbsoluteTransformation().transformVect(abs_cam_up, rel_cam_pos + rel_cam_up); - abs_cam_up -= m_camera_position; + m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up); // Set camera node transformation m_cameranode->setPosition(m_camera_position); m_cameranode->setUpVector(abs_cam_up); - m_cameranode->setTarget(m_camera_position + m_camera_direction); + // *100.0 helps in large map coordinates + m_cameranode->setTarget(m_camera_position + 100 * m_camera_direction); // FOV and and aspect ratio m_aspect = (f32)screensize.X / (f32) screensize.Y; -- cgit v1.2.3 From 6599002149f58c03b807cd1378ec17278dbdc09d Mon Sep 17 00:00:00 2001 From: Kahrl Date: Tue, 20 Sep 2011 18:25:29 +0200 Subject: fix a numerical problem, but tool is still jittery --- src/camera.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 316a3f70a..4b0f968a4 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -151,8 +151,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) m_playernode->updateAbsolutePosition(); // Set head node transformation - v3f eye_offset = player->getEyePosition() - player->getPosition(); - m_headnode->setPosition(eye_offset); + m_headnode->setPosition(player->getEyeOffset()); m_headnode->setRotation(v3f(player->getPitch(), 0, 0)); m_headnode->updateAbsolutePosition(); -- cgit v1.2.3 From 36af9bb027ed6846227282587e3414ea3d30f6c5 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Wed, 21 Sep 2011 01:42:52 +0200 Subject: Create a separate scene manager for the wielded tool. This fixes the glitchyness in large map coordinates and some depth buffer problems. (The tool doesn't bob anymore when walking, this will be fixed later.) Fix MSVC build (thanks to dannydark). --- src/camera.cpp | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 4b0f968a4..56028da40 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -31,7 +31,10 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_playernode(NULL), m_headnode(NULL), m_cameranode(NULL), + + m_wieldmgr(NULL), m_wieldnode(NULL), + m_draw_control(draw_control), m_viewing_range_min(5.0), m_viewing_range_max(5.0), @@ -66,13 +69,20 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_headnode = smgr->addEmptySceneNode(m_playernode); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode->bindTargetAndRotation(true); - m_wieldnode = new ExtrudedSpriteSceneNode(m_headnode, smgr); + + // This needs to be in its own scene manager. It is drawn after + // all other 3D scene nodes and before the GUI. + m_wieldmgr = smgr->createNewSceneManager(); + m_wieldmgr->addCameraSceneNode(); + m_wieldnode = new ExtrudedSpriteSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr); updateSettings(); } Camera::~Camera() { + m_wieldmgr->drop(); + m_wieldnode->drop(); } bool Camera::successfullyCreated(std::wstring& error_message) @@ -92,6 +102,11 @@ bool Camera::successfullyCreated(std::wstring& error_message) error_message = L"Failed to create the camera scene node"; return false; } + if (m_wieldmgr == NULL) + { + error_message = L"Failed to create the wielded item scene manager"; + return false; + } if (m_wieldnode == NULL) { error_message = L"Failed to create the wielded item scene node"; @@ -215,14 +230,14 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) m_cameranode->setFarValue(m_viewing_range_max * BS * 10); // Position the wielded item - v3f wield_position = v3f(1.3, -1.1, 2); + v3f wield_position = v3f(45, -35, 65); v3f wield_rotation = v3f(90, -90, -90); if (m_digging_button != -1) { f32 digfrac = m_digging_anim; - wield_position.X -= sin(pow(digfrac, 0.8) * PI); - wield_position.Y += 0.5 * sin(digfrac * 2 * PI); - wield_position.Z += 0.2 * digfrac; + wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * PI); + wield_position.Y += 15 * sin(digfrac * 2 * PI); + wield_position.Z += 5 * digfrac; // Euler angles are PURE EVIL, so why not use quaternions? core::quaternion quat_begin(wield_rotation * core::DEGTORAD); @@ -403,7 +418,7 @@ void Camera::wield(const InventoryItem* item) if (content_features(content).solidness || content_features(content).visual_solidness) { m_wieldnode->setCube(content_features(content).tiles); - m_wieldnode->setScale(v3f(0.9)); + m_wieldnode->setScale(v3f(30)); isCube = true; } } @@ -412,7 +427,7 @@ void Camera::wield(const InventoryItem* item) if (!isCube) { m_wieldnode->setSprite(item->getImageRaw()); - m_wieldnode->setScale(v3f(1.2)); + m_wieldnode->setScale(v3f(40)); } m_wieldnode->setVisible(true); @@ -430,6 +445,18 @@ void Camera::setDigging(s32 button) m_digging_button = button; } +void Camera::drawWieldedTool() +{ + m_wieldmgr->getVideoDriver()->clearZBuffer(); + + scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera(); + cam->setAspectRatio(m_cameranode->getAspectRatio()); + cam->setFOV(m_cameranode->getFOV()); + cam->setNearValue(0.1); + cam->setFarValue(100); + m_wieldmgr->drawAll(); +} + ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode( scene::ISceneNode* parent, -- cgit v1.2.3 From a4a2c348318139ae9605cf0d7477fe93e8aa2651 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Wed, 21 Sep 2011 15:54:06 +0200 Subject: reduce view bobbing slightly --- src/camera.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index 56028da40..c14d0e8bf 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -189,9 +189,9 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) 0.8 * bobtmp * bobtmp, 0.); - rel_cam_pos += 0.03 * bobvec; - rel_cam_target += 0.045 * bobvec; - rel_cam_up.rotateXYBy(0.03 * bobdir * bobtmp * PI); + rel_cam_pos += 0.02 * bobvec; + rel_cam_target += 0.03 * bobvec; + rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * PI); #else f32 angle_deg = 1 * bobdir * sin(bobfrac * PI); f32 angle_rad = angle_deg * PI / 180; -- cgit v1.2.3 From 3e012122d1607a6269af4e4522305d8b5efcd9d4 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Wed, 21 Sep 2011 18:37:29 +0200 Subject: Simplistic wielded tool lighting, added setMeshVerticesColor to utility.h and refactored some other code into calls of that --- src/camera.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index c14d0e8bf..a61532143 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -249,6 +249,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) } m_wieldnode->setPosition(wield_position); m_wieldnode->setRotation(wield_rotation); + m_wieldnode->updateLight(player->light); // Render distance feedback loop updateViewingRange(frametime); @@ -472,6 +473,7 @@ ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode( m_thickness = 0.1; m_cubemesh = NULL; m_is_cube = false; + m_light = LIGHT_MAX; } ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode() @@ -519,6 +521,7 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; m_meshnode->setVisible(true); m_is_cube = false; + updateLight(m_light); } void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6]) @@ -546,6 +549,16 @@ void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6]) } m_meshnode->setVisible(true); m_is_cube = true; + updateLight(m_light); +} + +void ExtrudedSpriteSceneNode::updateLight(u8 light) +{ + m_light = light; + + u8 li = decode_light(light); + video::SColor color(255,li,li,li); + setMeshVerticesColor(m_meshnode->getMesh(), color); } void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture) -- cgit v1.2.3 From 2ecd53ce09d8f20a06b057c24924a010fa2eefde Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 26 Sep 2011 15:09:04 +0300 Subject: Fix single-frame lag in camera yaw/pitch, tune view bobbing and add wielded tool movement when walking and tweak stuff a bit --- src/camera.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'src/camera.cpp') diff --git a/src/camera.cpp b/src/camera.cpp index a61532143..1a5330497 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -126,9 +126,11 @@ void Camera::step(f32 dtime) { if (m_view_bobbing_state != 0) { - f32 offset = dtime * m_view_bobbing_speed * 0.035; + //f32 offset = dtime * m_view_bobbing_speed * 0.035; + f32 offset = dtime * m_view_bobbing_speed * 0.030; if (m_view_bobbing_state == 2) { +#if 0 // Animation is getting turned off if (m_view_bobbing_anim < 0.5) m_view_bobbing_anim -= offset; @@ -139,6 +141,29 @@ void Camera::step(f32 dtime) m_view_bobbing_anim = 0; m_view_bobbing_state = 0; } +#endif +#if 1 + // Animation is getting turned off + if(m_view_bobbing_anim < 0.25){ + m_view_bobbing_anim -= offset; + } else if(m_view_bobbing_anim > 0.75){ + m_view_bobbing_anim += offset; + } if(m_view_bobbing_anim < 0.5){ + m_view_bobbing_anim += offset; + if(m_view_bobbing_anim > 0.5) + m_view_bobbing_anim = 0.5; + } else { + m_view_bobbing_anim -= offset; + if(m_view_bobbing_anim < 0.5) + m_view_bobbing_anim = 0.5; + } + if(m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1 || + fabs(m_view_bobbing_anim - 0.5) < 0.01) + { + m_view_bobbing_anim = 0; + m_view_bobbing_state = 0; + } +#endif } else { @@ -183,15 +208,24 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) #if 1 f32 bobknob = 1.2; f32 bobtmp = sin(pow(bobfrac, bobknob) * PI); + f32 bobtmp2 = cos(pow(bobfrac, bobknob) * PI); v3f bobvec = v3f( - bobdir * sin(bobfrac * PI), - 0.8 * bobtmp * bobtmp, + 0.3 * bobdir * sin(bobfrac * PI), + -0.28 * bobtmp * bobtmp, 0.); - rel_cam_pos += 0.02 * bobvec; - rel_cam_target += 0.03 * bobvec; - rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * PI); + //rel_cam_pos += 0.2 * bobvec; + //rel_cam_target += 0.03 * bobvec; + //rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * PI); + float f = 1.0; + rel_cam_pos += bobvec * f; + //rel_cam_target += 0.995 * bobvec * f; + rel_cam_target += bobvec * f; + rel_cam_target.Z -= 0.005 * bobvec.Z * f; + //rel_cam_target.X -= 0.005 * bobvec.X * f; + //rel_cam_target.Y -= 0.005 * bobvec.Y * f; + rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * PI * f); #else f32 angle_deg = 1 * bobdir * sin(bobfrac * PI); f32 angle_rad = angle_deg * PI / 180; @@ -241,12 +275,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) // Euler angles are PURE EVIL, so why not use quaternions? core::quaternion quat_begin(wield_rotation * core::DEGTORAD); - core::quaternion quat_end(v3f(90, 20, -130) * core::DEGTORAD); + core::quaternion quat_end(v3f(90, -10, -130) * core::DEGTORAD); core::quaternion quat_slerp; quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * PI)); quat_slerp.toEuler(wield_rotation); wield_rotation *= core::RADTODEG; } + else { + f32 bobfrac = my_modf(m_view_bobbing_anim); + wield_position.X -= sin(bobfrac*PI*2.0) * 3.0; + wield_position.Y += sin(my_modf(bobfrac*2.0)*PI) * 3.0; + } m_wieldnode->setPosition(wield_position); m_wieldnode->setRotation(wield_rotation); m_wieldnode->updateLight(player->light); @@ -557,6 +596,8 @@ void ExtrudedSpriteSceneNode::updateLight(u8 light) m_light = light; u8 li = decode_light(light); + // Set brightness one lower than incoming light + diminish_light(li); video::SColor color(255,li,li,li); setMeshVerticesColor(m_meshnode->getMesh(), color); } -- cgit v1.2.3