Add support for interlaced polarized 3d screens 1269/head
authorsapier <Sapier at GMX dot net>
Sun, 27 Apr 2014 14:09:21 +0000 (16:09 +0200)
committersapier <Sapier at GMX dot net>
Sat, 17 May 2014 23:08:13 +0000 (01:08 +0200)
Add (experimental) support for topbottom as well as sidebyside 3d mode

17 files changed:
minetest.conf.example
src/CMakeLists.txt
src/camera.cpp
src/camera.h
src/client.cpp
src/clientmap.cpp
src/clientmap.h
src/content_cao.cpp
src/defaultsettings.cpp
src/drawscene.cpp [new file with mode: 0644]
src/drawscene.h [new file with mode: 0644]
src/game.cpp
src/hud.cpp
src/localplayer.cpp
src/localplayer.h
src/sky.cpp
src/sky.h

index c134446579e23c2b74a65d7e122865b8f7d03db3..0b92d18478f02b35af625d2619f9769b47688fd1 100644 (file)
 #view_bobbing_amount = 1.0
 # Amount of fall bobbing (0 = no fall bobbing, 1.0 = normal, 2.0 = double)
 #fall_bobbing_amount = 0.0
-# Anaglyph stereo
-#anaglyph = false
-#anaglyph_strength = 0.1
+# 3d support,
+# right now:
+#     "none"       = no 3d output,
+#     "anaglyph"   = cyan/magenta color 3d,
+#     "interlaced" = odd/even line based polarisation screen support,
+#     "topbottom"  = split screen top boton,
+#     "sidebyside" = split screen side by side
+#3d_mode = none
+#3d_paralax_strength = 0.025
 # In-game chat console background color (R,G,B)
 #console_color = (0,0,0)
 # In-game chat console background alpha (opaqueness, between 0 and 255)
index 09964321a7e8b3104bfcaaea165309edb357c042..0992ea17646fcc6b0bc92eab9fa1eb1589b7b6fc 100644 (file)
@@ -460,6 +460,7 @@ set(minetest_SRCS
        guiEngine.cpp
        guiFileSelectMenu.cpp
        convert_json.cpp
+       drawscene.cpp
        ${minetest_SCRIPT_SRCS}
 )
 
index 25482780336237148bd48a8d7cab79c14c347c84..d961d45b9c1450b9fbfe4a943b512f9791032367 100644 (file)
@@ -82,7 +82,9 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
        m_wield_change_timer(0.125),
        m_wield_mesh_next(NULL),
        m_previous_playeritem(-1),
