From f31b0a3361c0c39b9f6f6ee440b93293690bbe02 Mon Sep 17 00:00:00 2001 From: JacobF Date: Wed, 7 Sep 2011 10:56:04 -0400 Subject: Display which tool the player is holding And some simple animation when trying to dig... --- src/client.cpp | 8 ++++++++ src/client.h | 1 + src/game.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/inventory.h | 57 +++++++++++++++++++++++++++++++++++------------------- src/player.cpp | 19 ++++++++++++++++++ src/player.h | 4 ++++ 6 files changed, 128 insertions(+), 21 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index a5ed6f61b..d491f9d36 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2008,6 +2008,14 @@ v3f Client::getPlayerPosition(v3f *eye_position) return player->getPosition(); } +void Client::setPlayerWield(scene::ISceneNode *wield) +{ + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + player->wield = wield; +} + void Client::setPlayerControl(PlayerControl &control) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index 1a7ef924a..398a3b849 100644 --- a/src/client.h +++ b/src/client.h @@ -210,6 +210,7 @@ public: // eye position in *eye_position v3f getPlayerPosition(v3f *eye_position=NULL); + void setPlayerWield(scene::ISceneNode *wield); void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); diff --git a/src/game.cpp b/src/game.cpp index dc3ed2456..86f1939c3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -956,7 +956,10 @@ void the_game( v3f(BS*100, BS*2, BS*100), // Look from v3f(BS*100+1, BS*2, BS*100), // Look to -1 // Camera ID - ); + ); + + // Do this so children rotate accordingly (tool) + camera->bindTargetAndRotation(true); if(camera == NULL) { @@ -972,6 +975,44 @@ void the_game( f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" + /* + Tool + */ + + v3f tool_wield_position(0.6, -0.6, 1.0); + v3f tool_wield_rotation(-25, 180, -25); + float tool_wield_animation = 0.0; + scene::IMeshSceneNode *tool_wield; + { + scene::SMesh *mesh = new scene::SMesh(); + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + video::S3DVertex vertices[4] = + { + video::S3DVertex(-0.5,0,0, 0,0,0, c, 0,1), + video::S3DVertex(0.5,0,0, 0,0,0, c, 1,1), + video::S3DVertex(0.5,0.5,0, 0,0,0, c, 1,0), + video::S3DVertex(-0.5,0.5,0, 0,0,0, c, 0,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + + tool_wield = smgr->addMeshSceneNode(mesh, camera); + mesh->drop(); + } + tool_wield->setVisible(false); + tool_wield->setPosition(tool_wield_position); + tool_wield->setRotation(tool_wield_rotation); + + client.setPlayerWield(tool_wield); + /* Clouds */ @@ -1920,6 +1961,7 @@ void the_game( } } + if(input->getRightClicked()) { std::cout<getLeftState()) + // Tool animation loops 0.0 - 1.0 + tool_wield_animation = fmod(tool_wield_animation + dtime * 3.0, 1.0); + else + // Return tool to holding position if not digging + tool_wield_animation /= 1.5; + } // selected_object == NULL input->resetLeftClicked(); @@ -2103,6 +2153,14 @@ void the_game( ); } + /* + Animate tool + */ + { + tool_wield->setRotation(tool_wield_rotation - sin(tool_wield_animation * PI) * 40.0); + tool_wield->setPosition(tool_wield_position - sin(tool_wield_animation * PI) / 3.0); + } + /* Update gui stuff (0ms) diff --git a/src/inventory.h b/src/inventory.h index 44ba6a5ad..f70d69b6d 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -53,6 +53,10 @@ public: // Shall make an exact clone of the item virtual InventoryItem* clone() = 0; #ifndef SERVER + // Return the name of the image for this item + virtual std::string getBasename() { return ""; } + // Shall return an image of the item (or NULL) + virtual video::ITexture * getImageRaw() { return NULL; } // Shall return an image to show in the GUI (or NULL) virtual video::ITexture * getImage() { return NULL; } #endif @@ -353,40 +357,53 @@ public: return new ToolItem(m_toolname, m_wear); } #ifndef SERVER - video::ITexture * getImage() - { - if(g_texturesource == NULL) - return NULL; - - std::string basename; + std::string getBasename() { if(m_toolname == "WPick") - basename = "tool_woodpick.png"; + return "tool_woodpick.png"; else if(m_toolname == "STPick") - basename = "tool_stonepick.png"; + return "tool_stonepick.png"; else if(m_toolname == "SteelPick") - basename = "tool_steelpick.png"; + return "tool_steelpick.png"; else if(m_toolname == "MesePick") - basename = "tool_mesepick.png"; + return "tool_mesepick.png"; else if(m_toolname == "WShovel") - basename = "tool_woodshovel.png"; + return "tool_woodshovel.png"; else if(m_toolname == "STShovel") - basename = "tool_stoneshovel.png"; + return "tool_stoneshovel.png"; else if(m_toolname == "SteelShovel") - basename = "tool_steelshovel.png"; + return "tool_steelshovel.png"; else if(m_toolname == "WAxe") - basename = "tool_woodaxe.png"; + return "tool_woodaxe.png"; else if(m_toolname == "STAxe") - basename = "tool_stoneaxe.png"; + return "tool_stoneaxe.png"; else if(m_toolname == "SteelAxe") - basename = "tool_steelaxe.png"; + return "tool_steelaxe.png"; else if(m_toolname == "WSword") - basename = "tool_woodsword.png"; + return "tool_woodsword.png"; else if(m_toolname == "STSword") - basename = "tool_stonesword.png"; + return "tool_stonesword.png"; else if(m_toolname == "SteelSword") - basename = "tool_steelsword.png"; + return "tool_steelsword.png"; else - basename = "cloud.png"; + return "cloud.png"; +} + + video::ITexture * getImageRaw() + { + if(g_texturesource == NULL) + return NULL; + + return g_texturesource->getTextureRaw(getBasename()); + } + + video::ITexture * getImage() + { + if(g_texturesource == NULL) + return NULL; + + std::string basename = getBasename(); + + return g_texturesource->getTextureRaw(basename); /* Calculate a progress value with sane amount of diff --git a/src/player.cpp b/src/player.cpp index 7cfdfebb6..03ae24f45 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -309,12 +309,31 @@ LocalPlayer::LocalPlayer(): // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points hp = 0; + + // No tool wielded initially + wield = NULL; } LocalPlayer::~LocalPlayer() { } +void LocalPlayer::wieldItem(u16 item) +{ + m_selected_item = item; + + if(wield) { + InventoryItem* i = inventory.getList("main")->getItem(m_selected_item); + + if(i && strcmp(i->getName(), "ToolItem") == 0) { + wield->getMaterial(0).setTexture(0, i->getImageRaw()); + wield->setVisible(true); + } + else + wield->setVisible(false); + } +} + void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info) { diff --git a/src/player.h b/src/player.h index 13cffa205..0f2c40011 100644 --- a/src/player.h +++ b/src/player.h @@ -356,6 +356,8 @@ public: { return true; } + + void wieldItem(u16 item); void move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info); @@ -365,6 +367,8 @@ public: PlayerControl control; + scene::ISceneNode *wield; + private: // This is used for determining the sneaking range v3s16 m_sneak_node; -- cgit v1.2.3 From c0b35fa429c68b49b2d6a5124aff6dcc31400b63 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Wed, 7 Sep 2011 19:21:28 +0200 Subject: Removed unused camera_position and camera_direction fields from Client. Moved ClientEnvironment::drawPostFx to ClientMap::renderPostFx -- this will make the camera management classes easier to write, as ClientMap already knows the camera position but ClientEnvironment doesn't and has to be told about it. This also eliminates the need for Client::getEnv(). Made the post effect color a content feature defined in content_mapnode.h. --- src/client.cpp | 14 ++++++++++---- src/client.h | 20 +++++--------------- src/content_mapnode.cpp | 4 ++++ src/environment.cpp | 23 ----------------------- src/environment.h | 3 --- src/game.cpp | 16 ++++++++-------- src/map.cpp | 29 +++++++++++++++++++++++++++++ src/map.h | 2 ++ src/mapnode.h | 3 +++ 9 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index a5ed6f61b..df792d116 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -189,8 +189,6 @@ Client::Client( ), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this), m_device(device), - camera_position(0,0,0), - camera_direction(0,0,1), m_server_ser_ver(SER_FMT_VER_INVALID), m_inventory_updated(false), m_time_of_day(0), @@ -1983,8 +1981,11 @@ void Client::addNode(v3s16 p, MapNode n) void Client::updateCamera(v3f pos, v3f dir) { m_env.getClientMap().updateCamera(pos, dir); - camera_position = pos; - camera_direction = dir; +} + +void Client::renderPostFx() +{ + m_env.getClientMap().renderPostFx(); } MapNode Client::getNode(v3s16 p) @@ -1998,6 +1999,11 @@ NodeMetadata* Client::getNodeMetadata(v3s16 p) return m_env.getMap().getNodeMetadata(p); } +LocalPlayer* Client::getLocalPlayer() +{ + return m_env.getLocalPlayer(); +} + v3f Client::getPlayerPosition(v3f *eye_position) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index 1a7ef924a..9c942ff9a 100644 --- a/src/client.h +++ b/src/client.h @@ -201,14 +201,16 @@ public: void updateCamera(v3f pos, v3f dir); + void renderPostFx(); + // Returns InvalidPositionException if not found MapNode getNode(v3s16 p); // Wrapper to Map NodeMetadata* getNodeMetadata(v3s16 p); - // Get the player position, and optionally put the - // eye position in *eye_position - v3f getPlayerPosition(v3f *eye_position=NULL); + LocalPlayer* getLocalPlayer(); + + v3f getPlayerPosition(v3f *eye_position); void setPlayerControl(PlayerControl &control); @@ -302,15 +304,6 @@ public: { return m_access_denied_reason; } - - /* - This should only be used for calling the special drawing stuff in - ClientEnvironment - */ - ClientEnvironment * getEnv() - { - return &m_env; - } private: @@ -342,9 +335,6 @@ private: IrrlichtDevice *m_device; - v3f camera_position; - v3f camera_direction; - // Server serialization version u8 m_server_ser_ver; diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 51f2f9736..89171755e 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -385,6 +385,7 @@ void content_mapnode_init() f->liquid_alternative_source = CONTENT_WATERSOURCE; f->liquid_viscosity = WATER_VISC; f->vertex_alpha = WATER_ALPHA; + f->post_effect_color = video::SColor(64, 100, 100, 200); if(f->special_material == NULL && g_texturesource) { // Flowing water material @@ -433,6 +434,7 @@ void content_mapnode_init() f->liquid_alternative_source = CONTENT_WATERSOURCE; f->liquid_viscosity = WATER_VISC; f->vertex_alpha = WATER_ALPHA; + f->post_effect_color = video::SColor(64, 100, 100, 200); if(f->special_material == NULL && g_texturesource) { // Flowing water material @@ -465,6 +467,7 @@ void content_mapnode_init() f->liquid_alternative_source = CONTENT_LAVASOURCE; f->liquid_viscosity = LAVA_VISC; f->damage_per_second = 4*2; + f->post_effect_color = video::SColor(192, 255, 64, 0); if(f->special_material == NULL && g_texturesource) { // Flowing lava material @@ -514,6 +517,7 @@ void content_mapnode_init() f->liquid_alternative_source = CONTENT_LAVASOURCE; f->liquid_viscosity = LAVA_VISC; f->damage_per_second = 4*2; + f->post_effect_color = video::SColor(192, 255, 64, 0); if(f->special_material == NULL && g_texturesource) { // Flowing lava material diff --git a/src/environment.cpp b/src/environment.cpp index 8103b7110..80f41f9fd 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1940,29 +1940,6 @@ ClientEnvEvent ClientEnvironment::getClientEvent() return m_client_event_queue.pop_front(); } -void ClientEnvironment::drawPostFx(video::IVideoDriver* driver, v3f camera_pos) -{ - /*LocalPlayer *player = getLocalPlayer(); - assert(player); - v3f pos_f = player->getPosition() + v3f(0,BS*1.625,0);*/ - v3f pos_f = camera_pos; - v3s16 p_nodes = floatToInt(pos_f, BS); - MapNode n = m_map->getNodeNoEx(p_nodes); - if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE) - { - v2u32 ss = driver->getScreenSize(); - core::rect rect(0,0, ss.X, ss.Y); - driver->draw2DRectangle(video::SColor(64, 100, 100, 200), rect); - } - else if(content_features(n).solidness == 2 && - g_settings.getBool("free_move") == false) - { - v2u32 ss = driver->getScreenSize(); - core::rect rect(0,0, ss.X, ss.Y); - driver->draw2DRectangle(video::SColor(255, 0, 0, 0), rect); - } -} - #endif // #ifndef SERVER diff --git a/src/environment.h b/src/environment.h index d9248d2ad..055e2b1f6 100644 --- a/src/environment.h +++ b/src/environment.h @@ -406,9 +406,6 @@ public: // Get event from queue. CEE_NONE is returned if queue is empty. ClientEnvEvent getClientEvent(); - - // Post effects - void drawPostFx(video::IVideoDriver* driver, v3f camera_pos); private: ClientMap *m_map; diff --git a/src/game.cpp b/src/game.cpp index dc3ed2456..afe1ce80f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2032,7 +2032,7 @@ void the_game( update_skybox(driver, smgr, skybox, brightness); /* - Update coulds + Update clouds */ if(clouds) { @@ -2313,6 +2313,13 @@ void the_game( driver->draw3DBox(*i, video::SColor(255,0,0,0)); } + /* + Post effects + */ + { + client.renderPostFx(); + } + /* Frametime log */ @@ -2352,13 +2359,6 @@ void the_game( // 0-1ms guienv->drawAll(); - /* - Environment post fx - */ - { - client.getEnv()->drawPostFx(driver, camera_position); - } - /* Draw hotbar */ diff --git a/src/map.cpp b/src/map.cpp index 7de79c75d..6f22498fe 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3925,6 +3925,35 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) <<", rendered "<getVideoDriver(); + v2u32 ss = driver->getScreenSize(); + core::rect rect(0,0, ss.X, ss.Y); + driver->draw2DRectangle(post_effect_color, rect); + } +} + bool ClientMap::setTempMod(v3s16 p, NodeMod mod, core::map *affected_blocks) { diff --git a/src/map.h b/src/map.h index e0b67eb6e..5bea4a137 100644 --- a/src/map.h +++ b/src/map.h @@ -552,6 +552,8 @@ public: void renderMap(video::IVideoDriver* driver, s32 pass); + void renderPostFx(); + /* Methods for setting temporary modifications to nodes for drawing. diff --git a/src/mapnode.h b/src/mapnode.h index 3ad67aaf6..19dfb2802 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -160,6 +160,8 @@ struct ContentFeatures u8 liquid_viscosity; // Used currently for flowing liquids u8 vertex_alpha; + // Post effect color, drawn when the camera is inside the node. + video::SColor post_effect_color; // Special irrlicht material, used sometimes video::SMaterial *special_material; AtlasPointer *special_atlas; @@ -197,6 +199,7 @@ struct ContentFeatures liquid_alternative_source = CONTENT_IGNORE; liquid_viscosity = 0; vertex_alpha = 255; + post_effect_color = video::SColor(0, 0, 0, 0); special_material = NULL; special_atlas = NULL; light_source = 0; -- cgit v1.2.3 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/CMakeLists.txt | 1 + src/camera.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ src/camera.h | 141 ++++++++++++++++++++++++++++ src/client.cpp | 14 +-- src/client.h | 4 +- src/constants.h | 3 - src/defaultsettings.cpp | 2 + src/game.cpp | 205 +++++----------------------------------- src/map.cpp | 7 +- src/map.h | 4 +- src/server.cpp | 2 +- src/utility.cpp | 7 +- src/utility.h | 4 +- 13 files changed, 428 insertions(+), 209 deletions(-) create mode 100644 src/camera.cpp create mode 100644 src/camera.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c3b0960a..80ee0fc64 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,6 +142,7 @@ set(minetest_SRCS mapblock_mesh.cpp farmesh.cpp keycode.cpp + camera.cpp clouds.cpp clientobject.cpp guiMainMenu.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 "< + +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. +*/ + +#ifndef CAMERA_HEADER +#define CAMERA_HEADER + +#include "common_irrlicht.h" +#include "utility.h" + +class LocalPlayer; +class MapDrawControl; + +/* + Client camera class, manages the player and camera scene nodes, the viewing distance + and performs view bobbing etc. +*/ +class Camera +{ +public: + Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control); + ~Camera(); + + // Get player scene node. + // This node is positioned at the player's torso (without any view bobbing), + // as given by Player::m_position, Player::m_pitch and Player::m_yaw. + // Things like wielded tools should be positioned relative to this node. + inline scene::ISceneNode* getPlayerNode() const + { + return m_playernode; + } + + // Get camera scene node. + // The camera node is a child of the player node. + // It has the eye transformation and view bobbing applied. + inline scene::ICameraSceneNode* getCameraNode() const + { + return m_cameranode; + } + + // Get the camera position (in absolute scene coordinates). + // This has view bobbing applied. + inline v3f getPosition() const + { + return m_camera_position; + } + + // Get the camera direction (in absolute camera coordinates). + // This has view bobbing applied. + inline v3f getDirection() const + { + return m_camera_direction; + } + + // Horizontal field of view + inline f32 getFovX() const + { + return m_fov_x; + } + + // Vertical field of view + inline f32 getFovY() const + { + return m_fov_y; + } + + // Get maximum of getFovX() and getFovY() + inline f32 getFovMax() const + { + return MYMAX(m_fov_x, m_fov_y); + } + + // Step the camera: updates the viewing range and view bobbing. + void step(f32 dtime); + + // Update the camera from the local player's position. + // frametime is used to adjust the viewing range. + void update(LocalPlayer* player, f32 frametime, v2u32 screensize); + + // Render distance feedback loop + void updateViewingRange(f32 frametime_in); + + // Update settings from g_settings + void updateSettings(); + +private: + // Scene manager and nodes + scene::ISceneManager* m_smgr; + scene::ISceneNode* m_playernode; + scene::ICameraSceneNode* m_cameranode; + + // draw control + MapDrawControl& m_draw_control; + + // viewing_range_min_nodes setting + f32 m_viewing_range_min; + // viewing_range_max_nodes setting + f32 m_viewing_range_max; + + // Absolute camera position + v3f m_camera_position; + // Absolute camera direction + v3f m_camera_direction; + + // Field of view and aspect ratio stuff + f32 m_aspect; + f32 m_fov_x; + f32 m_fov_y; + + // Stuff for viewing range calculations + f32 m_wanted_frametime; + f32 m_added_frametime; + s16 m_added_frames; + f32 m_range_old; + f32 m_frametime_old; + f32 m_frametime_counter; + f32 m_time_per_range; + + // View bobbing animation frame (0 <= m_view_bobbing < 0x10000) + u32 m_view_bobbing_anim; + // Number of frames to continue the view bobbing animation. + u32 m_view_bobbing_anim_left; +}; + +#endif + diff --git a/src/client.cpp b/src/client.cpp index df792d116..81dedd144 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1978,9 +1978,9 @@ void Client::addNode(v3s16 p, MapNode n) } } -void Client::updateCamera(v3f pos, v3f dir) +void Client::updateCamera(v3f pos, v3f dir, f32 fov) { - m_env.getClientMap().updateCamera(pos, dir); + m_env.getClientMap().updateCamera(pos, dir, fov); } void Client::renderPostFx() @@ -2004,16 +2004,6 @@ LocalPlayer* Client::getLocalPlayer() return m_env.getLocalPlayer(); } -v3f Client::getPlayerPosition(v3f *eye_position) -{ - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - LocalPlayer *player = m_env.getLocalPlayer(); - assert(player != NULL); - if (eye_position) - *eye_position = player->getEyePosition(); - return player->getPosition(); -} - void Client::setPlayerControl(PlayerControl &control) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index 9c942ff9a..930987c02 100644 --- a/src/client.h +++ b/src/client.h @@ -199,7 +199,7 @@ public: // locks envlock void addNode(v3s16 p, MapNode n); - void updateCamera(v3f pos, v3f dir); + void updateCamera(v3f pos, v3f dir, f32 fov); void renderPostFx(); @@ -210,8 +210,6 @@ public: LocalPlayer* getLocalPlayer(); - v3f getPlayerPosition(v3f *eye_position); - void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); diff --git a/src/constants.h b/src/constants.h index 1af5f1f1b..9ba10b51c 100644 --- a/src/constants.h +++ b/src/constants.h @@ -44,9 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PI 3.14159 -// This is the same as in minecraft and everything else -#define FOV_ANGLE (PI/2.5) - // The absolute working limit is (2^15 - viewing_range). // I really don't want to make every algorithm to check if it's // going near the limit or not, so this is lower. diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 1e17f2f3a..163ed0884 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -59,6 +59,8 @@ void set_default_settings() g_settings.setDefault("random_input", "false"); g_settings.setDefault("client_unload_unused_data_timeout", "600"); g_settings.setDefault("enable_fog", "true"); + g_settings.setDefault("fov", "72"); + g_settings.setDefault("view_bobbing", "true"); g_settings.setDefault("new_style_water", "false"); g_settings.setDefault("new_style_leaves", "true"); g_settings.setDefault("smooth_lighting", "true"); diff --git a/src/game.cpp b/src/game.cpp index afe1ce80f..fc1486b73 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "materials.h" #include "config.h" #include "clouds.h" +#include "camera.h" #include "farmesh.h" #include "mapblock.h" @@ -49,8 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define FIELD_OF_VIEW_TEST 0 -MapDrawControl draw_control; - // Chat data struct ChatLine { @@ -143,144 +142,6 @@ struct TextDestSignNode : public TextDest Client *m_client; }; -/* - Render distance feedback loop -*/ -void updateViewingRange(f32 frametime_in, Client *client) -{ - if(draw_control.range_all == true) - return; - - static f32 added_frametime = 0; - static s16 added_frames = 0; - - added_frametime += frametime_in; - added_frames += 1; - - // Actually this counter kind of sucks because frametime is busytime - static f32 counter = 0; - counter -= frametime_in; - if(counter > 0) - return; - //counter = 0.1; - counter = 0.2; - - /*dstream<<__FUNCTION_NAME - <<": Collected "< range_max) - new_range = range_max; - - /*dstream<<"new_range="<addCameraSceneNode( - 0, // Camera parent - v3f(BS*100, BS*2, BS*100), // Look from - v3f(BS*100+1, BS*2, BS*100), // Look to - -1 // Camera ID - ); - - if(camera == NULL) + Camera camera(smgr, draw_control); + if (camera.getPlayerNode() == NULL) + { + error_message = L"Failed to create the player node"; + return; + } + if (camera.getCameraNode() == NULL) { error_message = L"Failed to create the camera node"; return; } - camera->setFOV(FOV_ANGLE); - - // Just so big a value that everything rendered is visible - camera->setFarValue(100000*BS); - f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" @@ -1168,12 +1023,6 @@ void the_game( // Necessary for device->getTimer()->getTime() device->run(); - /* - Viewing range - */ - - updateViewingRange(busytime, &client); - /* FPS limiter */ @@ -1565,10 +1414,6 @@ void the_game( } } - // Get player position - v3f camera_position; - v3f player_position = client.getPlayerPosition(&camera_position); - //TimeTaker //timer2("//timer2"); /* @@ -1621,25 +1466,25 @@ void the_game( first_loop_after_window_activation = true; } - camera_yaw = wrapDegrees(camera_yaw); - camera_pitch = wrapDegrees(camera_pitch); - - v3f camera_direction = v3f(0,0,1); - camera_direction.rotateYZBy(camera_pitch); - camera_direction.rotateXZBy(camera_yaw); + LocalPlayer* player = client.getLocalPlayer(); + camera.update(player, busytime, screensize); + camera.step(dtime); - camera->setPosition(camera_position); - // *100.0 helps in large map coordinates - camera->setTarget(camera_position + camera_direction * 100.0); + v3f player_position = player->getPosition(); + v3f camera_position = camera.getPosition(); + v3f camera_direction = camera.getDirection(); + f32 camera_fov = camera.getFovMax(); - if(FIELD_OF_VIEW_TEST){ - client.updateCamera(v3f(0,0,0), v3f(0,0,1)); + if(FIELD_OF_VIEW_TEST) + { + client.updateCamera(v3f(0,0,0), v3f(0,0,1), M_PI); } - else{ - //TimeTaker timer("client.updateCamera"); - client.updateCamera(camera_position, camera_direction); + else + { + client.updateCamera(camera_position, + camera_direction, camera_fov); } - + //timer2.stop(); //TimeTaker //timer3("//timer3"); @@ -2010,8 +1855,6 @@ void the_game( Calculate stuff for drawing */ - camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y); - u32 daynight_ratio = client.getDayNightRatio(); u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000); video::SColor bgcolor = video::SColor( diff --git a/src/map.cpp b/src/map.cpp index 6f22498fe..b1908fe2e 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3604,7 +3604,8 @@ ClientMap::ClientMap( m_client(client), m_control(control), m_camera_position(0,0,0), - m_camera_direction(0,0,1) + m_camera_direction(0,0,1), + m_camera_fov(M_PI) { m_camera_mutex.Init(); assert(m_camera_mutex.IsInitialized()); @@ -3713,6 +3714,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) m_camera_mutex.Lock(); v3f camera_position = m_camera_position; v3f camera_direction = m_camera_direction; + f32 camera_fov = m_camera_fov; m_camera_mutex.Unlock(); /* @@ -3805,7 +3807,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) float d = 0.0; if(isBlockInSight(block->getPos(), camera_position, - camera_direction, range, &d) == false) + camera_direction, camera_fov, + range, &d) == false) { continue; } diff --git a/src/map.h b/src/map.h index 5bea4a137..cb649addd 100644 --- a/src/map.h +++ b/src/map.h @@ -518,11 +518,12 @@ public: ISceneNode::drop(); } - void updateCamera(v3f pos, v3f dir) + void updateCamera(v3f pos, v3f dir, f32 fov) { JMutexAutoLock lock(m_camera_mutex); m_camera_position = pos; m_camera_direction = dir; + m_camera_fov = fov; } /* @@ -603,6 +604,7 @@ private: v3f m_camera_position; v3f m_camera_direction; + f32 m_camera_fov; JMutex m_camera_mutex; core::map m_last_drawn_sectors; diff --git a/src/server.cpp b/src/server.cpp index 14d8942cb..fd93d7523 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -584,7 +584,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Don't generate or send if not in sight */ - if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false) + if(isBlockInSight(p, camera_pos, camera_dir, M_PI, 10000*BS) == false) { continue; } diff --git a/src/utility.cpp b/src/utility.cpp index 0721100cb..9c1edc8a9 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -162,8 +162,8 @@ void mysrand(unsigned seed) camera_dir: an unit vector pointing to camera direction range: viewing range */ -bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, - f32 *distance_ptr) +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr) { v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; @@ -211,8 +211,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, cosangle += block_max_radius / dforward; // If block is not in the field of view, skip it - //if(cosangle < cos(FOV_ANGLE/2)) - if(cosangle < cos(FOV_ANGLE/2. * 4./3.)) + if(cosangle < cos(camera_fov / 2)) return false; } diff --git a/src/utility.h b/src/utility.h index ea7c11846..d331bafbb 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1765,8 +1765,8 @@ inline int myrand_range(int min, int max) Miscellaneous functions */ -bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, - f32 *distance_ptr=NULL); +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr=NULL); /* Queue with unique values with fast checking of value existence -- cgit v1.2.3 From 18771a39cfdfcdd0bacca8f71ee5fd3fb78bbca6 Mon Sep 17 00:00:00 2001 From: Kahrl 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(-) 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 ++++++++++++++++++++++++++++++++++++++++++---------------- src/camera.h | 13 +++++---- src/game.cpp | 2 +- 3 files changed, 72 insertions(+), 30 deletions(-) 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; } } diff --git a/src/camera.h b/src/camera.h index 88f03e66d..500168f3d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -38,7 +38,7 @@ public: // Get player scene node. // This node is positioned at the player's torso (without any view bobbing), - // as given by Player::m_position, Player::m_pitch and Player::m_yaw. + // 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 { @@ -46,7 +46,6 @@ public: } // Get camera scene node. - // The camera node is a child of the player node. // It has the eye transformation and view bobbing applied. inline scene::ICameraSceneNode* getCameraNode() const { @@ -131,10 +130,12 @@ private: f32 m_frametime_counter; f32 m_time_per_range; - // View bobbing animation frame (0 <= m_view_bobbing < 0x10000) - u32 m_view_bobbing_anim; - // Number of frames to continue the view bobbing animation. - u32 m_view_bobbing_anim_left; + // View bobbing animation frame (0 <= m_view_bobbing < 0x1000000) + s32 m_view_bobbing_anim; + // If 0, view bobbing is off (e.g. player is standing). + // If 1, view bobbing is on (player is walking). + // If 2, view bobbing is getting switched off. + s32 m_view_bobbing_state; }; #endif diff --git a/src/game.cpp b/src/game.cpp index fc1486b73..24f356e46 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1477,7 +1477,7 @@ void the_game( if(FIELD_OF_VIEW_TEST) { - client.updateCamera(v3f(0,0,0), v3f(0,0,1), M_PI); + client.updateCamera(v3f(0,0,0), v3f(0,0,1), camera_fov); } else { -- 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(-) 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(-) 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 +++--- src/game.cpp | 9 +++++---- src/map.cpp | 2 +- src/server.cpp | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) 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); diff --git a/src/game.cpp b/src/game.cpp index af4886137..cb7594c30 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -831,7 +831,7 @@ void the_game( Tool */ - v3f tool_wield_position(0.06*BS, 1.619*BS, 0.1*BS); + v3f tool_wield_position(0.06*BS, -0.06*BS, 0.1*BS); v3f tool_wield_rotation(-25, 180, -25); float tool_wield_animation = 0.0; scene::IMeshSceneNode *tool_wield; @@ -856,7 +856,7 @@ void the_game( mesh->addMeshBuffer(buf); buf->drop(); - tool_wield = smgr->addMeshSceneNode(mesh, camera.getPlayerNode()); + tool_wield = smgr->addMeshSceneNode(mesh, camera.getCameraNode()); mesh->drop(); } tool_wield->setVisible(false); @@ -1997,8 +1997,9 @@ void the_game( Animate tool */ { - tool_wield->setRotation(tool_wield_rotation - sin(tool_wield_animation * PI) * 40.0); - tool_wield->setPosition(tool_wield_position - sin(tool_wield_animation * PI) / 3.0); + f32 tool_wield_sin = sin(tool_wield_animation * PI); + tool_wield->setRotation(tool_wield_rotation - tool_wield_sin * 40.0); + tool_wield->setPosition(tool_wield_position - tool_wield_sin * BS / 30.0); } diff --git a/src/map.cpp b/src/map.cpp index b1908fe2e..ecd12bddb 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3605,7 +3605,7 @@ ClientMap::ClientMap( m_control(control), m_camera_position(0,0,0), m_camera_direction(0,0,1), - m_camera_fov(M_PI) + m_camera_fov(PI) { m_camera_mutex.Init(); assert(m_camera_mutex.IsInitialized()); diff --git a/src/server.cpp b/src/server.cpp index fd93d7523..c89e4113b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -584,7 +584,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Don't generate or send if not in sight */ - if(isBlockInSight(p, camera_pos, camera_dir, M_PI, 10000*BS) == false) + if(isBlockInSight(p, camera_pos, camera_dir, PI, 10000*BS) == false) { continue; } -- cgit v1.2.3 From 524cf237b8ccbd233c57feb23a9e06f7ba8ff521 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 17:45:39 +0200 Subject: inventory displays tool breakage bar again --- src/inventory.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/inventory.h b/src/inventory.h index f70d69b6d..ef8c499b1 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -403,8 +403,6 @@ public: std::string basename = getBasename(); - return g_texturesource->getTextureRaw(basename); - /* Calculate a progress value with sane amount of maximum states -- 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 +++++++------ src/camera.h | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) 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) diff --git a/src/camera.h b/src/camera.h index 500168f3d..ba5d72bf4 100644 --- a/src/camera.h +++ b/src/camera.h @@ -136,6 +136,8 @@ private: // If 1, view bobbing is on (player is walking). // If 2, view bobbing is getting switched off. s32 m_view_bobbing_state; + // If true, view bobbing is slown down (player is swimming) + bool m_view_bobbing_slow; }; #endif -- 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 ++++++++++++++++++++++++++++----- 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); -- cgit v1.2.3 From acfb2bb8bced286626fa1fc04d56c9ba9ff82d48 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Fri, 16 Sep 2011 18:03:58 +0200 Subject: Revert some changes that could lead to slower map transfer and increaed network load. --- src/server.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index c89e4113b..46993913f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -582,9 +582,12 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, /* Don't generate or send if not in sight + FIXME This only works if the client uses a small enough + FOV setting. The default of 72 degrees is fine. */ - if(isBlockInSight(p, camera_pos, camera_dir, PI, 10000*BS) == false) + float camera_fov = (72.0*PI/180) * 4./3.; + if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false) { continue; } -- 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 ++++++++++++++++++++++++++++---------------------- src/camera.h | 4 ++-- 2 files changed, 30 insertions(+), 24 deletions(-) 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) diff --git a/src/camera.h b/src/camera.h index a6dd7476f..dd9f30551 100644 --- a/src/camera.h +++ b/src/camera.h @@ -147,8 +147,8 @@ private: // If 1, view bobbing is on (player is walking). // If 2, view bobbing is getting switched off. s32 m_view_bobbing_state; - // If true, view bobbing is slown down (player is swimming) - bool m_view_bobbing_slow; + // Speed of view bobbing animation + f32 m_view_bobbing_speed; }; #endif -- 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(-) 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(-) 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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/camera.h | 66 ++++++++++- src/client.cpp | 8 -- src/client.h | 1 - src/game.cpp | 70 ++---------- src/inventory.h | 11 -- src/player.cpp | 19 --- src/player.h | 4 - 8 files changed, 425 insertions(+), 103 deletions(-) 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; +} + diff --git a/src/camera.h b/src/camera.h index dd9f30551..08c03dd19 100644 --- a/src/camera.h +++ b/src/camera.h @@ -21,14 +21,17 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAMERA_HEADER #include "common_irrlicht.h" +#include "inventory.h" #include "utility.h" class LocalPlayer; class MapDrawControl; +class ExtrudedSpriteSceneNode; /* Client camera class, manages the player and camera scene nodes, the viewing distance - and performs view bobbing etc. + and performs view bobbing etc. It also displays the wielded tool in front of the + first-person camera. */ class Camera { @@ -59,6 +62,12 @@ public: return m_cameranode; } + // Get wielded item scene node. + inline ExtrudedSpriteSceneNode* getWieldNode() const + { + return m_wieldnode; + } + // Get the camera position (in absolute scene coordinates). // This has view bobbing applied. inline v3f getPosition() const @@ -107,12 +116,19 @@ public: // Update settings from g_settings void updateSettings(); + // Replace the wielded item mesh + void wield(InventoryItem* item); + + // Start or stop digging animation + void setDigging(bool digging); + private: // Scene manager and nodes scene::ISceneManager* m_smgr; scene::ISceneNode* m_playernode; scene::ISceneNode* m_headnode; scene::ICameraSceneNode* m_cameranode; + ExtrudedSpriteSceneNode* m_wieldnode; // draw control MapDrawControl& m_draw_control; @@ -151,5 +167,51 @@ private: f32 m_view_bobbing_speed; }; -#endif +/* + A scene node that displays a 2D mesh extruded into the third dimension, + to add an illusion of depth. + + Since this class was created to display the wielded tool of the local + player, and only tools and items are rendered like this (but not solid + content like stone and mud, which are shown as cubes), the option to + draw a textured cube instead is provided. + */ +class ExtrudedSpriteSceneNode: public scene::ISceneNode +{ +public: + ExtrudedSpriteSceneNode( + scene::ISceneNode* parent, + scene::ISceneManager* mgr, + s32 id = -1, + const v3f& position = v3f(0,0,0), + const v3f& rotation = v3f(0,0,0), + const v3f& scale = v3f(0,0,0)); + ~ExtrudedSpriteSceneNode(); + + void setSprite(video::ITexture* texture); + void setCube(const TileSpec faces[6]); + + f32 getSpriteThickness() const { return m_thickness; } + void setSpriteThickness(f32 thickness); + + void removeSpriteFromCache(video::ITexture* texture); + + virtual const core::aabbox3d& getBoundingBox() const; + virtual void OnRegisterSceneNode(); + virtual void render(); + +private: + scene::IMeshSceneNode* m_meshnode; + f32 m_thickness; + scene::IMesh* m_cubemesh; + bool m_is_cube; + + // internal extrusion helper methods + io::path getExtrudedName(video::ITexture* texture); + scene::IAnimatedMesh* extrudeARGB(u32 width, u32 height, u8* data); + scene::IAnimatedMesh* extrude(video::ITexture* texture); + scene::IMesh* createCubeMesh(); +}; + +#endif diff --git a/src/client.cpp b/src/client.cpp index 71a826a1f..81dedd144 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2004,14 +2004,6 @@ LocalPlayer* Client::getLocalPlayer() return m_env.getLocalPlayer(); } -void Client::setPlayerWield(scene::ISceneNode *wield) -{ - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - LocalPlayer *player = m_env.getLocalPlayer(); - assert(player != NULL); - player->wield = wield; -} - void Client::setPlayerControl(PlayerControl &control) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index e7a81a111..930987c02 100644 --- a/src/client.h +++ b/src/client.h @@ -210,7 +210,6 @@ public: LocalPlayer* getLocalPlayer(); - void setPlayerWield(scene::ISceneNode *wield); void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); diff --git a/src/game.cpp b/src/game.cpp index a712323b5..5e8db9b1d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -819,44 +819,6 @@ void the_game( f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" - /* - Tool - */ - - v3f tool_wield_position(0.06*BS, -0.06*BS, 0.1*BS); - v3f tool_wield_rotation(-25, 180, -25); - float tool_wield_animation = 0.0; - scene::IMeshSceneNode *tool_wield; - { - scene::SMesh *mesh = new scene::SMesh(); - scene::IMeshBuffer *buf = new scene::SMeshBuffer(); - video::SColor c(255,255,255,255); - video::S3DVertex vertices[4] = - { - video::S3DVertex(-0.5,0,0, 0,0,0, c, 0,1), - video::S3DVertex(0.5,0,0, 0,0,0, c, 1,1), - video::S3DVertex(0.5,0.5,0, 0,0,0, c, 1,0), - video::S3DVertex(-0.5,0.5,0, 0,0,0, c, 0,0), - }; - u16 indices[] = {0,1,2,2,3,0}; - buf->append(vertices, 4, indices, 6); - // Set material - buf->getMaterial().setFlag(video::EMF_LIGHTING, false); - buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); - buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - // Add to mesh - mesh->addMeshBuffer(buf); - buf->drop(); - - tool_wield = smgr->addMeshSceneNode(mesh, camera.getHeadNode()); - mesh->drop(); - } - tool_wield->setVisible(false); - tool_wield->setPosition(tool_wield_position); - tool_wield->setRotation(tool_wield_rotation); - - client.setPlayerWield(tool_wield); - /* Clouds */ @@ -1552,6 +1514,7 @@ void the_game( std::cout<getBlock()->getPos(), selected_object->getId(), g_selected_item); + camera.setDigging(true); } else if(input->getRightClicked()) { @@ -1619,6 +1582,7 @@ void the_game( std::cout<getId(), g_selected_item); + camera.setDigging(true); } else if(input->getRightClicked()) { @@ -1792,6 +1756,8 @@ void the_game( } dig_time += dtime; + + camera.setDigging(true); } } @@ -1859,16 +1825,6 @@ void the_game( nodepos_old = nodepos; } - else{ - } - - - if(input->getLeftState()) - // Tool animation loops 0.0 - 1.0 - tool_wield_animation = fmod(tool_wield_animation + dtime * 3.0, 1.0); - else - // Return tool to holding position if not digging - tool_wield_animation /= 1.5; } // selected_object == NULL @@ -1880,6 +1836,7 @@ void the_game( std::cout<getRightReleased()) { @@ -1985,16 +1942,6 @@ void the_game( ); } - /* - Animate tool - */ - { - f32 tool_wield_sin = sin(tool_wield_animation * PI); - tool_wield->setRotation(tool_wield_rotation - tool_wield_sin * 40.0); - tool_wield->setPosition(tool_wield_position - tool_wield_sin * BS / 30.0); - } - - /* Update gui stuff (0ms) */ @@ -2140,6 +2087,13 @@ void the_game( old_selected_item = g_selected_item; //std::cout<<"Updating local inventory"<getItem(g_selected_item); + camera.wield(item); } /* diff --git a/src/inventory.h b/src/inventory.h index ef8c499b1..4aa68d99e 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -56,8 +56,6 @@ public: // Return the name of the image for this item virtual std::string getBasename() { return ""; } // Shall return an image of the item (or NULL) - virtual video::ITexture * getImageRaw() { return NULL; } - // Shall return an image to show in the GUI (or NULL) virtual video::ITexture * getImage() { return NULL; } #endif // Shall return a text to show in the GUI @@ -156,7 +154,6 @@ public: video::ITexture * getImage() { return content_features(m_content).inventory_texture; - return NULL; } #endif std::string getText() @@ -388,14 +385,6 @@ public: return "cloud.png"; } - video::ITexture * getImageRaw() - { - if(g_texturesource == NULL) - return NULL; - - return g_texturesource->getTextureRaw(getBasename()); - } - video::ITexture * getImage() { if(g_texturesource == NULL) diff --git a/src/player.cpp b/src/player.cpp index 03ae24f45..7cfdfebb6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -309,31 +309,12 @@ LocalPlayer::LocalPlayer(): // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points hp = 0; - - // No tool wielded initially - wield = NULL; } LocalPlayer::~LocalPlayer() { } -void LocalPlayer::wieldItem(u16 item) -{ - m_selected_item = item; - - if(wield) { - InventoryItem* i = inventory.getList("main")->getItem(m_selected_item); - - if(i && strcmp(i->getName(), "ToolItem") == 0) { - wield->getMaterial(0).setTexture(0, i->getImageRaw()); - wield->setVisible(true); - } - else - wield->setVisible(false); - } -} - void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info) { diff --git a/src/player.h b/src/player.h index 0f2c40011..ad0fb5ff9 100644 --- a/src/player.h +++ b/src/player.h @@ -357,8 +357,6 @@ public: return true; } - void wieldItem(u16 item); - void move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info); void move(f32 dtime, Map &map, f32 pos_max_d); @@ -367,8 +365,6 @@ public: PlayerControl control; - scene::ISceneNode *wield; - private: // This is used for determining the sneaking range v3s16 m_sneak_node; -- 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 ++++++++++++++++++++++++++++++++++++++++++------------ src/camera.h | 5 +- src/inventory.cpp | 4 +- src/inventory.h | 24 ++++++--- src/tile.h | 2 +- 5 files changed, 141 insertions(+), 43 deletions(-) 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; +} diff --git a/src/camera.h b/src/camera.h index 08c03dd19..ccc224e3c 100644 --- a/src/camera.h +++ b/src/camera.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include "inventory.h" +#include "tile.h" #include "utility.h" class LocalPlayer; @@ -117,7 +118,7 @@ public: void updateSettings(); // Replace the wielded item mesh - void wield(InventoryItem* item); + void wield(const InventoryItem* item); // Start or stop digging animation void setDigging(bool digging); @@ -190,7 +191,7 @@ public: ~ExtrudedSpriteSceneNode(); void setSprite(video::ITexture* texture); - void setCube(const TileSpec faces[6]); + void setCube(const TileSpec tiles[6]); f32 getSpriteThickness() const { return m_thickness; } void setSpriteThickness(f32 thickness); diff --git a/src/inventory.cpp b/src/inventory.cpp index f31e19f77..a3e35c92c 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -158,7 +158,7 @@ InventoryItem *MaterialItem::createCookResult() const */ #ifndef SERVER -video::ITexture * CraftItem::getImage() +video::ITexture * CraftItem::getImage() const { if(g_texturesource == NULL) return NULL; @@ -224,7 +224,7 @@ bool CraftItem::use(ServerEnvironment *env, Player *player) TODO: Remove */ #ifndef SERVER -video::ITexture * MapBlockObjectItem::getImage() +video::ITexture * MapBlockObjectItem::getImage() const { if(m_inventorystring.substr(0,3) == "Rat") return g_texturesource->getTextureRaw("rat.png"); diff --git a/src/inventory.h b/src/inventory.h index 4aa68d99e..3e05015ef 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -54,9 +54,11 @@ public: virtual InventoryItem* clone() = 0; #ifndef SERVER // Return the name of the image for this item - virtual std::string getBasename() { return ""; } + virtual std::string getBasename() const { return ""; } // Shall return an image of the item (or NULL) - virtual video::ITexture * getImage() { return NULL; } + virtual video::ITexture * getImage() const { return NULL; } + // Shall return an image of the item without embellishments (or NULL) + virtual video::ITexture * getImageRaw() const { return getImage(); } #endif // Shall return a text to show in the GUI virtual std::string getText() { return ""; } @@ -151,7 +153,7 @@ public: return new MaterialItem(m_content, m_count); } #ifndef SERVER - video::ITexture * getImage() + video::ITexture * getImage() const { return content_features(m_content).inventory_texture; } @@ -226,7 +228,7 @@ public: } #ifndef SERVER - video::ITexture * getImage(); + video::ITexture * getImage() const; #endif std::string getText(); @@ -277,7 +279,7 @@ public: return new CraftItem(m_subname, m_count); } #ifndef SERVER - video::ITexture * getImage(); + video::ITexture * getImage() const; #endif std::string getText() { @@ -354,7 +356,7 @@ public: return new ToolItem(m_toolname, m_wear); } #ifndef SERVER - std::string getBasename() { + std::string getBasename() const { if(m_toolname == "WPick") return "tool_woodpick.png"; else if(m_toolname == "STPick") @@ -385,7 +387,7 @@ public: return "cloud.png"; } - video::ITexture * getImage() + video::ITexture * getImage() const { if(g_texturesource == NULL) return NULL; @@ -405,6 +407,14 @@ public: return g_texturesource->getTextureRaw(os.str()); } + + video::ITexture * getImageRaw() const + { + if(g_texturesource == NULL) + return NULL; + + return g_texturesource->getTextureRaw(getBasename()); + } #endif std::string getText() { diff --git a/src/tile.h b/src/tile.h index 216d76508..5cebb0eaa 100644 --- a/src/tile.h +++ b/src/tile.h @@ -304,7 +304,7 @@ struct TileSpec } // Sets everything else except the texture in the material - void applyMaterialOptions(video::SMaterial &material) + void applyMaterialOptions(video::SMaterial &material) const { if(alpha != 255 && material_type != MATERIAL_ALPHA_VERTEX) dstream<<"WARNING: TileSpec: alpha != 255 " -- 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 +++++++++++--------------- src/camera.h | 7 ++++++- src/content_mapnode.cpp | 4 ++++ 3 files changed, 21 insertions(+), 16 deletions(-) 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); diff --git a/src/camera.h b/src/camera.h index ccc224e3c..f960e748e 100644 --- a/src/camera.h +++ b/src/camera.h @@ -166,6 +166,11 @@ private: s32 m_view_bobbing_state; // Speed of view bobbing animation f32 m_view_bobbing_speed; + + // Digging animation + s32 m_digging_anim; + // Speed of digging animation + s32 m_digging_speed; }; @@ -187,7 +192,7 @@ public: s32 id = -1, const v3f& position = v3f(0,0,0), const v3f& rotation = v3f(0,0,0), - const v3f& scale = v3f(0,0,0)); + const v3f& scale = v3f(1,1,1)); ~ExtrudedSpriteSceneNode(); void setSprite(video::ITexture* texture); diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 89171755e..70f465130 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -236,6 +236,8 @@ void content_mapnode_init() if(new_style_leaves) { f->solidness = 0; // drawn separately, makes no faces + f->visual_solidness = 1; + f->setAllTextures("leaves.png"); f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png"); } else @@ -287,6 +289,8 @@ void content_mapnode_init() f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->solidness = 0; // drawn separately, makes no faces + f->visual_solidness = 1; + f->setAllTextures("glass.png"); f->setInventoryTextureCube("glass.png", "glass.png", "glass.png"); setWoodLikeDiggingProperties(f->digging_properties, 0.15); -- 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(-) 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 +++++++++++++++++++++++++++++++++++++++++++--------------- src/camera.h | 19 +++++++------ src/game.cpp | 11 ++++--- 3 files changed, 85 insertions(+), 35 deletions(-) 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; } diff --git a/src/camera.h b/src/camera.h index f960e748e..026f92874 100644 --- a/src/camera.h +++ b/src/camera.h @@ -120,8 +120,9 @@ public: // Replace the wielded item mesh void wield(const InventoryItem* item); - // Start or stop digging animation - void setDigging(bool digging); + // Start digging animation + // Pass 0 for left click, 1 for right click + void setDigging(s32 button); private: // Scene manager and nodes @@ -158,8 +159,8 @@ private: f32 m_frametime_counter; f32 m_time_per_range; - // View bobbing animation frame (0 <= m_view_bobbing < 0x1000000) - s32 m_view_bobbing_anim; + // View bobbing animation frame (0 <= m_view_bobbing_anim < 1) + f32 m_view_bobbing_anim; // If 0, view bobbing is off (e.g. player is standing). // If 1, view bobbing is on (player is walking). // If 2, view bobbing is getting switched off. @@ -167,10 +168,12 @@ private: // Speed of view bobbing animation f32 m_view_bobbing_speed; - // Digging animation - s32 m_digging_anim; - // Speed of digging animation - s32 m_digging_speed; + // Digging animation frame (0 <= m_digging_anim < 1) + f32 m_digging_anim; + // If -1, no digging animation + // If 0, left-click digging animation + // If 1, right-click digging animation + s32 m_digging_button; }; diff --git a/src/game.cpp b/src/game.cpp index 5e8db9b1d..08bc6f176 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1514,7 +1514,6 @@ void the_game( std::cout<getBlock()->getPos(), selected_object->getId(), g_selected_item); - camera.setDigging(true); } else if(input->getRightClicked()) { @@ -1582,7 +1581,6 @@ void the_game( std::cout<getId(), g_selected_item); - camera.setDigging(true); } else if(input->getRightClicked()) { @@ -1757,7 +1755,7 @@ void the_game( dig_time += dtime; - camera.setDigging(true); + camera.setDigging(0); // left click animation } } @@ -1820,6 +1818,7 @@ void the_game( else { client.groundAction(1, nodepos, neighbourpos, g_selected_item); + camera.setDigging(1); // right click animation } } @@ -1828,6 +1827,11 @@ void the_game( } // selected_object == NULL + if(input->getLeftClicked()) + { + camera.setDigging(0); // left click animation + } + input->resetLeftClicked(); input->resetRightClicked(); @@ -1836,7 +1840,6 @@ void the_game( std::cout<getRightReleased()) { -- 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(-) 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 +-- src/player.h | 11 ++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) 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(); diff --git a/src/player.h b/src/player.h index ad0fb5ff9..350b85e1b 100644 --- a/src/player.h +++ b/src/player.h @@ -67,12 +67,17 @@ public: return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); } - v3f getEyePosition() + v3f getEyeOffset() { // This is at the height of the eyes of the current figure - // return m_position + v3f(0, BS+BS/2, 0); + // return v3f(0, BS+BS/2, 0); // This is more like in minecraft - return m_position + v3f(0,BS+(5*BS)/8,0); + return v3f(0,BS+(5*BS)/8,0); + } + + v3f getEyePosition() + { + return m_position + getEyeOffset(); } virtual void setPosition(const v3f &position) -- 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 ++++++++++++++++++++++++++++++++++------- src/camera.h | 13 +++++++------ src/game.cpp | 8 ++++++++ 3 files changed, 49 insertions(+), 13 deletions(-) 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, diff --git a/src/camera.h b/src/camera.h index 026f92874..fbee4a378 100644 --- a/src/camera.h +++ b/src/camera.h @@ -63,12 +63,6 @@ public: return m_cameranode; } - // Get wielded item scene node. - inline ExtrudedSpriteSceneNode* getWieldNode() const - { - return m_wieldnode; - } - // Get the camera position (in absolute scene coordinates). // This has view bobbing applied. inline v3f getPosition() const @@ -124,12 +118,19 @@ public: // Pass 0 for left click, 1 for right click void setDigging(s32 button); + // Draw the wielded tool. + // This has to happen *after* the main scene is drawn. + // Warning: This clears the Z buffer. + void drawWieldedTool(); + private: // Scene manager and nodes scene::ISceneManager* m_smgr; scene::ISceneNode* m_playernode; scene::ISceneNode* m_headnode; scene::ICameraSceneNode* m_cameranode; + + scene::ISceneManager* m_wieldmgr; ExtrudedSpriteSceneNode* m_wieldnode; // draw control diff --git a/src/game.cpp b/src/game.cpp index 08bc6f176..a99662651 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2161,6 +2161,14 @@ void the_game( driver->draw3DBox(*i, video::SColor(255,0,0,0)); } + /* + Wielded tool + */ + { + // Warning: This clears the Z buffer. + camera.drawWieldedTool(); + } + /* Post effects */ -- 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(-) 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 ++++++++++ src/camera.h | 3 +++ src/content_cao.cpp | 68 ++++------------------------------------------------ src/environment.cpp | 21 ++++++++-------- src/mapblockobject.h | 60 ++++------------------------------------------ src/player.h | 24 +++++++------------ src/utility.cpp | 19 +++++++++++++++ src/utility.h | 3 +++ 8 files changed, 66 insertions(+), 145 deletions(-) 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) diff --git a/src/camera.h b/src/camera.h index fbee4a378..66825e372 100644 --- a/src/camera.h +++ b/src/camera.h @@ -205,6 +205,8 @@ public: f32 getSpriteThickness() const { return m_thickness; } void setSpriteThickness(f32 thickness); + void updateLight(u8 light); + void removeSpriteFromCache(video::ITexture* texture); virtual const core::aabbox3d& getBoundingBox() const; @@ -216,6 +218,7 @@ private: f32 m_thickness; scene::IMesh* m_cubemesh; bool m_is_cube; + u8 m_light; // internal extrusion helper methods io::path getExtrudedName(video::ITexture* texture); diff --git a/src/content_cao.cpp b/src/content_cao.cpp index dfeaea85a..b6543061a 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -224,22 +224,7 @@ void ItemCAO::updateLight(u8 light_at_pos) u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - if(mesh == NULL) - return; - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } v3s16 ItemCAO::getLightPosition() @@ -430,22 +415,7 @@ void RatCAO::updateLight(u8 light_at_pos) u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - if(mesh == NULL) - return; - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } v3s16 RatCAO::getLightPosition() @@ -601,22 +571,7 @@ void Oerkki1CAO::updateLight(u8 light_at_pos) u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - if(mesh == NULL) - return; - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } v3s16 Oerkki1CAO::getLightPosition() @@ -833,22 +788,7 @@ void FireflyCAO::updateLight(u8 light_at_pos) u8 li = 255; video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - if(mesh == NULL) - return; - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } v3s16 FireflyCAO::getLightPosition() diff --git a/src/environment.cpp b/src/environment.cpp index 80f41f9fd..ea33274df 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1686,18 +1686,19 @@ void ClientEnvironment::step(float dtime) // Move player->move(dtime, *m_map, 100*BS); - // Update lighting on remote players on client - u8 light = LIGHT_MAX; - try{ - // Get node at head - v3s16 p = player->getLightPosition(); - MapNode n = m_map->getNode(p); - light = n.getLightBlend(getDayNightRatio()); - } - catch(InvalidPositionException &e) {} - player->updateLight(light); } + // Update lighting on all players on client + u8 light = LIGHT_MAX; + try{ + // Get node at head + v3s16 p = player->getLightPosition(); + MapNode n = m_map->getNode(p); + light = n.getLightBlend(getDayNightRatio()); + } + catch(InvalidPositionException &e) {} + player->updateLight(light); + /* Add footsteps to grass */ diff --git a/src/mapblockobject.h b/src/mapblockobject.h index 804494715..b852812e2 100644 --- a/src/mapblockobject.h +++ b/src/mapblockobject.h @@ -484,20 +484,7 @@ public: u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } #endif @@ -676,20 +663,7 @@ public: u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } #endif @@ -836,20 +810,7 @@ public: u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } #endif @@ -982,20 +943,7 @@ public: u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } #endif diff --git a/src/player.h b/src/player.h index 350b85e1b..ce1001992 100644 --- a/src/player.h +++ b/src/player.h @@ -126,7 +126,10 @@ public: virtual bool isLocal() const = 0; - virtual void updateLight(u8 light_at_pos) {}; + virtual void updateLight(u8 light_at_pos) + { + light = light_at_pos; + } // NOTE: Use peer_id == 0 for disconnected /*virtual bool isClientConnected() { return false; } @@ -149,6 +152,8 @@ public: bool swimming_up; bool is_frozen; + u8 light; + Inventory inventory; // Actual inventory is backed up here when creative mode is used Inventory *inventory_backup; @@ -266,25 +271,14 @@ public: virtual void updateLight(u8 light_at_pos) { + Player::updateLight(light_at_pos); + if(m_node == NULL) return; u8 li = decode_light(light_at_pos); video::SColor color(255,li,li,li); - - scene::IMesh *mesh = m_node->getMesh(); - - u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetMesh(), color); } void move(f32 dtime, Map &map, f32 pos_max_d); diff --git a/src/utility.cpp b/src/utility.cpp index 9c1edc8a9..3c6c2f286 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -156,6 +156,25 @@ void mysrand(unsigned seed) next = seed; } +// Sets the color of all vertices in the mesh +void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color) +{ + if(mesh == NULL) + return; + + u16 mc = mesh->getMeshBufferCount(); + for(u16 j=0; jgetMeshBuffer(j); + video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); + u16 vc = buf->getVertexCount(); + for(u16 i=0; i &list, u16 d) { -- 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 +++++++++++++++++++++++++++---- src/game.cpp | 101 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 99 insertions(+), 57 deletions(-) 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); } diff --git a/src/game.cpp b/src/game.cpp index a99662651..13b06db6c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1336,6 +1336,57 @@ void the_game( debug_stacks_print(); } + /* + Mouse and camera control + NOTE: Do this before client.setPlayerControl() to not cause a camera lag of one frame + */ + + if((device->isWindowActive() && noMenuActive()) || random_input) + { + if(!random_input) + { + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible()) + device->getCursorControl()->setVisible(false); + } + + if(first_loop_after_window_activation){ + //std::cout<<"window active, first loop"<getMousePos().X - displaycenter.X; + s32 dy = input->getMousePos().Y - displaycenter.Y; + if(invert_mouse) + dy = -dy; + //std::cout<<"window active, pos difference "<isKeyDown(irr::KEY_UP)) + dy -= dtime * keyspeed; + if(input->isKeyDown(irr::KEY_DOWN)) + dy += dtime * keyspeed; + if(input->isKeyDown(irr::KEY_LEFT)) + dx -= dtime * keyspeed; + if(input->isKeyDown(irr::KEY_RIGHT)) + dx += dtime * keyspeed;*/ + + camera_yaw -= dx*0.2; + camera_pitch += dy*0.2; + if(camera_pitch < -89.5) camera_pitch = -89.5; + if(camera_pitch > 89.5) camera_pitch = 89.5; + } + input->setMousePos(displaycenter.X, displaycenter.Y); + } + else{ + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible() == false) + device->getCursorControl()->setVisible(true); + + //std::cout<<"window inactive"<isWindowActive() && noMenuActive()) || random_input) - { - if(!random_input) - { - // Mac OSX gets upset if this is set every frame - if(device->getCursorControl()->isVisible()) - device->getCursorControl()->setVisible(false); - } - - if(first_loop_after_window_activation){ - //std::cout<<"window active, first loop"<getMousePos().X - displaycenter.X; - s32 dy = input->getMousePos().Y - displaycenter.Y; - if(invert_mouse) - dy = -dy; - //std::cout<<"window active, pos difference "<isKeyDown(irr::KEY_UP)) - dy -= dtime * keyspeed; - if(input->isKeyDown(irr::KEY_DOWN)) - dy += dtime * keyspeed; - if(input->isKeyDown(irr::KEY_LEFT)) - dx -= dtime * keyspeed; - if(input->isKeyDown(irr::KEY_RIGHT)) - dx += dtime * keyspeed;*/ - - camera_yaw -= dx*0.2; - camera_pitch += dy*0.2; - if(camera_pitch < -89.5) camera_pitch = -89.5; - if(camera_pitch > 89.5) camera_pitch = 89.5; - } - input->setMousePos(displaycenter.X, displaycenter.Y); - } - else{ - // Mac OSX gets upset if this is set every frame - if(device->getCursorControl()->isVisible() == false) - device->getCursorControl()->setVisible(true); - - //std::cout<<"window inactive"<