From c3b279750ece0b5144bf8e973d55108347462223 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Feb 2016 14:01:01 +0100 Subject: [PATCH] Move object nametags to camera --- src/camera.cpp | 49 ++++++++++++++++++++++++++ src/camera.h | 30 ++++++++++++++-- src/client.cpp | 1 + src/client.h | 8 +++++ src/content_cao.cpp | 83 ++++++++++++++++++--------------------------- src/content_cao.h | 7 +++- src/drawscene.cpp | 7 +++- src/game.cpp | 1 + src/gamedef.h | 6 ++++ 9 files changed, 138 insertions(+), 54 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 94bbe9880..8aac32123 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include "util/mathconstants.h" #include "constants.h" +#include "fontengine.h" #define CAMERA_OFFSET_STEP 200 @@ -81,6 +82,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, { //dstream<getVideoDriver(); // 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()); @@ -110,6 +112,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_cache_wanted_fps = g_settings->getFloat("wanted_fps"); m_cache_fov = g_settings->getFloat("fov"); m_cache_view_bobbing = g_settings->getBool("view_bobbing"); + m_nametags.clear(); } Camera::~Camera() @@ -662,3 +665,49 @@ void Camera::drawWieldedTool(irr::core::matrix4* translation) } m_wieldmgr->drawAll(); } + +void Camera::drawNametags() +{ + core::matrix4 trans = m_cameranode->getProjectionMatrix(); + trans *= m_cameranode->getViewMatrix(); + + for (std::list::const_iterator + i = m_nametags.begin(); + i != m_nametags.end(); ++i) { + Nametag *nametag = *i; + v3f pos = nametag->parent_node->getPosition() - + intToFloat(m_camera_offset, BS) + v3f(0.0, 1.1 * BS, 0.0); + f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f }; + trans.multiplyWith1x4Matrix(transformed_pos); + if (transformed_pos[3] > 0) { + core::dimension2d textsize = + g_fontengine->getFont()->getDimension( + utf8_to_wide(nametag->nametag_text).c_str()); + f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : + core::reciprocal(transformed_pos[3]); + v2u32 screensize = m_driver->getScreenSize(); + v2s32 screen_pos; + screen_pos.X = screensize.X * + (0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2; + screen_pos.Y = screensize.Y * + (0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2; + core::rect size(0, 0, textsize.Width, textsize.Height); + g_fontengine->getFont()->draw(utf8_to_wide(nametag->nametag_text).c_str(), + size + screen_pos, nametag->nametag_color); + } + } +} + +Nametag *Camera::addNametag(scene::ISceneNode *parent_node, + std::string nametag_text, video::SColor nametag_color) +{ + Nametag *nametag = new Nametag(parent_node, nametag_text, nametag_color); + m_nametags.push_back(nametag); + return nametag; +} + +void Camera::removeNametag(Nametag *nametag) +{ + m_nametags.remove(nametag); + delete nametag; +} diff --git a/src/camera.h b/src/camera.h index 006f4b3ce..2df7da2b8 100644 --- a/src/camera.h +++ b/src/camera.h @@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/tile.h" #include "util/numeric.h" #include +#include +#include #include "client.h" @@ -34,6 +36,20 @@ struct MapDrawControl; class IGameDef; class WieldMeshSceneNode; +struct Nametag { + Nametag(scene::ISceneNode *a_parent_node, + const std::string &a_nametag_text, + const video::SColor &a_nametag_color): + parent_node(a_parent_node), + nametag_text(a_nametag_text), + nametag_color(a_nametag_color) + { + } + scene::ISceneNode *parent_node; + std::string nametag_text; + video::SColor nametag_color; +}; + enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; /* @@ -84,7 +100,7 @@ public: { return m_camera_direction; } - + // Get the camera offset inline v3s16 getOffset() const { @@ -151,6 +167,13 @@ public: return m_camera_mode; } + Nametag *addNametag(scene::ISceneNode *parent_node, + std::string nametag_text, video::SColor nametag_color); + + void removeNametag(Nametag *nametag); + + void drawNametags(); + private: // Nodes scene::ISceneNode* m_playernode; @@ -162,8 +185,9 @@ private: // draw control MapDrawControl& m_draw_control; - + IGameDef *m_gamedef; + video::IVideoDriver *m_driver; // Absolute camera position v3f m_camera_position; @@ -214,6 +238,8 @@ private: f32 m_cache_wanted_fps; f32 m_cache_fov; bool m_cache_view_bobbing; + + std::list m_nametags; }; #endif diff --git a/src/client.cpp b/src/client.cpp index ed5ff96fe..3fe67d645 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -228,6 +228,7 @@ Client::Client( m_particle_manager(&m_env), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this), m_device(device), + m_camera(NULL), m_minimap_disabled_by_server(false), m_server_ser_ver(SER_FMT_VER_INVALID), m_proto_ver(0), diff --git a/src/client.h b/src/client.h index c16e9b77a..cdadb9d3e 100644 --- a/src/client.h +++ b/src/client.h @@ -50,6 +50,7 @@ struct PointedThing; class Database; class Mapper; struct MinimapMapblock; +class Camera; struct QueuedMeshUpdate { @@ -507,6 +508,12 @@ public: Mapper* getMapper () { return m_mapper; } + void setCamera(Camera* camera) + { m_camera = camera; } + + Camera* getCamera () + { return m_camera; } + bool isMinimapDisabledByServer() { return m_minimap_disabled_by_server; } @@ -589,6 +596,7 @@ private: ParticleManager m_particle_manager; con::Connection m_con; IrrlichtDevice *m_device; + Camera *m_camera; Mapper *m_mapper; bool m_minimap_disabled_by_server; // Server serialization version diff --git a/src/content_cao.cpp b/src/content_cao.cpp index e7c7a0be5..d701e4f72 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -546,12 +546,14 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env): // m_smgr(NULL), m_irr(NULL), + m_camera(NULL), + m_gamedef(NULL), m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.), m_meshnode(NULL), m_animated_meshnode(NULL), m_wield_meshnode(NULL), m_spritenode(NULL), - m_textnode(NULL), + m_nametag(NULL), m_position(v3f(0,10*BS,0)), m_velocity(v3f(0,0,0)), m_acceleration(v3f(0,0,0)), @@ -580,8 +582,11 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env): m_last_light(255), m_is_visible(false) { - if(gamedef == NULL) + if (gamedef == NULL) { ClientActiveObject::registerType(getType(), create); + } else { + m_gamedef = gamedef; + } } bool GenericCAO::getCollisionBox(aabb3f *toset) @@ -667,8 +672,7 @@ void GenericCAO::initialize(const std::string &data) GenericCAO::~GenericCAO() { - if(m_is_player) - { + if (m_is_player) { m_env->removePlayerName(m_name.c_str()); } removeFromScene(true); @@ -695,14 +699,15 @@ v3f GenericCAO::getPosition() scene::ISceneNode* GenericCAO::getSceneNode() { - if (m_meshnode) + if (m_meshnode) { return m_meshnode; - if (m_animated_meshnode) + } else if (m_animated_meshnode) { return m_animated_meshnode; - if (m_wield_meshnode) + } else if (m_wield_meshnode) { return m_wield_meshnode; - if (m_spritenode) + } else if (m_spritenode) { return m_spritenode; + } return NULL; } @@ -775,56 +780,47 @@ void GenericCAO::removeFromScene(bool permanent) } } - if(m_meshnode) - { + if (m_meshnode) { m_meshnode->remove(); m_meshnode->drop(); m_meshnode = NULL; - } - if(m_animated_meshnode) - { + } else if (m_animated_meshnode) { m_animated_meshnode->remove(); m_animated_meshnode->drop(); m_animated_meshnode = NULL; - } - if(m_wield_meshnode) - { + } else if (m_wield_meshnode) { m_wield_meshnode->remove(); m_wield_meshnode->drop(); m_wield_meshnode = NULL; - } - if(m_spritenode) - { + } else if (m_spritenode) { m_spritenode->remove(); m_spritenode->drop(); m_spritenode = NULL; } - if (m_textnode) - { - m_textnode->remove(); - m_textnode->drop(); - m_textnode = NULL; + + if (m_nametag) { + m_gamedef->getCamera()->removeNametag(m_nametag); + m_nametag = NULL; } } -void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, - IrrlichtDevice *irr) +void GenericCAO::addToScene(scene::ISceneManager *smgr, + ITextureSource *tsrc, IrrlichtDevice *irr) { m_smgr = smgr; m_irr = irr; - if (getSceneNode() != NULL) + if (getSceneNode() != NULL) { return; + } m_visuals_expired = false; - if(!m_prop.is_visible) + if (!m_prop.is_visible) { return; + } - //video::IVideoDriver* driver = smgr->getVideoDriver(); - - if(m_prop.visual == "sprite") - { + if (m_prop.visual == "sprite") { infostream<<"GenericCAO::addToScene(): single_sprite"<addBillboardSceneNode( NULL, v2f(1, 1), v3f(0,0,0), -1); @@ -972,18 +968,9 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, scene::ISceneNode *node = getSceneNode(); if (node && m_prop.nametag != "" && !m_is_local_player) { - // Add a text node for showing the name - gui::IGUIEnvironment* gui = irr->getGUIEnvironment(); - std::wstring nametag_text = utf8_to_wide(m_prop.nametag); - m_textnode = smgr->addTextSceneNode(gui->getSkin()->getFont(), - nametag_text.c_str(), m_prop.nametag_color, node); - m_textnode->grab(); - m_textnode->setPosition(v3f(0, BS*1.1, 0)); - - // Enforce hiding nametag, - // because if freetype is enabled, a grey - // shadow can remain. - m_textnode->setVisible(m_prop.nametag_color.getAlpha() > 0); + // Add nametag + m_nametag = m_gamedef->getCamera()->addNametag(node, + m_prop.nametag, m_prop.nametag_color); } updateNodePos(); @@ -1785,12 +1772,8 @@ void GenericCAO::processMessage(const std::string &data) // Deprecated, for backwards compatibility only. readU8(is); // version m_prop.nametag_color = readARGB8(is); - if (m_textnode != NULL) { - m_textnode->setTextColor(m_prop.nametag_color); - - // Enforce hiding nametag, - // because if freetype is enabled, a grey shadow can remain. - m_textnode->setVisible(m_prop.nametag_color.getAlpha() > 0); + if (m_nametag != NULL) { + m_nametag->nametag_color = m_prop.nametag_color; } } } diff --git a/src/content_cao.h b/src/content_cao.h index f71dfeb1f..a166ff494 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -26,6 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "object_properties.h" #include "itemgroup.h" +class Camera; +struct Nametag; + /* SmoothTranslator */ @@ -65,12 +68,14 @@ private: // scene::ISceneManager *m_smgr; IrrlichtDevice *m_irr; + Camera* m_camera; + IGameDef *m_gamedef; aabb3f m_selection_box; scene::IMeshSceneNode *m_meshnode; scene::IAnimatedMeshSceneNode *m_animated_meshnode; WieldMeshSceneNode *m_wield_meshnode; scene::IBillboardSceneNode *m_spritenode; - scene::ITextSceneNode* m_textnode; + Nametag* m_nametag; v3f m_position; v3f m_velocity; v3f m_acceleration; diff --git a/src/drawscene.cpp b/src/drawscene.cpp index 32eafeb29..c6abda4ac 100644 --- a/src/drawscene.cpp +++ b/src/drawscene.cpp @@ -195,7 +195,7 @@ video::ITexture* draw_hud(video::IVideoDriver* driver, const v2u32& screensize, hud.drawCrosshair(); hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); - + camera.drawNametags(); guienv->drawAll(); } @@ -416,6 +416,7 @@ void draw_pageflip_3d_mode(Camera& camera, bool show_hud, camera.drawWieldedTool(&leftMove); hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); + camera.drawNametags(); } guienv->drawAll(); @@ -443,6 +444,7 @@ void draw_pageflip_3d_mode(Camera& camera, bool show_hud, camera.drawWieldedTool(&rightMove); hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); + camera.drawNametags(); } guienv->drawAll(); @@ -538,8 +540,11 @@ void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr, { if (draw_crosshair) hud.drawCrosshair(); + hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); + camera.drawNametags(); + if (show_minimap) mapper.drawMinimap(); } diff --git a/src/game.cpp b/src/game.cpp index 44b35ff5b..53db14fb3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2087,6 +2087,7 @@ bool Game::createClient(const std::string &playername, camera = new Camera(smgr, *draw_control, gamedef); if (!camera || !camera->successfullyCreated(*error_message)) return false; + client->setCamera(camera); /* Clouds */ diff --git a/src/gamedef.h b/src/gamedef.h index a5f6b5968..7e3da4cac 100644 --- a/src/gamedef.h +++ b/src/gamedef.h @@ -32,6 +32,8 @@ class IShaderSource; class MtEventManager; class IRollbackManager; class EmergeManager; +class Camera; + namespace irr { namespace scene { class IAnimatedMesh; class ISceneManager; @@ -67,6 +69,10 @@ public: { return NULL; } virtual scene::ISceneManager* getSceneManager()=0; + virtual Camera* getCamera() + { return NULL; } + virtual void setCamera(Camera *camera) {} + // Only usable on the server, and NOT thread-safe. It is usable from the // environment thread. virtual IRollbackManager* getRollbackManager(){return NULL;}