-       m_previous_itemname("")
+       m_previous_itemname(""),
+
+       m_camera_mode(CAMERA_MODE_FIRST)
 {
        //dstream<<__FUNCTION_NAME<<std::endl;
 
@@ -159,8 +161,10 @@ void Camera::step(f32 dtime)
        if(m_wield_change_timer > 0.125)
                m_wield_change_timer = 0.125;
 
-       if(m_wield_change_timer >= 0 && was_under_zero) {
-               if(m_wield_mesh_next) {
+       if(m_wield_change_timer >= 0 && was_under_zero)
+       {
+               if(m_wield_mesh_next)
+               {
                        m_wieldnode->setMesh(m_wield_mesh_next);
                        m_wieldnode->setVisible(true);
                } else {
@@ -189,11 +193,14 @@ void Camera::step(f32 dtime)
 #endif
 #if 1
                        // Animation is getting turned off
-                       if(m_view_bobbing_anim < 0.25){
+                       if(m_view_bobbing_anim < 0.25)
+                       {
                                m_view_bobbing_anim -= offset;
-                       } else if(m_view_bobbing_anim > 0.75){
+                       } else if(m_view_bobbing_anim > 0.75) {
                                m_view_bobbing_anim += offset;
-                       } if(m_view_bobbing_anim < 0.5){
+                       }
+                       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;
@@ -217,7 +224,8 @@ void Camera::step(f32 dtime)
                        bool step = (was == 0 ||
                                        (was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
                                        (was > 0.5f && m_view_bobbing_anim <= 0.5f));
-                       if(step){
+                       if(step)
+                       {
                                MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep");
                                m_gamedef->event()->put(e);
                        }
@@ -237,10 +245,11 @@ void Camera::step(f32 dtime)
                float lim = 0.15;
                if(m_digging_anim_was < lim && m_digging_anim >= lim)
                {
-                       if(m_digging_button == 0){
+                       if(m_digging_button == 0)
+                       {
                                MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft");
                                m_gamedef->event()->put(e);
-                       } else if(m_digging_button == 1){
+                       } else if(m_digging_button == 1) {
                                MtEvent *e = new SimpleTriggerEvent("CameraPunchRight");
                                m_gamedef->event()->put(e);
                        }
@@ -249,8 +258,7 @@ void Camera::step(f32 dtime)
 }
 
 void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
-               f32 tool_reload_ratio,
-               int current_camera_mode, ClientEnvironment &c_env)
+               f32 tool_reload_ratio, ClientEnvironment &c_env)
 {
        // Get player position
        // Smooth the movement when walking up stairs
@@ -278,7 +286,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
 
        // Fall bobbing animation
        float fall_bobbing = 0;
-       if(player->camera_impact >= 1 && current_camera_mode < CAMERA_MODE_THIRD)
+       if(player->camera_impact >= 1 && m_camera_mode < CAMERA_MODE_THIRD)
        {
                if(m_view_bobbing_fall == -1) // Effect took place and has finished
                        player->camera_impact = m_view_bobbing_fall = 0;
@@ -297,7 +305,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
 
        // Calculate players eye offset for different camera modes
        v3f PlayerEyeOffset = player->getEyeOffset();
-       if (current_camera_mode == CAMERA_MODE_FIRST)
+       if (m_camera_mode == CAMERA_MODE_FIRST)
                PlayerEyeOffset += player->eye_offset_first;
        else
                PlayerEyeOffset += player->eye_offset_third;
@@ -312,7 +320,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
        v3f rel_cam_target = v3f(0,0,1);
        v3f rel_cam_up = v3f(0,1,0);
 
-       if (m_view_bobbing_anim != 0 && current_camera_mode < CAMERA_MODE_THIRD)
+       if (m_view_bobbing_anim != 0 && m_camera_mode < CAMERA_MODE_THIRD)
        {
                f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
                f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
@@ -365,16 +373,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
        v3f my_cp = m_camera_position;
        
        // Reposition the camera for third person view
-       if (current_camera_mode > CAMERA_MODE_FIRST) {
-               
-               if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
+       if (m_camera_mode > CAMERA_MODE_FIRST)
+       {
+               if (m_camera_mode == CAMERA_MODE_THIRD_FRONT)
                        m_camera_direction *= -1;
 
                my_cp.Y += 2;
 
                // Calculate new position
                bool abort = false;
-               for (int i = BS; i <= BS*2; i++) {
+               for (int i = BS; i <= BS*2; i++)
+               {
                        my_cp.X = m_camera_position.X + m_camera_direction.X*-i;
                        my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i;
                        if (i > 12)
@@ -384,7 +393,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                        INodeDefManager *nodemgr = m_gamedef->ndef();
                        MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS));
                        const ContentFeatures& features = nodemgr->get(n);
-                       if(features.walkable) {
+                       if(features.walkable)
+                       {
                                my_cp.X += m_camera_direction.X*-1*-BS/2;
                                my_cp.Z += m_camera_direction.Z*-1*-BS/2;
                                my_cp.Y += m_camera_direction.Y*-1*-BS/2;
@@ -413,7 +423,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
        m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction);
 
        // update the camera position in front-view mode to render blocks behind player
-       if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
+       if (m_camera_mode == CAMERA_MODE_THIRD_FRONT)
                m_camera_position = my_cp;
 
        // Get FOV setting
@@ -439,7 +449,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                wield_position.Y -= 40 + m_wield_change_timer*320;
        else
                wield_position.Y -= 40 - m_wield_change_timer*320;
-       if(m_digging_anim < 0.05 || m_digging_anim > 0.5){
+       if(m_digging_anim < 0.05 || m_digging_anim > 0.5)
+       {
                f32 frac = 1.0;
                if(m_digging_anim > 0.5)
                        frac = 2.0 * (m_digging_anim - 0.5);
@@ -468,8 +479,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI));
                quat_slerp.toEuler(wield_rotation);
                wield_rotation *= core::RADTODEG;
-       }
-       else {
+       } else {
                f32 bobfrac = my_modf(m_view_bobbing_anim);
                wield_position.X -= sin(bobfrac*M_PI*2.0) * 3.0;
                wield_position.Y += sin(my_modf(bobfrac*2.0)*M_PI) * 3.0;
@@ -654,12 +664,14 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
        std::string itemname = item.getDefinition(idef).name;
        m_wield_mesh_next = idef->getWieldMesh(itemname, m_gamedef);
        if(playeritem != m_previous_playeritem &&
-                       !(m_previous_itemname == "" && itemname == "")) {
+                       !(m_previous_itemname == "" && itemname == ""))
+       {
                m_previous_playeritem = playeritem;
                m_previous_itemname = itemname;
                if(m_wield_change_timer >= 0.125)
                        m_wield_change_timer = -0.125;
-               else if(m_wield_change_timer > 0) {
+               else if(m_wield_change_timer > 0)
+               {
                        m_wield_change_timer = -m_wield_change_timer;
                }
        } else {
@@ -670,7 +682,8 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
                        m_wieldnode->setVisible(false);
                }
                m_wield_mesh_next = NULL;
-               if(m_previous_itemname != itemname) {
+               if(m_previous_itemname != itemname)
+               {
                        m_previous_itemname = itemname;
                        m_wield_change_timer = 0;
                }
@@ -679,7 +692,7 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
        }
 }
 
-void Camera::drawWieldedTool()
+void Camera::drawWieldedTool(irr::core::matrix4* translation)
 {
        // Set vertex colors of wield mesh according to light level
        u8 li = m_wieldlight;
@@ -695,5 +708,17 @@ void Camera::drawWieldedTool()
        cam->setFOV(72.0*M_PI/180.0);
        cam->setNearValue(0.1);
        cam->setFarValue(100);
+       if (translation != NULL)
+       {
+               irr::core::matrix4 startMatrix = cam->getAbsoluteTransformation();
+               irr::core::vector3df focusPoint = (cam->getTarget()
+                               - cam->getAbsolutePosition()).setLength(1)
+                               + cam->getAbsolutePosition();
+
+               irr::core::vector3df camera_pos =
+                               (startMatrix * *translation).getTranslation();
+               cam->setPosition(camera_pos);
+               cam->setTarget(focusPoint);
+       }
        m_wieldmgr->drawAll();
 }
index 63d109f1f877e708d82074573ea9b3b1032b13ba..8831257cc8c2df3b8d7bf51989785779203d31e8 100644 (file)
@@ -33,7 +33,7 @@ class LocalPlayer;
 struct MapDrawControl;
 class IGameDef;
 
-enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
+enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
 
 /*
        Client camera class, manages the player and camera scene nodes, the viewing distance
@@ -117,8 +117,7 @@ public:
        // Update the camera from the local player's position.
        // busytime is used to adjust the viewing range.
        void update(LocalPlayer* player, f32 frametime, f32 busytime,
-                       f32 tool_reload_ratio,
-                       int current_camera_mode, ClientEnvironment &c_env);
+                       f32 tool_reload_ratio, ClientEnvironment &c_env);
 
        // Render distance feedback loop
        void updateViewingRange(f32 frametime_in, f32 busytime_in);
@@ -133,7 +132,23 @@ public:
        // Draw the wielded tool.
        // This has to happen *after* the main scene is drawn.
        // Warning: This clears the Z buffer.
-       void drawWieldedTool();
+       void drawWieldedTool(irr::core::matrix4* translation=NULL);
+
+       // Toggle the current camera mode
+       void toggleCameraMode() {
+               if (m_camera_mode == CAMERA_MODE_FIRST)
+                       m_camera_mode = CAMERA_MODE_THIRD;
+               else if (m_camera_mode == CAMERA_MODE_THIRD)
+                       m_camera_mode = CAMERA_MODE_THIRD_FRONT;
+               else
+                       m_camera_mode = CAMERA_MODE_FIRST;
+       }
+
+       //read the current camera mode
+       inline CameraMode getCameraMode()
+       {
+               return m_camera_mode;
+       }
 
 private:
        // Nodes
@@ -196,6 +211,8 @@ private:
        scene::IMesh *m_wield_mesh_next;
        u16 m_previous_playeritem;
        std::string m_previous_itemname;
+
+       CameraMode m_camera_mode;
 };
 
 #endif
index 6b5072267ed1221ca0db60a45e89f9a6c7ee67f7..5f3c3f590d15fef260ab8c47237c8c661a9fa700 100644 (file)
@@ -51,6 +51,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/directiontables.h"
 #include "util/pointedthing.h"
 #include "version.h"
+#include "drawscene.h"
+
+extern gui::IGUIEnvironment* guienv;
 
 /*
        QueuedMeshUpdate
@@ -2648,10 +2651,6 @@ float Client::mediaReceiveProgress()
                return 1.0; // downloader only exists when not yet done
 }
 
-void draw_load_screen(const std::wstring &text,
-               IrrlichtDevice* device, gui::IGUIFont* font,
-               float dtime=0 ,int percent=0, bool clouds=true);
-
 void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
 {
        infostream<<"Client::afterContentReceived() started"<<std::endl;
@@ -2680,7 +2679,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
        {
                verbosestream<<"Updating item textures and meshes"<<std::endl;
                wchar_t* text = wgettext("Item textures...");
-               draw_load_screen(text,device,font,0,0);
+               draw_load_screen(text, device, guienv, font, 0, 0);
                std::set<std::string> names = m_itemdef->getAll();
                size_t size = names.size();
                size_t count = 0;
@@ -2693,7 +2692,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
                        count++;
                        percent = count*100/size;
                        if (count%50 == 0) // only update every 50 item
-                               draw_load_screen(text,device,font,0,percent);
+                               draw_load_screen(text, device, guienv, font, 0, percent);
                }
                delete[] text;
        }
index 0a5d00b99a01d7b649457bf43238d39ab9ca620b..e061a5998d42bd588773ce3c0baa8ca4b4a35a5e 100644 (file)
@@ -856,7 +856,7 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
        return ret;
 }
 
-void ClientMap::renderPostFx()
+void ClientMap::renderPostFx(CameraMode cam_mode)
 {
        INodeDefManager *nodemgr = m_gamedef->ndef();
 
@@ -867,8 +867,6 @@ void ClientMap::renderPostFx()
        v3f camera_position = m_camera_position;
        m_camera_mutex.Unlock();
 
-       LocalPlayer *player = m_client->getEnv().getLocalPlayer();
-
        MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
 
        // - If the player is in a solid node, make everything black.
@@ -876,7 +874,9 @@ void ClientMap::renderPostFx()
        // - Do not if player is in third person mode
        const ContentFeatures& features = nodemgr->get(n);
        video::SColor post_effect_color = features.post_effect_color;
-       if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")) && player->camera_mode == CAMERA_MODE_FIRST)
+       if(features.solidness == 2 && !(g_settings->getBool("noclip") &&
+                       m_gamedef->checkLocalPrivilege("noclip")) &&
+                       cam_mode == CAMERA_MODE_FIRST)
        {
                post_effect_color = video::SColor(255, 0, 0, 0);
        }
index e695411be593916695a4616c03449e95ac2e8524..91f58a70c5dbd125e59efb92247437b1f5946bb4 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "irrlichttypes_extrabloated.h"
 #include "map.h"
+#include "camera.h"
 #include <set>
 #include <map>
 
@@ -126,7 +127,7 @@ public:
        int getBackgroundBrightness(float max_d, u32 daylight_factor,
                        int oldvalue, bool *sunlight_seen_result);
 
-       void renderPostFx();
+       void renderPostFx(CameraMode cam_mode);
 
        // For debug printing
        virtual void PrintInfo(std::ostream &out);
index 30384a3134855a79576b14c21ed162953a56c9c1..b7923ff80d4c02bc03cf980da0232b413eb0b573 100644 (file)
@@ -84,7 +84,8 @@ void SmoothTranslator::update(v3f vect_new, bool is_end_position, float update_i
        aim_is_end = is_end_position;
        vect_old = vect_show;
        vect_aim = vect_new;
-       if(update_interval > 0){
+       if(update_interval > 0)
+       {
                anim_time = update_interval;
        } else {
                if(anim_time < 0.001 || anim_time > 1.0)
@@ -582,8 +583,10 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
                ClientActiveObject::registerType(getType(), create);
 }
 
-bool GenericCAO::getCollisionBox(aabb3f *toset) {
-       if (m_prop.physical) {
+bool GenericCAO::getCollisionBox(aabb3f *toset)
+{
+       if (m_prop.physical)
+       {
                //update collision box
                toset->MinEdge = m_prop.collisionbox.MinEdge * BS;
                toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS;
@@ -597,7 +600,8 @@ bool GenericCAO::getCollisionBox(aabb3f *toset) {
        return false;
 }
 
-bool GenericCAO::collideWithObjects() {
+bool GenericCAO::collideWithObjects()
+{
        return m_prop.collideWithObjects;
 }
 
@@ -635,7 +639,8 @@ void GenericCAO::initialize(const std::string &data)
                return;
        }
 
-       for(int i=0; i<num_messages; i++){
+       for(int i=0; i<num_messages; i++)
+       {
                std::string message = deSerializeLongString(is);
                processMessage(message);
        }
@@ -643,10 +648,17 @@ void GenericCAO::initialize(const std::string &data)
        pos_translator.init(m_position);
        updateNodePos();
 
-       if(m_is_player){
+       if(m_is_player)
+       {
                Player *player = m_env->getPlayer(m_name.c_str());
-               if(player && player->isLocal()){
+               if(player && player->isLocal())
+               {
                        m_is_local_player = true;
+                       m_is_visible = false;
+                       LocalPlayer* localplayer = dynamic_cast<LocalPlayer*>(player);
+
+                       assert( localplayer != NULL );
+                       localplayer->setCAO(this);
                }
                m_env->addPlayerName(m_name.c_str());
        }
@@ -654,7 +666,8 @@ void GenericCAO::initialize(const std::string &data)
 
 GenericCAO::~GenericCAO()
 {
-       if(m_is_player){
+       if(m_is_player)
+       {
                m_env->removePlayerName(m_name.c_str());
        }
 }
@@ -668,7 +681,8 @@ core::aabbox3d<f32>* GenericCAO::getSelectionBox()
 
 v3f GenericCAO::getPosition()
 {
-       if(getParent() != NULL){
+       if(getParent() != NULL)
+       {
                if(m_meshnode)
                        return m_meshnode->getAbsolutePosition();
                if(m_animated_meshnode)
@@ -711,9 +725,12 @@ ClientActiveObject* GenericCAO::getParent()
        ClientActiveObject *obj = NULL;
        for(std::vector<core::vector2d<int> >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++)
        {
-               if(cii->X == getId()){ // This ID is our child
-                       if(cii->Y > 0){ // A parent ID exists for our child
-                               if(cii->X != cii->Y){ // The parent and child ID are not the same
+               if(cii->X == getId()) // This ID is our child
+               {
+                       if(cii->Y > 0) // A parent ID exists for our child
+                       {
+                               if(cii->X != cii->Y) // The parent and child ID are not the same
+                               {
                                        obj = m_env->getActiveObject(cii->Y);
                                }
                        }
@@ -730,18 +747,21 @@ void GenericCAO::removeFromScene(bool permanent)
        if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
        {
                // Detach this object's children
-               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
+               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
+                               ii != m_env->attachment_list.end(); ii++)
                {
                        if(ii->Y == getId()) // Is a child of our object
                        {
                                ii->Y = 0;
-                               ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
+                               // Get the object of the child
+                               ClientActiveObject *obj = m_env->getActiveObject(ii->X);
                                if(obj)
                                        obj->setAttachments();
                        }
                }
                // Delete this object from the attachments list
-               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
+               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
+                               ii != m_env->attachment_list.end(); ii++)
                {
                        if(ii->X == getId()) // Is our object
                        {
@@ -751,15 +771,18 @@ void GenericCAO::removeFromScene(bool permanent)
                }
        }
 
-       if(m_meshnode){
+       if(m_meshnode)
+       {
                m_meshnode->remove();
                m_meshnode = NULL;
        }
-       if(m_animated_meshnode){
+       if(m_animated_meshnode)
+       {
                m_animated_meshnode->remove();
                m_animated_meshnode = NULL;
        }
-       if(m_spritenode){
+       if(m_spritenode)
+       {
                m_spritenode->remove();
                m_spritenode = NULL;
        }
@@ -781,7 +804,8 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
 
        //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);
@@ -801,8 +825,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
                                        txs, tys, 0, 0);
                }
        }
-       else if(m_prop.visual == "upright_sprite")
-       {
+       else if(m_prop.visual == "upright_sprite") {
                scene::SMesh *mesh = new scene::SMesh();
                double dx = BS*m_prop.visual_size.X/2;
                double dy = BS*m_prop.visual_size.Y/2;
@@ -856,7 +879,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
                // This is needed for changing the texture in the future
                m_meshnode->setReadOnlyMaterials(true);
        }
-       else if(m_prop.visual == "cube"){
+       else if(m_prop.visual == "cube") {
                infostream<<"GenericCAO::addToScene(): cube"<<std::endl;
                scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
                m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
@@ -873,7 +896,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
                m_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
                m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
        }
-       else if(m_prop.visual == "mesh"){
+       else if(m_prop.visual == "mesh") {
                infostream<<"GenericCAO::addToScene(): mesh"<<std::endl;
                scene::IAnimatedMesh *mesh = m_gamedef->getMesh(m_prop.mesh);
                if(mesh)
@@ -895,7 +918,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
                else
                        errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
        }
-       else if(m_prop.visual == "wielditem"){
+       else if(m_prop.visual == "wielditem") {
                infostream<<"GenericCAO::addToScene(): node"<<std::endl;
                infostream<<"textures: "<<m_prop.textures.size()<<std::endl;
                if(m_prop.textures.size() >= 1){
@@ -949,7 +972,8 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
 void GenericCAO::updateLight(u8 light_at_pos)
 {
        u8 li = decode_light(light_at_pos);
-       if(li != m_last_light){
+       if(li != m_last_light)
+       {
                m_last_light = li;
                video::SColor color(255,li,li,li);
                if(m_meshnode)
@@ -972,19 +996,22 @@ void GenericCAO::updateNodePos()
                return;
 
        v3s16 camera_offset = m_env->getCameraOffset();
-       if(m_meshnode){
+       if(m_meshnode)
+       {
                m_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
                v3f rot = m_meshnode->getRotation();
                rot.Y = -m_yaw;
                m_meshnode->setRotation(rot);
        }
-       if(m_animated_meshnode){
+       if(m_animated_meshnode)
+       {
                m_animated_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
                v3f rot = m_animated_meshnode->getRotation();
                rot.Y = -m_yaw;
                m_animated_meshnode->setRotation(rot);
        }
-       if(m_spritenode){
+       if(m_spritenode)
+       {
                m_spritenode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
        }
 }
@@ -992,13 +1019,14 @@ void GenericCAO::updateNodePos()
 void GenericCAO::step(float dtime, ClientEnvironment *env)
 {
        // Handel model of local player instantly to prevent lags
-       if(m_is_local_player) {
+       if(m_is_local_player)
+       {
                LocalPlayer *player = m_env->getLocalPlayer();
 
-               if (player->camera_mode > CAMERA_MODE_FIRST) {
+               if (m_is_visible)
+               {
                        int old_anim = player->last_animation;
                        float old_anim_speed = player->last_animation_speed;
-                       m_is_visible = true;
                        m_position = player->getPosition() + v3f(0,BS,0);
                        m_velocity = v3f(0,0,0);
                        m_acceleration = v3f(0,0,0);
@@ -1026,7 +1054,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                        if(controls.sneak && walking)
                                new_speed /= 2;
 
-                       if(walking && (controls.LMB || controls.RMB)) {
+                       if(walking && (controls.LMB || controls.RMB))
+                       {
                                new_anim = player->local_animations[3];
                                player->last_animation = WD_ANIM;
                        } else if(walking) {
@@ -1039,7 +1068,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
 
                        // Apply animations if input detected and not attached
                        // or set idle animation
-                       if ((new_anim.X + new_anim.Y) > 0 && !player->isAttached) {
+                       if ((new_anim.X + new_anim.Y) > 0 && !player->isAttached)
+                       {
                                allow_update = true;
                                m_animation_range = new_anim;
                                m_animation_speed = new_speed;
@@ -1047,36 +1077,42 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                        } else {
                                player->last_animation = NO_ANIM;
 
-                               if (old_anim != NO_ANIM) {
+                               if (old_anim != NO_ANIM)
+                               {
                                        m_animation_range = player->local_animations[0];
                                        updateAnimation();
                                }
                        }
 
                        // Update local player animations
-                       if ((player->last_animation != old_anim || m_animation_speed != old_anim_speed) &&
+                       if ((player->last_animation != old_anim ||
+                               m_animation_speed != old_anim_speed) &&
                                player->last_animation != NO_ANIM && allow_update)
                                        updateAnimation();
 
-               } else {
-                       m_is_visible = false;
                }
        }
 
        if(m_visuals_expired && m_smgr && m_irr){
                m_visuals_expired = false;
 
-               // Attachments, part 1: All attached objects must be unparented first, or Irrlicht causes a segmentation fault
-               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
+               // Attachments, part 1: All attached objects must be unparented first,
+               // or Irrlicht causes a segmentation fault
+               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
+                               ii != m_env->attachment_list.end(); ii++)
                {
                        if(ii->Y == getId()) // This is a child of our parent
                        {
-                               ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
+                               // Get the object of the child
+                               ClientActiveObject *obj = m_env->getActiveObject(ii->X);
                                if(obj)
                                {
-                                       scene::IMeshSceneNode *m_child_meshnode = obj->getMeshSceneNode();
-                                       scene::IAnimatedMeshSceneNode *m_child_animated_meshnode = obj->getAnimatedMeshSceneNode();
-                                       scene::IBillboardSceneNode *m_child_spritenode = obj->getSpriteSceneNode();
+                                       scene::IMeshSceneNode *m_child_meshnode
+                                                       = obj->getMeshSceneNode();
+                                       scene::IAnimatedMeshSceneNode *m_child_animated_meshnode
+                                                       = obj->getAnimatedMeshSceneNode();
+                                       scene::IBillboardSceneNode *m_child_spritenode
+                                                       = obj->getSpriteSceneNode();
                                        if(m_child_meshnode)
                                                m_child_meshnode->setParent(m_smgr->getRootSceneNode());
                                        if(m_child_animated_meshnode)
@@ -1091,11 +1127,13 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
 
                // Attachments, part 2: Now that the parent has been refreshed, put its attachments back
-               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
+               for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
+                               ii != m_env->attachment_list.end(); ii++)
                {
                        if(ii->Y == getId()) // This is a child of our parent
                        {
-                               ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
+                               // Get the object of the child
+                               ClientActiveObject *obj = m_env->getActiveObject(ii->X);
                                if(obj)
                                        obj->setAttachments();
                        }
@@ -1126,12 +1164,11 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                        player->overridePosition = getParent()->getPosition();
                        m_env->getLocalPlayer()->parent = getParent();
                }
-       }
-       else
-       {
+       } else {
                v3f lastpos = pos_translator.vect_show;
 
-               if(m_prop.physical){
+               if(m_prop.physical)
+               {
                        core::aabbox3d<f32> box = m_prop.collisionbox;
                        box.MinEdge *= BS;
                        box.MaxEdge *= BS;
@@ -1156,16 +1193,19 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                } else {
                        m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
                        m_velocity += dtime * m_acceleration;
-                       pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
+                       pos_translator.update(m_position, pos_translator.aim_is_end,
+                                       pos_translator.anim_time);
                        pos_translator.translate(dtime);
                        updateNodePos();
                }
 
                float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
                m_step_distance_counter += moved;
-               if(m_step_distance_counter > 1.5*BS){
+               if(m_step_distance_counter > 1.5*BS)
+               {
                        m_step_distance_counter = 0;
-                       if(!m_is_local_player && m_prop.makes_footstep_sound){
+                       if(!m_is_local_player && m_prop.makes_footstep_sound)
+                       {
                                INodeDefManager *ndef = m_gamedef->ndef();
                                v3s16 p = floatToInt(getPosition() + v3f(0,
                                                (m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS);
@@ -1177,7 +1217,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
        }
 
        m_anim_timer += dtime;
-       if(m_anim_timer >= m_anim_framelength){
+       if(m_anim_timer >= m_anim_framelength)
+       {
                m_anim_timer -= m_anim_framelength;
                m_anim_frame++;
                if(m_anim_frame >= m_anim_num_frames)
@@ -1186,28 +1227,33 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
 
        updateTexturePos();
 
-       if(m_reset_textures_timer >= 0){
+       if(m_reset_textures_timer >= 0)
+       {
                m_reset_textures_timer -= dtime;
                if(m_reset_textures_timer <= 0){
                        m_reset_textures_timer = -1;
                        updateTextures("");
                }
        }
-       if(getParent() == NULL && fabs(m_prop.automatic_rotate) > 0.001){
+       if(getParent() == NULL && fabs(m_prop.automatic_rotate) > 0.001)
+       {
                m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI;
                updateNodePos();
        }
 
        if (getParent() == NULL && m_prop.automatic_face_movement_dir &&
-                       (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)){
-               m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI + m_prop.automatic_face_movement_dir_offset;
+                       (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001))
+       {
+               m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI
+                               + m_prop.automatic_face_movement_dir_offset;
                updateNodePos();
        }
 }
 
 void GenericCAO::updateTexturePos()
 {
-       if(m_spritenode){
+       if(m_spritenode)
+       {
                scene::ICameraSceneNode* camera =
                                m_spritenode->getSceneManager()->getActiveCamera();
                if(!camera)
@@ -1226,7 +1272,8 @@ void GenericCAO::updateTexturePos()
                        else if(cam_to_entity.Y < -0.75)
                                col += 4;
                        else{
-                               float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.;
+                               float mob_dir =
+                                               atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.;
                                float dir = mob_dir - m_yaw;
                                dir = wrapDegrees_180(dir);
                                //infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
@@ -1291,7 +1338,8 @@ void GenericCAO::updateTextures(const std::string &mod)
        {
                if(m_prop.visual == "mesh")
                {
-                       for (u32 i = 0; i < m_prop.textures.size() && i < m_animated_meshnode->getMaterialCount(); ++i)
+                       for (u32 i = 0; i < m_prop.textures.size() &&
+                                       i < m_animated_meshnode->getMaterialCount(); ++i)
                        {
                                std::string texturestring = m_prop.textures[i];
                                if(texturestring == "")
@@ -1310,11 +1358,15 @@ void GenericCAO::updateTextures(const std::string &mod)
                                material.setFlag(video::EMF_LIGHTING, false);
                                material.setFlag(video::EMF_BILINEAR_FILTER, false);
 
-                               m_animated_meshnode->getMaterial(i).setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
-                               m_animated_meshnode->getMaterial(i).setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
-                               m_animated_meshnode->getMaterial(i).setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+                               m_animated_meshnode->getMaterial(i)
+                                               .setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+                               m_animated_meshnode->getMaterial(i)
+                                               .setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+                               m_animated_meshnode->getMaterial(i)
+                                               .setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
                        }
-                       for (u32 i = 0; i < m_prop.colors.size() && i < m_animated_meshnode->getMaterialCount(); ++i)
+                       for (u32 i = 0; i < m_prop.colors.size() &&
+                       i < m_animated_meshnode->getMaterialCount(); ++i)
                        {
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
@@ -1436,7 +1488,10 @@ void GenericCAO::updateBonePosition()
                return;
 
        m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
-       for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
+       for(std::map<std::string,
+                       core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin();
+                       ii != m_bone_position.end(); ++ii)
+       {
                std::string bone_name = (*ii).first;
                v3f bone_pos = (*ii).second.X;
                v3f bone_rot = (*ii).second.Y;
@@ -1451,8 +1506,14 @@ void GenericCAO::updateBonePosition()
        
 void GenericCAO::updateAttachments()
 {
-       m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer();
-       m_is_visible = !m_attached_to_local; // Objects attached to the local player should always be hidden
+
+       // localplayer itself can't be attached to localplayer
+       if (!m_is_local_player)
+       {
+               m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer();
+               // Objects attached to the local player should always be hidden
+               m_is_visible = !m_attached_to_local;
+       }
 
        if(getParent() == NULL || m_attached_to_local) // Detach or don't attach
        {
@@ -1503,12 +1564,17 @@ void GenericCAO::updateAttachments()
 
                scene::IBoneSceneNode *parent_bone = NULL;
                if(parent_animated_mesh && m_attachment_bone != "")
-                       parent_bone = parent_animated_mesh->getJointNode(m_attachment_bone.c_str());
-
-               // The spaghetti code below makes sure attaching works if either the parent or child is a spritenode, meshnode, or animatedmeshnode
+               {
+                       parent_bone =
+                                       parent_animated_mesh->getJointNode(m_attachment_bone.c_str());
+               }
+               // The spaghetti code below makes sure attaching works if either the
+               // parent or child is a spritenode, meshnode, or animatedmeshnode
                // TODO: Perhaps use polymorphism here to save code duplication
-               if(m_meshnode){
-                       if(parent_bone){
+               if(m_meshnode)
+               {
+                       if(parent_bone)
+                       {
                                m_meshnode->setParent(parent_bone);
                                m_meshnode->setPosition(m_attachment_position);
                                m_meshnode->setRotation(m_attachment_rotation);
@@ -1516,19 +1582,20 @@ void GenericCAO::updateAttachments()
                        }
                        else
                        {
-                               if(parent_mesh){
+                               if(parent_mesh)
+                               {
                                        m_meshnode->setParent(parent_mesh);
                                        m_meshnode->setPosition(m_attachment_position);
                                        m_meshnode->setRotation(m_attachment_rotation);
                                        m_meshnode->updateAbsolutePosition();
                                }
-                               else if(parent_animated_mesh){
+                               else if(parent_animated_mesh) {
                                        m_meshnode->setParent(parent_animated_mesh);
                                        m_meshnode->setPosition(m_attachment_position);
                                        m_meshnode->setRotation(m_attachment_rotation);
                                        m_meshnode->updateAbsolutePosition();
                                }
-                               else if(parent_sprite){
+                               else if(parent_sprite) {
                                        m_meshnode->setParent(parent_sprite);
                                        m_meshnode->setPosition(m_attachment_position);
                                        m_meshnode->setRotation(m_attachment_rotation);
@@ -1536,8 +1603,10 @@ void GenericCAO::updateAttachments()
                                }
                        }
                }
-               if(m_animated_meshnode){
-                       if(parent_bone){
+               if(m_animated_meshnode)
+               {
+                       if(parent_bone)
+                       {
                                m_animated_meshnode->setParent(parent_bone);
                                m_animated_meshnode->setPosition(m_attachment_position);
                                m_animated_meshnode->setRotation(m_attachment_rotation);
@@ -1545,19 +1614,18 @@ void GenericCAO::updateAttachments()
                        }
                        else
                        {
-                               if(parent_mesh){
+                               if(parent_mesh)
+                               {
                                        m_animated_meshnode->setParent(parent_mesh);
                                        m_animated_meshnode->setPosition(m_attachment_position);
                                        m_animated_meshnode->setRotation(m_attachment_rotation);
                                        m_animated_meshnode->updateAbsolutePosition();
-                               }
-                               else if(parent_animated_mesh){
+                               } else if(parent_animated_mesh) {
                                        m_animated_meshnode->setParent(parent_animated_mesh);
                                        m_animated_meshnode->setPosition(m_attachment_position);
                                        m_animated_meshnode->setRotation(m_attachment_rotation);
                                        m_animated_meshnode->updateAbsolutePosition();
-                               }
-                               else if(parent_sprite){
+                               } else if(parent_sprite) {
                                        m_animated_meshnode->setParent(parent_sprite);
                                        m_animated_meshnode->setPosition(m_attachment_position);
                                        m_animated_meshnode->setRotation(m_attachment_rotation);
@@ -1565,28 +1633,29 @@ void GenericCAO::updateAttachments()
                                }
                        }
                }
-               if(m_spritenode){
-                       if(parent_bone){
+               if(m_spritenode)
+               {
+                       if(parent_bone)
+                       {
                                m_spritenode->setParent(parent_bone);
                                m_spritenode->setPosition(m_attachment_position);
                                m_spritenode->setRotation(m_attachment_rotation);
                                m_spritenode->updateAbsolutePosition();
-                       }
-                       else
-                       {
-                               if(parent_mesh){
+                       } else {
+                               if(parent_mesh)
+                               {
                                        m_spritenode->setParent(parent_mesh);
                                        m_spritenode->setPosition(m_attachment_position);
                                        m_spritenode->setRotation(m_attachment_rotation);
                                        m_spritenode->updateAbsolutePosition();
                                }
-                               else if(parent_animated_mesh){
+                               else if(parent_animated_mesh) {
                                        m_spritenode->setParent(parent_animated_mesh);
                                        m_spritenode->setPosition(m_attachment_position);
                                        m_spritenode->setRotation(m_attachment_rotation);
                                        m_spritenode->updateAbsolutePosition();
                                }
-                               else if(parent_sprite){
+                               else if(parent_sprite) {
                                        m_spritenode->setParent(parent_sprite);
                                        m_spritenode->setPosition(m_attachment_position);
                                        m_spritenode->setRotation(m_attachment_rotation);
@@ -1649,7 +1718,8 @@ void GenericCAO::processMessage(const std::string &data)
                if(getParent() != NULL) // Just in case
                        return;
 
-               if(do_interpolate){
+               if(do_interpolate)
+               {
                        if(!m_prop.physical)
                                pos_translator.update(m_position, is_end_position, update_interval);
                } else {
@@ -1657,13 +1727,11 @@ void GenericCAO::processMessage(const std::string &data)
                }
                updateNodePos();
        }
-       else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD)
-       {
+       else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) {
                std::string mod = deSerializeString(is);
                updateTextures(mod);
        }
-       else if(cmd == GENERIC_CMD_SET_SPRITE)
-       {
+       else if(cmd == GENERIC_CMD_SET_SPRITE) {
                v2s16 p = readV2S16(is);
                int num_frames = readU16(is);
                float framelength = readF1000(is);
@@ -1676,8 +1744,7 @@ void GenericCAO::processMessage(const std::string &data)
 
                updateTexturePos();
        }
-       else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE)
-       {
+       else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) {
                float override_speed = readF1000(is);
                float override_jump = readF1000(is);
                float override_gravity = readF1000(is);
@@ -1696,8 +1763,7 @@ void GenericCAO::processMessage(const std::string &data)
                        player->physics_override_sneak_glitch = sneak_glitch;
                }
        }
-       else if(cmd == GENERIC_CMD_SET_ANIMATION)
-       {
+       else if(cmd == GENERIC_CMD_SET_ANIMATION) {
                // TODO: change frames send as v2s32 value
                v2f range = readV2F1000(is);
                if (!m_is_local_player) {
@@ -1707,7 +1773,8 @@ void GenericCAO::processMessage(const std::string &data)
                        updateAnimation();
                } else {
                        LocalPlayer *player = m_env->getLocalPlayer();
-                       if(player->last_animation == NO_ANIM) {
+                       if(player->last_animation == NO_ANIM)
+                       {
                                m_animation_range = v2s32((s32)range.X, (s32)range.Y);
                                m_animation_speed = readF1000(is);
                                m_animation_blend = readF1000(is);
@@ -1715,7 +1782,8 @@ void GenericCAO::processMessage(const std::string &data)
                        // update animation only if local animations present
                        // and received animation is unknown (except idle animation)
                        bool is_known = false;
-                       for (int i = 1;i<4;i++) {
+                       for (int i = 1;i<4;i++)
+                       {
                                if(m_animation_range.Y == player->local_animations[i].Y)
                                        is_known = true;
                        }
@@ -1726,8 +1794,7 @@ void GenericCAO::processMessage(const std::string &data)
                        }
                }
        }
-       else if(cmd == GENERIC_CMD_SET_BONE_POSITION)
-       {
+       else if(cmd == GENERIC_CMD_SET_BONE_POSITION) {
                std::string bone = deSerializeString(is);
                v3f position = readV3F1000(is);
                v3f rotation = readV3F1000(is);
@@ -1735,8 +1802,7 @@ void GenericCAO::processMessage(const std::string &data)
 
                updateBonePosition();
        }
-       else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
-       {
+       else if(cmd == GENERIC_CMD_SET_ATTACHMENT) {
                // If an entry already exists for this object, delete it first to avoid duplicates
                for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
                {
@@ -1753,8 +1819,7 @@ void GenericCAO::processMessage(const std::string &data)
 
                updateAttachments();
        }
-       else if(cmd == GENERIC_CMD_PUNCHED)
-       {
+       else if(cmd == GENERIC_CMD_PUNCHED) {
                /*s16 damage =*/ readS16(is);
                s16 result_hp = readS16(is);
 
@@ -1763,8 +1828,10 @@ void GenericCAO::processMessage(const std::string &data)
 
                m_hp = result_hp;
 
-               if (damage > 0) {
-                       if (m_hp <= 0) {
+               if (damage > 0)
+               {
+                       if (m_hp <= 0)
+                       {
                                // TODO: Execute defined fast response
                                // As there is no definition, make a smoke puff
                                ClientSimpleObject *simple = createSmokePuff(
@@ -1781,11 +1848,11 @@ void GenericCAO::processMessage(const std::string &data)
                        }
                }
        }
-       else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS)
-       {
+       else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) {
                m_armor_groups.clear();
                int armor_groups_size = readU16(is);
-               for(int i=0; i<armor_groups_size; i++){
+               for(int i=0; i<armor_groups_size; i++)
+               {
                        std::string name = deSerializeString(is);
                        int rating = readS16(is);
                        m_armor_groups[name] = rating;
@@ -1807,7 +1874,8 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
 
        if(result.did_punch && result.damage != 0)
        {
-               if(result.damage < m_hp){
+               if(result.damage < m_hp)
+               {
                        m_hp -= result.damage;
                } else {
                        m_hp = 0;
@@ -1835,7 +1903,8 @@ std::string GenericCAO::debugInfoText()
        os<<"GenericCAO hp="<<m_hp<<"\n";
        os<<"armor={";
        for(ItemGroupList::const_iterator i = m_armor_groups.begin();
-                       i != m_armor_groups.end(); i++){
+                       i != m_armor_groups.end(); i++)
+       {
                os<<i->first<<"="<<i->second<<", ";
        }
        os<<"}";
index 945804ba82ac4c5b5c09905299cb1ff9dcd36a5d..6ba7057bdfc55413d1c4c60481fecafe24be416a 100644 (file)
@@ -56,8 +56,8 @@ void set_default_settings(Settings *settings)
        settings->setDefault("keymap_camera_mode", "KEY_F7");
        settings->setDefault("keymap_increase_viewing_range_min", "+");
        settings->setDefault("keymap_decrease_viewing_range_min", "-");
-       settings->setDefault("anaglyph", "false");
-       settings->setDefault("anaglyph_strength", "0.1");
+       settings->setDefault("3d_mode", "none");
+       settings->setDefault("3d_paralax_strength", "0.025");
        settings->setDefault("aux1_descends", "false");
        settings->setDefault("doubletap_jump", "false");
        settings->setDefault("always_fly_fast", "true");
diff --git a/src/drawscene.cpp b/src/drawscene.cpp
new file mode 100644 (file)
index 0000000..4911015
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+Minetest
+Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser 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 "drawscene.h"
+#include "main.h" // for g_settings
+#include "settings.h"
+#include "clouds.h"
+#include "util/timetaker.h"
+
+typedef enum {
+       LEFT = -1,
+       RIGHT = 1,
+       EYECOUNT = 2
+} paralax_sign;
+
+void draw_selectionbox(video::IVideoDriver* driver, Hud& hud,
+               std::vector<aabb3f>& hilightboxes, bool show_hud)
+{
+       if (!show_hud)
+               return;
+
+       video::SMaterial oldmaterial = driver->getMaterial2D();
+       video::SMaterial m;
+       m.Thickness = 3;
+       m.Lighting = false;
+       driver->setMaterial(m);
+       hud.drawSelectionBoxes(hilightboxes);
+       driver->setMaterial(oldmaterial);
+}
+
+void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud,
+               std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               scene::ISceneManager* smgr, bool draw_wield_tool, Client& client,
+               gui::IGUIEnvironment* guienv )
+{
+
+       /* preserve old setup*/
+       irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
+       irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
+
+       irr::core::matrix4 startMatrix =
+                       camera.getCameraNode()->getAbsoluteTransformation();
+       irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
+                       - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+                       + camera.getCameraNode()->getAbsolutePosition();
+
+
+       //Left eye...
+       irr::core::vector3df leftEye;
+       irr::core::matrix4 leftMove;
+       leftMove.setTranslation(
+                       irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
+                                       0.0f, 0.0f));
+       leftEye = (startMatrix * leftMove).getTranslation();
+
+       //clear the depth buffer, and color
+       driver->beginScene( true, true, irr::video::SColor(0, 200, 200, 255));
+       driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
+       driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
+       driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
+                       + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
+                       + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
+       camera.getCameraNode()->setPosition(leftEye);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+       if (show_hud)
+       {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if (draw_wield_tool)
+                       camera.drawWieldedTool(&leftMove);
+       }
+
+       guienv->drawAll();
+
+       //Right eye...
+       irr::core::vector3df rightEye;
+       irr::core::matrix4 rightMove;
+       rightMove.setTranslation(
+                       irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
+                                       0.0f, 0.0f));
+       rightEye = (startMatrix * rightMove).getTranslation();
+
+       //clear the depth buffer
+       driver->clearZBuffer();
+       driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN
+                       + irr::video::ECP_BLUE;
+       driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
+       driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
+                       + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
+                       + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
+       camera.getCameraNode()->setPosition(rightEye);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+       if (show_hud)
+       {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if (draw_wield_tool)
+                       camera.drawWieldedTool(&rightMove);
+       }
+
+       guienv->drawAll();
+
+       driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL;
+       driver->getOverrideMaterial().EnableFlags = 0;
+       driver->getOverrideMaterial().EnablePasses = 0;
+       camera.getCameraNode()->setPosition(oldPosition);
+       camera.getCameraNode()->setTarget(oldTarget);
+}
+
+void init_texture(video::IVideoDriver* driver, const v2u32& screensize,
+               video::ITexture** texture)
+{
+       static v2u32 last_screensize = v2u32(0,0);
+
+       if (( *texture == NULL ) || (screensize != last_screensize))
+       {
+               if (*texture != NULL)
+               {
+                       driver->removeTexture(*texture);
+               }
+               *texture = driver->addRenderTargetTexture(
+                               core::dimension2d<u32>(screensize.X, screensize.Y));
+               last_screensize = screensize;
+       }
+}
+
+video::ITexture* draw_image(const v2u32& screensize,
+               paralax_sign psign, const irr::core::matrix4& startMatrix,
+               const irr::core::vector3df& focusPoint, bool show_hud,
+               video::IVideoDriver* driver, Camera& camera, scene::ISceneManager* smgr,
+               Hud& hud, std::vector<aabb3f>& hilightboxes,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
+               video::SColor skycolor )
+{
+       static video::ITexture* images[2] = { NULL, NULL };
+
+       video::ITexture* image = NULL;
+
+       if (psign == RIGHT)
+       {
+               init_texture(driver, screensize, &images[1]);
+               image = images[1];
+       } else {
+               init_texture(driver, screensize, &images[0]);
+               image = images[0];
+       }
+
+       driver->setRenderTarget(image, true, true,
+                       irr::video::SColor(255,
+                                       skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
+
+       irr::core::vector3df eye_pos;
+       irr::core::matrix4 movement;
+       movement.setTranslation(
+                       irr::core::vector3df((int) psign *
+                                       g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
+       eye_pos = (startMatrix * movement).getTranslation();
+
+       //clear the depth buffer
+       driver->clearZBuffer();
+       camera.getCameraNode()->setPosition(eye_pos);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+
+       if (show_hud)
+       {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if (draw_wield_tool)
+                       camera.drawWieldedTool(&movement);
+       }
+
+       guienv->drawAll();
+
+       /* switch back to real renderer */
+       driver->setRenderTarget(0, true, true,
+                       irr::video::SColor(0,
+                                       skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
+
+       return image;
+}
+
+video::ITexture*  draw_hud(video::IVideoDriver* driver, const v2u32& screensize,
+               bool show_hud, Hud& hud, Client& client, bool draw_crosshair,
+               video::SColor skycolor, gui::IGUIEnvironment* guienv, Camera& camera )
+{
+       static video::ITexture* image = NULL;
+       init_texture(driver, screensize, &image);
+       driver->setRenderTarget(image, true, true,
+                       irr::video::SColor(255,0,0,0));
+
+       if (show_hud)
+       {
+               if (draw_crosshair)
+                       hud.drawCrosshair();
+               hud.drawHotbar(client.getPlayerItem());
+               hud.drawLuaElements(camera.getOffset());
+
+               guienv->drawAll();
+       }
+
+       driver->setRenderTarget(0, true, true,
+                       irr::video::SColor(0,
+                                       skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
+
+       return image;
+}
+
+void draw_interlaced_3d_mode(Camera& camera, bool show_hud,
+               Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               scene::ISceneManager* smgr, const v2u32& screensize,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
+               video::SColor skycolor )
+{
+       /* save current info */
+       irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
+       irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
+       irr::core::matrix4 startMatrix =
+                       camera.getCameraNode()->getAbsoluteTransformation();
+       irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
+                       - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+                       + camera.getCameraNode()->getAbsolutePosition();
+
+       /* create left view */
+       video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
+                       focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
+                       draw_wield_tool, client, guienv, skycolor);
+
+       //Right eye...
+       irr::core::vector3df rightEye;
+       irr::core::matrix4 rightMove;
+       rightMove.setTranslation(
+                       irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
+                                       0.0f, 0.0f));
+       rightEye = (startMatrix * rightMove).getTranslation();
+
+       //clear the depth buffer
+       driver->clearZBuffer();
+       camera.getCameraNode()->setPosition(rightEye);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+
+       if (show_hud)
+       {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if(draw_wield_tool)
+                       camera.drawWieldedTool(&rightMove);
+       }
+       guienv->drawAll();
+
+       for (unsigned int i = 0; i < screensize.Y; i+=2 ) {
+               driver->draw2DImage(left_image, irr::core::position2d<s32>(0, screensize.Y-i),
+                               irr::core::rect<s32>(0, i,screensize.X, i+1), 0,
+                               irr::video::SColor(255, 255, 255, 255),
+                               false);
+       }
+
+       /* cleanup */
+       camera.getCameraNode()->setPosition(oldPosition);
+       camera.getCameraNode()->setTarget(oldTarget);
+}
+
+void draw_sidebyside_3d_mode(Camera& camera, bool show_hud,
+               Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               scene::ISceneManager* smgr, const v2u32& screensize,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
+               video::SColor skycolor )
+{
+       /* save current info */
+       irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
+       irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
+       irr::core::matrix4 startMatrix =
+                       camera.getCameraNode()->getAbsoluteTransformation();
+       irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
+                       - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+                       + camera.getCameraNode()->getAbsolutePosition();
+
+       /* create left view */
+       video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
+                       focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
+                       draw_wield_tool, client, guienv, skycolor);
+
+       /* create right view */
+       video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
+                       focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
+                       draw_wield_tool, client, guienv, skycolor);
+
+       /* create hud overlay */
+       video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
+                       false, skycolor, guienv, camera );
+       driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
+       //makeColorKeyTexture mirrors texture so we do it twice to get it right again
+       driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
+
+       driver->draw2DImage(left_image,
+                       irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
+
+       driver->draw2DImage(hudtexture,
+                       irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
+
+       driver->draw2DImage(right_image,
+                       irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
+
+       driver->draw2DImage(hudtexture,
+                       irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
+
+       left_image = NULL;
+       right_image = NULL;
+
+       /* cleanup */
+       camera.getCameraNode()->setPosition(oldPosition);
+       camera.getCameraNode()->setTarget(oldTarget);
+}
+
+void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
+               Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               scene::ISceneManager* smgr, const v2u32& screensize,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
+               video::SColor skycolor )
+{
+       /* save current info */
+       irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
+       irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
+       irr::core::matrix4 startMatrix =
+                       camera.getCameraNode()->getAbsoluteTransformation();
+       irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
+                       - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+                       + camera.getCameraNode()->getAbsolutePosition();
+
+       /* create left view */
+       video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
+                       focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
+                       draw_wield_tool, client, guienv, skycolor);
+
+       /* create right view */
+       video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
+                       focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
+                       draw_wield_tool, client, guienv, skycolor);
+
+       /* create hud overlay */
+       video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
+                       false, skycolor, guienv, camera );
+       driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
+       //makeColorKeyTexture mirrors texture so we do it twice to get it right again
+       driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
+
+       driver->draw2DImage(left_image,
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
+
+       driver->draw2DImage(hudtexture,
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
+
+       driver->draw2DImage(right_image,
+                       irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
+
+       driver->draw2DImage(hudtexture,
+                       irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
+                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
+
+       left_image = NULL;
+       right_image = NULL;
+
+       /* cleanup */
+       camera.getCameraNode()->setPosition(oldPosition);
+       camera.getCameraNode()->setTarget(oldTarget);
+}
+
+void draw_plain(Camera& camera, bool show_hud, Hud& hud,
+               std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv)
+{
+
+       draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+       if(draw_wield_tool)
+               camera.drawWieldedTool();
+}
+
+void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr,
+               Camera& camera, Client& client, LocalPlayer* player, Hud& hud,
+               gui::IGUIEnvironment* guienv, std::vector<aabb3f> hilightboxes,
+               const v2u32& screensize, video::SColor skycolor, bool show_hud)
+{
+       //TODO check if usefull
+       u32 scenetime = 0;
+       {
+               TimeTaker timer("smgr");
+
+               bool draw_wield_tool = (show_hud &&
+                               (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
+                               camera.getCameraMode() < CAMERA_MODE_THIRD );
+
+               bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
+                               (camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT));
+
+               std::string draw_mode = g_settings->get("3d_mode");
+
+               smgr->drawAll();
+
+               if (draw_mode == "anaglyph")
+               {
+                       draw_anaglyph_3d_mode(camera, show_hud, hud, hilightboxes, driver,
+                                       smgr, draw_wield_tool, client, guienv);
+                       draw_crosshair = false;
+               }
+               else if (draw_mode == "interlaced")
+               {
+                       draw_interlaced_3d_mode(camera, show_hud, hud, hilightboxes, driver,
+                                       smgr, screensize, draw_wield_tool, client, guienv, skycolor);
+                       draw_crosshair = false;
+               }
+               else if (draw_mode == "sidebyside")
+               {
+                       draw_sidebyside_3d_mode(camera, show_hud, hud, hilightboxes, driver,
+                                       smgr, screensize, draw_wield_tool, client, guienv, skycolor);
+                       show_hud = false;
+               }
+               else if (draw_mode == "topbottom")
+               {
+                       draw_top_bottom_3d_mode(camera, show_hud, hud, hilightboxes, driver,
+                                       smgr, screensize, draw_wield_tool, client, guienv, skycolor);
+                       show_hud = false;
+               }
+               else {
+                       draw_plain(camera, show_hud, hud, hilightboxes, driver,
+                                       draw_wield_tool, client, guienv);
+               }
+               //TODO how to make those 3d too
+               if (show_hud)
+               {
+                       if (draw_crosshair)
+                               hud.drawCrosshair();
+                       hud.drawHotbar(client.getPlayerItem());
+                       hud.drawLuaElements(camera.getOffset());
+
+                       guienv->drawAll();
+               }
+
+               scenetime = timer.stop(true);
+       }
+
+}
+
+/*
+       Draws a screen with a single text on it.
+       Text will be removed when the screen is drawn the next time.
+       Additionally, a progressbar can be drawn when percent is set between 0 and 100.
+*/
+/*gui::IGUIStaticText **/
+void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
+               gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime,
+               int percent, bool clouds )
+{
+       video::IVideoDriver* driver = device->getVideoDriver();
+       v2u32 screensize = driver->getScreenSize();
+       const wchar_t *loadingtext = text.c_str();
+       core::vector2d<u32> textsize_u = font->getDimension(loadingtext);
+       core::vector2d<s32> textsize(textsize_u.X,textsize_u.Y);
+       core::vector2d<s32> center(screensize.X/2, screensize.Y/2);
+       core::rect<s32> textrect(center - textsize/2, center + textsize/2);
+
+       gui::IGUIStaticText *guitext = guienv->addStaticText(
+                       loadingtext, textrect, false, false);
+       guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
+
+       bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
+       if (cloud_menu_background)
+       {
+               g_menuclouds->step(dtime*3);
+               g_menuclouds->render();
+               driver->beginScene(true, true, video::SColor(255,140,186,250));
+               g_menucloudsmgr->drawAll();
+       }
+       else
+               driver->beginScene(true, true, video::SColor(255,0,0,0));
+
+       if (percent >= 0 && percent <= 100) // draw progress bar
+       {
+               core::vector2d<s32> barsize(256,32);
+               core::rect<s32> barrect(center-barsize/2, center+barsize/2);
+               driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border
+               driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect<s32> (
+                               barrect.UpperLeftCorner+1,
+                               barrect.LowerRightCorner-1), NULL); // black inside the bar
+               driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> (
+                               barrect.UpperLeftCorner+1,
+                               core::vector2d<s32>(
+                                       barrect.LowerRightCorner.X-(barsize.X-1)+percent*(barsize.X-2)/100,
+                                       barrect.LowerRightCorner.Y-1)), NULL); // the actual progress
+       }
+       guienv->drawAll();
+       driver->endScene();
+
+       guitext->remove();
+
+       //return guitext;
+}
diff --git a/src/drawscene.h b/src/drawscene.h
new file mode 100644 (file)
index 0000000..0625525
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Minetest
+Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser 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 DRAWSCENE_H_
+#define DRAWSCENE_H_
+
+#include "camera.h"
+#include "hud.h"
+#include "irrlichttypes_extrabloated.h"
+
+
+void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
+               gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime=0,
+               int percent=0, bool clouds=true);
+
+void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr,
+               Camera& camera, Client& client, LocalPlayer* player, Hud& hud,
+               gui::IGUIEnvironment* guienv, std::vector<aabb3f> hilightboxes,
+               const v2u32& screensize, video::SColor skycolor, bool show_hud);
+
+#endif /* DRAWSCENE_H_ */
index 0b28c7d176fdd3adbdfa2b669ee38e6ea6402213..d7dfa11b12acad1a6789d4aa71f7dcbbaf062088 100644 (file)
@@ -68,6 +68,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <list>
 #include "util/directiontables.h"
 #include "util/pointedthing.h"
+#include "drawscene.h"
+#include "content_cao.h"
 
 /*
        Text input system
@@ -418,59 +420,6 @@ PointedThing getPointedThing(Client *client, v3f player_position,
        return result;
 }
 
-/*
-       Draws a screen with a single text on it.
-       Text will be removed when the screen is drawn the next time.
-       Additionally, a progressbar can be drawn when percent is set between 0 and 100.
-*/
-/*gui::IGUIStaticText **/
-void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
-               gui::IGUIFont* font, float dtime=0 ,int percent=0, bool clouds=true)
-{
-       video::IVideoDriver* driver = device->getVideoDriver();
-       v2u32 screensize = driver->getScreenSize();
-       const wchar_t *loadingtext = text.c_str();
-       core::vector2d<u32> textsize_u = font->getDimension(loadingtext);
-       core::vector2d<s32> textsize(textsize_u.X,textsize_u.Y);
-       core::vector2d<s32> center(screensize.X/2, screensize.Y/2);
-       core::rect<s32> textrect(center - textsize/2, center + textsize/2);
-
-       gui::IGUIStaticText *guitext = guienv->addStaticText(
-                       loadingtext, textrect, false, false);
-       guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
-
-       bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
-       if (cloud_menu_background)
-       {
-               g_menuclouds->step(dtime*3);
-               g_menuclouds->render();
-               driver->beginScene(true, true, video::SColor(255,140,186,250));
-               g_menucloudsmgr->drawAll();
-       }
-       else
-               driver->beginScene(true, true, video::SColor(255,0,0,0));
-       if (percent >= 0 && percent <= 100) // draw progress bar
-       {
-               core::vector2d<s32> barsize(256,32);
-               core::rect<s32> barrect(center-barsize/2, center+barsize/2);
-               driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border
-               driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect<s32> (
-                               barrect.UpperLeftCorner+1,
-                               barrect.LowerRightCorner-1), NULL); // black inside the bar
-               driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> (
-                               barrect.UpperLeftCorner+1,
-                               core::vector2d<s32>(
-                                       barrect.LowerRightCorner.X-(barsize.X-1)+percent*(barsize.X-2)/100,
-                                       barrect.LowerRightCorner.Y-1)), NULL); // the actual progress
-       }
-       guienv->drawAll();
-       driver->endScene();
-       
-       guitext->remove();
-       
-       //return guitext;
-}
-
 /* Profiler display */
 
 void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
@@ -1113,7 +1062,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 
        {
                wchar_t* text = wgettext("Loading...");
-               draw_load_screen(text, device, font,0,0);
+               draw_load_screen(text, device, guienv, font, 0, 0);
                delete[] text;
        }
        
@@ -1173,7 +1122,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 
        if(address == ""){
                wchar_t* text = wgettext("Creating server....");
-               draw_load_screen(text, device, font,0,25);
+               draw_load_screen(text, device, guienv, font, 0, 25);
                delete[] text;
                infostream<<"Creating server"<<std::endl;
 
@@ -1216,7 +1165,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 
        {
                wchar_t* text = wgettext("Creating client...");
-               draw_load_screen(text, device, font,0,50);
+               draw_load_screen(text, device, guienv, font, 0, 50);
                delete[] text;
        }
        infostream<<"Creating client"<<std::endl;
@@ -1225,7 +1174,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
        
        {
                wchar_t* text = wgettext("Resolving address...");
-               draw_load_screen(text, device, font,0,75);
+               draw_load_screen(text, device, guienv, font, 0, 75);
                delete[] text;
        }
        Address connect_address(0,0,0,0, port);
@@ -1324,7 +1273,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                        // Display status
                        {
                                wchar_t* text = wgettext("Connecting to server...");
-                               draw_load_screen(text, device, font, dtime, 100);
+                               draw_load_screen(text, device, guienv, font, dtime, 100);
                                delete[] text;
                        }
                        
@@ -1428,14 +1377,14 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                        {
                                wchar_t* text = wgettext("Item definitions...");
                                progress = 0;
-                               draw_load_screen(text, device, font, dtime, progress);
+                               draw_load_screen(text, device, guienv, font, dtime, progress);
                                delete[] text;
                        }
                        else if (!client.nodedefReceived())
                        {
                                wchar_t* text = wgettext("Node definitions...");
                                progress = 25;
-                               draw_load_screen(text, device, font, dtime, progress);
+                               draw_load_screen(text, device, guienv, font, dtime, progress);
                                delete[] text;
                        }
                        else
@@ -1457,7 +1406,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                                        message << " ( " << cur << cur_unit << " )";
                                }
                                progress = 50+client.mediaReceiveProgress()*50+0.5;
-                               draw_load_screen(narrow_to_wide(message.str().c_str()), device, font, dtime, progress);
+                               draw_load_screen(narrow_to_wide(message.str().c_str()), device,
+                                               guienv, font, dtime, progress);
                        }
                        
                        // On some computers framerate doesn't seem to be
@@ -1513,8 +1463,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
        f32 camera_yaw = 0; // "right/left"
        f32 camera_pitch = 0; // "up/down"
 
-       int current_camera_mode = CAMERA_MODE_FIRST; // start in first-person view
-
        /*
                Clouds
        */
@@ -1530,7 +1478,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
        */
 
        Sky *sky = NULL;
-       sky = new Sky(smgr->getRootSceneNode(), smgr, -1, client.getEnv().getLocalPlayer());
+       sky = new Sky(smgr->getRootSceneNode(), smgr, -1);
 
        scene::ISceneNode* skybox = NULL;
        
@@ -1605,7 +1553,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
        */
        u32 drawtime = 0;
        u32 beginscenetime = 0;
-       u32 scenetime = 0;
        u32 endscenetime = 0;
        
        float recent_turn_speed = 0.0;
@@ -2281,7 +2228,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                        else{
                                s32 dx = input->getMousePos().X - (driver->getScreenSize().Width/2);
                                s32 dy = input->getMousePos().Y - (driver->getScreenSize().Height/2);
-                               if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT) {
+                               if(invert_mouse || camera.getCameraMode() == CAMERA_MODE_THIRD_FRONT) {
                                        dy = -dy;
                                }
                                //infostream<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
@@ -2668,19 +2615,20 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                float tool_reload_ratio = time_from_last_punch / full_punch_interval;
 
                if(input->wasKeyDown(getKeySetting("keymap_camera_mode"))) {
+                       camera.toggleCameraMode();
+                       GenericCAO* playercao = player->getCAO();
 
-                       if (current_camera_mode == CAMERA_MODE_FIRST)
-                               current_camera_mode = CAMERA_MODE_THIRD;
-                       else if (current_camera_mode == CAMERA_MODE_THIRD)
-                               current_camera_mode = CAMERA_MODE_THIRD_FRONT;
-                       else
-                               current_camera_mode = CAMERA_MODE_FIRST;
-
+                       assert( playercao != NULL );
+                       if (camera.getCameraMode() > CAMERA_MODE_FIRST) {
+                               playercao->setVisible(true);
+                       }
+                       else {
+                               playercao->setVisible(false);
+                       }
                }
-               player->camera_mode = current_camera_mode;
                tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
                camera.update(player, dtime, busytime, tool_reload_ratio,
-                               current_camera_mode, client.getEnv());
+                               client.getEnv());
                camera.step(dtime);
 
                v3f player_position = player->getPosition();
@@ -2736,7 +2684,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                                camera_position + camera_direction * BS * (d+1));
 
                // prevent player pointing anything in front-view
-               if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
+               if (camera.getCameraMode() == CAMERA_MODE_THIRD_FRONT)
                        shootline = core::line3d<f32>(0,0,0,0,0,0);
 
                ClientActiveObject *selected_object = NULL;
@@ -3148,7 +3096,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                                        + time_of_day * todsm;
                        
                sky->update(time_of_day_smooth, time_brightness, direct_brightness,
-                               sunlight_seen);
+                               sunlight_seen,camera.getCameraMode(), player->getYaw(),
+                               player->getPitch());
                
                video::SColor bgcolor = sky->getBgColor();
                video::SColor skycolor = sky->getSkyColor();
@@ -3417,141 +3366,22 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                /*
                        Drawing begins
                */
-
                TimeTaker tt_draw("mainloop: draw");
-               
                {
                        TimeTaker timer("beginScene");
-                       //driver->beginScene(false, true, bgcolor);
-                       //driver->beginScene(true, true, bgcolor);
                        driver->beginScene(true, true, skycolor);
                        beginscenetime = timer.stop(true);
                }
-               
-               //timer3.stop();
-       
-               //infostream<<"smgr->drawAll()"<<std::endl;
-               {
-                       TimeTaker timer("smgr");
-                       smgr->drawAll();
-                       
-                       if(g_settings->getBool("anaglyph"))
-                       {
-                               irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
-                               irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
-
-                               irr::core::matrix4 startMatrix   = camera.getCameraNode()->getAbsoluteTransformation();
-
-                               irr::core::vector3df focusPoint  = (camera.getCameraNode()->getTarget() -
-                                                                                camera.getCameraNode()->getAbsolutePosition()).setLength(1) +
-                                                                                camera.getCameraNode()->getAbsolutePosition() ;
-
-                               //Left eye...
-                               irr::core::vector3df leftEye;
-                               irr::core::matrix4   leftMove;
-
-                               leftMove.setTranslation( irr::core::vector3df(-g_settings->getFloat("anaglyph_strength"),0.0f,0.0f) );
-                               leftEye=(startMatrix*leftMove).getTranslation();
-
-                               //clear the depth buffer, and color
-                               driver->beginScene( true, true, irr::video::SColor(0,200,200,255) );
-
-                               driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
-                               driver->getOverrideMaterial().EnableFlags  = irr::video::EMF_COLOR_MASK;
-                               driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX +
-                                                                                                                        irr::scene::ESNRP_SOLID +
-                                                                                                                        irr::scene::ESNRP_TRANSPARENT +
-                                                                                                                        irr::scene::ESNRP_TRANSPARENT_EFFECT +
-                                                                                                                        irr::scene::ESNRP_SHADOW;
-
-                               camera.getCameraNode()->setPosition( leftEye );
-                               camera.getCameraNode()->setTarget( focusPoint );
-
-                               smgr->drawAll(); // 'smgr->drawAll();' may go here
-
-                               driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-                               if (show_hud)
-                                       hud.drawSelectionBoxes(hilightboxes);
-
-
-                               //Right eye...
-                               irr::core::vector3df rightEye;
-                               irr::core::matrix4   rightMove;
-
-                               rightMove.setTranslation( irr::core::vector3df(g_settings->getFloat("anaglyph_strength"),0.0f,0.0f) );
-                               rightEye=(startMatrix*rightMove).getTranslation();
-
-                               //clear the depth buffer
-                               driver->clearZBuffer();
 
-                               driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN + irr::video::ECP_BLUE;
-                               driver->getOverrideMaterial().EnableFlags  = irr::video::EMF_COLOR_MASK;
-                               driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX +
-                                                                                                                        irr::scene::ESNRP_SOLID +
-                                                                                                                        irr::scene::ESNRP_TRANSPARENT +
-                                                                                                                        irr::scene::ESNRP_TRANSPARENT_EFFECT +
-                                                                                                                        irr::scene::ESNRP_SHADOW;
-
-                               camera.getCameraNode()->setPosition( rightEye );
-                               camera.getCameraNode()->setTarget( focusPoint );
-
-                               smgr->drawAll(); // 'smgr->drawAll();' may go here
-
-                               driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-                               if (show_hud)
-                                       hud.drawSelectionBoxes(hilightboxes);
-
-
-                               //driver->endScene();
-
-                               driver->getOverrideMaterial().Material.ColorMask=irr::video::ECP_ALL;
-                               driver->getOverrideMaterial().EnableFlags=0;
-                               driver->getOverrideMaterial().EnablePasses=0;
-
-                               camera.getCameraNode()->setPosition( oldPosition );
-                               camera.getCameraNode()->setTarget( oldTarget );
-                       }
-
-                       scenetime = timer.stop(true);
-               }
                
-               {
-               //TimeTaker timer9("auxiliary drawings");
-               // 0ms
-               
-               //timer9.stop();
-               //TimeTaker //timer10("//timer10");
-               
-               video::SMaterial m;
-               //m.Thickness = 10;
-               m.Thickness = 3;
-               m.Lighting = false;
-               driver->setMaterial(m);
-
-               driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-               if((!g_settings->getBool("anaglyph")) && (show_hud))
-               {
-                       hud.drawSelectionBoxes(hilightboxes);
-               }
-
-               /*
-                       Wielded tool
-               */
-               if(show_hud &&
-                       (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
-                       current_camera_mode < CAMERA_MODE_THIRD)
-               {
-                       // Warning: This clears the Z buffer.
-                       camera.drawWieldedTool();
-               }
+               draw_scene(driver, smgr, camera, client, player, hud, guienv,
+                               hilightboxes, screensize, skycolor, show_hud);
 
                /*
                        Post effects
                */
                {
-                       client.getEnv().getClientMap().renderPostFx();
+                       client.getEnv().getClientMap().renderPostFx(camera.getCameraMode());
                }
 
                /*
@@ -3562,26 +3392,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                        graph.draw(10, screensize.Y - 10, driver, font);
                }
 
-               /*
-                       Draw crosshair
-               */
-               if (show_hud)
-                       hud.drawCrosshair();
-                       
-               } // timer
-
-               //timer10.stop();
-               //TimeTaker //timer11("//timer11");
-
-
-               /*
-                       Draw hotbar
-               */
-               if (show_hud)
-               {
-                       hud.drawHotbar(client.getPlayerItem());
-               }
-
                /*
                        Damage flash
                */
@@ -3605,18 +3415,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                                player->hurt_tilt_strength = 0;
                }
 
-               /*
-                       Draw lua hud items
-               */
-               if (show_hud)
-                       hud.drawLuaElements(camera.getOffset());
-
-               /*
-                       Draw gui
-               */
-               // 0-1ms
-               guienv->drawAll();
-
                /*
                        End scene
                */
@@ -3659,7 +3457,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
        {
                /*gui::IGUIStaticText *gui_shuttingdowntext = */
                wchar_t* text = wgettext("Shutting down stuff...");
-               draw_load_screen(text, device, font, 0, -1, false);
+               draw_load_screen(text, device, guienv, font, 0, -1, false);
                delete[] text;
                /*driver->beginScene(true, true, video::SColor(255,0,0,0));
                guienv->drawAll();
@@ -3728,5 +3526,3 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
                << driver-> getMaterialRendererCount ()
                << " (note: irrlicht doesn't support removing renderers)"<< std::endl;
 }
-
-
index 7b601ec87e98cfe98290e8c30418e234b98d2a3d..6d0fc8a8998de2bc892e3dab27523b08ceb9cedf 100644 (file)
@@ -435,10 +435,6 @@ void Hud::drawHotbar(u16 playeritem) {
 
 
 void Hud::drawCrosshair() {
-       if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) ||
-                       (player->camera_mode == CAMERA_MODE_THIRD_FRONT)) {
-               return;
-       }
                
        if (use_crosshair_image) {
                video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
index a7a105fc5c8e09791bdc7cffd7cfa1d2d8bf825f..1a238cb4787789c0f45d25cecf5abd015765517d 100644 (file)
@@ -43,7 +43,6 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef):
        last_pitch(0),
        last_yaw(0),
        last_keyPressed(0),
-       camera_mode(0),
        eye_offset_first(v3f(0,0,0)),
        eye_offset_third(v3f(0,0,0)),
        last_animation(NO_ANIM),
@@ -54,7 +53,8 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef):
        m_old_node_below(32767,32767,32767),
        m_old_node_below_type("air"),
        m_need_to_get_new_sneak_node(true),
-       m_can_jump(false)
+       m_can_jump(false),
+       m_cao(NULL)
 {
        // Initialize hp to 0, so that no hearts will be shown if server
        // doesn't support health points
@@ -505,7 +505,7 @@ void LocalPlayer::applyControl(float dtime)
        if(control.jump)
        {
                if(free_move)
-               {                       
+               {
                        if(g_settings->getBool("aux1_descends") || g_settings->getBool("always_fly_fast"))
                        {
                                if(fast_move)
index 38e7a4cd9e739ba0955dde3fbaf60f20dffe36ac..bfe476b70360068e64e74c1d26066ce963819048 100644 (file)
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <list>
 
 class Environment;
-
+class GenericCAO;
 class ClientActiveObject;
 
 enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM};  // no local animation, walking, digging, both
@@ -62,7 +62,6 @@ public:
        unsigned int last_keyPressed;
 
        float camera_impact;
-       int camera_mode;
        v3f eye_offset_first;
        v3f eye_offset_third;
 
@@ -72,6 +71,15 @@ public:
        std::string hotbar_image;
        std::string hotbar_selected_image;
 
+       GenericCAO* getCAO() const {
+               return m_cao;
+       }
+
+       void setCAO(GenericCAO* toset) {
+               assert( m_cao == NULL );
+               m_cao = toset;
+       }
+
 private:
        // This is used for determining the sneaking range
        v3s16 m_sneak_node;
@@ -84,6 +92,8 @@ private:
        // Whether recalculation of the sneak node is needed
        bool m_need_to_get_new_sneak_node;
        bool m_can_jump;
+
+       GenericCAO* m_cao;
 };
 
 #endif
index be7798407e959e6f3fcfe104ba1b6aac4e75d217..17d8d46ce4dc788acdb6bc63b064ceadff25f5b8 100644 (file)
@@ -13,7 +13,7 @@
 #include "camera.h" // CameraModes
 
 //! constructor
-Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player):
+Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id):
                scene::ISceneNode(parent, mgr, id),
                m_visible(true),
                m_fallback_bg_color(255,255,255,255),
@@ -22,8 +22,7 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlay
                m_cloud_brightness(0.5),
                m_bgcolor_bright_f(1,1,1,1),
                m_skycolor_bright_f(1,1,1,1),
-               m_cloudcolor_bright_f(1,1,1,1),
-               m_player(player)
+               m_cloudcolor_bright_f(1,1,1,1)
 {
        setAutomaticCulling(scene::EAC_OFF);
        Box.MaxEdge.set(0,0,0);
@@ -66,14 +65,14 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlay
                m_materials[3].setTexture(0, m_sun_texture);
                m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
                if (m_sun_tonemap)
-                       m_materials[3].Lighting = true;         
+                       m_materials[3].Lighting = true;
        }
        if (m_moon_texture){
                m_materials[4] = mat;
                m_materials[4].setTexture(0, m_moon_texture);
                m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
                if (m_moon_tonemap)
-                       m_materials[4].Lighting = true;         
+                       m_materials[4].Lighting = true;
        }
 
        for(u32 i=0; i<SKY_STAR_COUNT; i++){
@@ -161,20 +160,20 @@ void Sky::render()
                video::SColor mooncolor2 = mooncolor2_f.toSColor();
 
                // Calculate offset normalized to the X dimension of a 512x1 px tonemap
-               float offset=(1.0-fabs(sin((m_time_of_day - 0.5)*irr::core::PI)))*511;       
+               float offset=(1.0-fabs(sin((m_time_of_day - 0.5)*irr::core::PI)))*511;
 
                if (m_sun_tonemap){
                        u8 * texels = (u8 *)m_sun_tonemap->lock();
                        video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4);
                        video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue());
-                       m_sun_tonemap->unlock();                                
+                       m_sun_tonemap->unlock();
                        m_materials[3].EmissiveColor = texel_color;
                }
                if (m_moon_tonemap){
                        u8 * texels = (u8 *)m_moon_tonemap->lock();
                        video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4);
                        video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue());
-                       m_moon_tonemap->unlock();                               
+                       m_moon_tonemap->unlock();
                        m_materials[4].EmissiveColor = texel_color;
                }
 
@@ -263,7 +262,7 @@ void Sky::render()
                }
 
                // Draw sun
-               if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85){     
+               if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85){
                        if (!m_sun_texture){
                                driver->setMaterial(m_materials[1]);
                                float d = sunsize * 1.7;
@@ -411,7 +410,7 @@ void Sky::render()
                                        vertices[i].Pos.rotateXZBy(-90);
                                        vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
                                }
-                               driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);            
+                               driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
                        }
                }
 
@@ -485,7 +484,8 @@ void Sky::render()
 }
 
 void Sky::update(float time_of_day, float time_brightness,
-               float direct_brightness, bool sunlight_seen)
+               float direct_brightness, bool sunlight_seen,
+               CameraMode cam_mode, float yaw, float pitch)
 {
        // Stabilize initial brightness and color values by flooding updates
        if(m_first_update){
@@ -496,7 +496,7 @@ void Sky::update(float time_of_day, float time_brightness,
                m_first_update = false;
                for(u32 i=0; i<100; i++){
                        update(time_of_day, time_brightness, direct_brightness,
-                                       sunlight_seen);
+                                       sunlight_seen, cam_mode, yaw, pitch);
                }
                return;
        }
@@ -580,16 +580,16 @@ void Sky::update(float time_of_day, float time_brightness,
                {
                        // calculate hemisphere value from yaw, (inverted in third person front view)
                        s8 dir_factor = 1;
-                       if (m_player->camera_mode > CAMERA_MODE_THIRD)
+                       if (cam_mode > CAMERA_MODE_THIRD)
                                dir_factor = -1;
-                       f32 pointcolor_blend = wrapDegrees_0_360(m_player->getYaw()*dir_factor + 90);
+                       f32 pointcolor_blend = wrapDegrees_0_360( yaw*dir_factor + 90);
                        if (pointcolor_blend > 180)
                                pointcolor_blend = 360 - pointcolor_blend;
                        pointcolor_blend /= 180;
                        // bound view angle to determine where transition starts and ends
                        pointcolor_blend = rangelim(1 - pointcolor_blend * 1.375, 0, 1 / 1.375) * 1.375;
                        // combine the colors when looking up or down, otherwise turning looks weird
-                       pointcolor_blend += (0.5 - pointcolor_blend) * (1 - MYMIN((90 - std::abs(m_player->getPitch())) / 90 * 1.5, 1));
+                       pointcolor_blend += (0.5 - pointcolor_blend) * (1 - MYMIN((90 - std::abs(pitch)) / 90 * 1.5, 1));
                        // invert direction to match where the sun and moon are rising
                        if (m_time_of_day > 0.5)
                                pointcolor_blend = 1 - pointcolor_blend;
index aaa2faf57cd23d6611bebb95e4561c220bd0660b..d7dabedb80640315520de95c81ffa92d1ac1dc5d 100644 (file)
--- a/src/sky.h
+++ b/src/sky.h
@@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "irrlichttypes_extrabloated.h"
 #include <ISceneNode.h>
-#include "localplayer.h"
+#include "camera.h"
 
 #ifndef SKY_HEADER
 #define SKY_HEADER
@@ -32,7 +32,7 @@ class Sky : public scene::ISceneNode
 {
 public:
        //! constructor
-       Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player);
+       Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id);
 
        virtual void OnRegisterSceneNode();
 
@@ -50,7 +50,8 @@ public:
        { return SKY_MATERIAL_COUNT; }
 
        void update(float m_time_of_day, float time_brightness,
-                       float direct_brightness, bool sunlight_seen);
+                       float direct_brightness, bool sunlight_seen, CameraMode cam_mode,
+                       float yaw, float pitch);
        
        float getBrightness(){ return m_brightness; }
 
@@ -126,7 +127,6 @@ private:
        video::SColorf m_cloudcolor_f;
        v3f m_stars[SKY_STAR_COUNT];
        video::S3DVertex m_star_vertices[SKY_STAR_COUNT*4];
-       LocalPlayer* m_player;
        video::ITexture* m_sun_texture;
        video::ITexture* m_moon_texture;
        video::ITexture* m_sun_tonemap;