Move object nametags to camera
authorRealBadAngel <maciej.kasatkin@o2.pl>
Mon, 15 Feb 2016 13:01:01 +0000 (14:01 +0100)
committerest31 <MTest31@outlook.com>
Thu, 18 Feb 2016 15:43:29 +0000 (16:43 +0100)
src/camera.cpp
src/camera.h
src/client.cpp
src/client.h
src/content_cao.cpp
src/content_cao.h
src/drawscene.cpp
src/game.cpp
src/gamedef.h

index 94bbe9880386f9c16fc42d4ec85e371abc1d7aba..8aac32123b42042f06fd06ec9145b5e1d03fbd67 100644 (file)
@@ -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<<FUNCTION_NAME<<std::endl;
 
+       m_driver = smgr->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<Nametag *>::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<u32> 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<s32> 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;
+}
index 006f4b3cebadf1a74f9e682d2e1ed74b9bd54198..2df7da2b83be5a196bdfab763f9294af43d884cb 100644 (file)
@@ -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 <ICameraSceneNode.h>
+#include <ISceneNode.h>
+#include <list>
 
 #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<Nametag *> m_nametags;
 };
 
 #endif
index ed5ff96fefad4f3c24fddda1931ff37712820a36..3fe67d64597dd110eb254e3228c318fa3db33edb 100644 (file)
@@ -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),
index c16e9b77aee6f1d9fdab26607fa4d3455e88af6a..cdadb9d3ea42b1f2566f0a48fcb3524a1477345c 100644 (file)
@@ -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
index e7c7a0be5fbf8eace98a7f6760cf42ded7f8f201..d701e4f725d66c04d127ece4754024bf90d1315a 100644 (file)
@@ -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"<<std::endl;
                m_spritenode = smgr->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;
                }
        }
 }
index f71dfeb1f36c16f6c813d08eb1be1ad23d539475..a166ff4943d34bad84bc9214ead733ea48e3d489 100644 (file)
@@ -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;
index 32eafeb29422e2c087e49bb6206166ce7ab1a221..c6abda4ac135b28efb588396a144ae5471c32437 100644 (file)
@@ -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();
        }
index 44b35ff5bf402e19c19abda6832be7a2f30abe1b..53db14fb3de5bc59a20ee3d6596775b8f19d0d3a 100644 (file)
@@ -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
         */
index a5f6b596822842397e53b5e77c5e49d3cd7a0a6d..7e3da4cacf8e29d7bbcdc1034f4cf3463136e5bd 100644 (file)
@@ -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;}