Create a separate scene manager for the wielded tool. This fixes the glitchyness...
authorKahrl <kahrl@gmx.net>
Tue, 20 Sep 2011 23:42:52 +0000 (01:42 +0200)
committerKahrl <kahrl@gmx.net>
Tue, 20 Sep 2011 23:42:52 +0000 (01:42 +0200)
src/camera.cpp
src/camera.h
src/game.cpp

index 4b0f968a42e45fcd51e419428388b68521fb65fd..56028da4027ea0c5a2cecf68bc21225c1333ce26 100644 (file)
@@ -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,
index 026f928741c41011e4cbe1346bc7cb63aa3bfc9b..fbee4a3786af523b9a78779f2d8ea395c3a627b8 100644 (file)
@@ -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
index 08bc6f176e58f57bfa8debfb80a8ce9d1d43d617..a996626515d677a70772553a373ede615053ca5b 100644 (file)
@@ -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
                */