]> git.lizzy.rs Git - minetest.git/blobdiff - src/camera.cpp
Use numeric indices and raw table access with LUA_REGISTRYINDEX
[minetest.git] / src / camera.cpp
index db53cd5d9a5d94707eef0c6ab90d1b6c5c639115..0c6d03e4e5034e66d9126323642a23655e27743a 100644 (file)
@@ -20,14 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "camera.h"
 #include "debug.h"
 #include "client.h"
-#include "main.h" // for g_settings
 #include "map.h"
-#include "clientmap.h" // MapDrawControl
+#include "clientmap.h"     // MapDrawControl
 #include "player.h"
 #include <cmath>
 #include "settings.h"
 #include "wieldmesh.h"
-#include "noise.h" // easeCurve
+#include "noise.h"         // easeCurve
 #include "gamedef.h"
 #include "sound.h"
 #include "event.h"
@@ -93,10 +92,9 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
        // all other 3D scene nodes and before the GUI.
        m_wieldmgr = smgr->createNewSceneManager();
        m_wieldmgr->addCameraSceneNode();
-       m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, true);
+       m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, false);
        m_wieldnode->setItem(ItemStack(), m_gamedef);
        m_wieldnode->drop(); // m_wieldmgr grabbed it
-       m_wieldlightnode = m_wieldmgr->addLightSceneNode(NULL, v3f(0.0, 50.0, 0.0));
 
        /* TODO: Add a callback function so these can be updated when a setting
         *       changes.  At this point in time it doesn't matter (e.g. /set
@@ -109,8 +107,6 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
         */
        m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount");
        m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount");
-       m_cache_viewing_range_min   = g_settings->getFloat("viewing_range_nodes_min");
-       m_cache_viewing_range_max   = g_settings->getFloat("viewing_range_nodes_max");
        m_cache_wanted_fps          = g_settings->getFloat("wanted_fps");
        m_cache_fov                 = g_settings->getFloat("fov");
        m_cache_view_bobbing        = g_settings->getBool("view_bobbing");
@@ -121,34 +117,22 @@ Camera::~Camera()
        m_wieldmgr->drop();
 }
 
-bool Camera::successfullyCreated(std::wstring& error_message)
+bool Camera::successfullyCreated(std::string &error_message)
 {
-       if (m_playernode == NULL)
-       {
-               error_message = L"Failed to create the player scene node";
-               return false;
-       }
-       if (m_headnode == NULL)
-       {
-               error_message = L"Failed to create the head scene node";
-               return false;
-       }
-       if (m_cameranode == NULL)
-       {
-               error_message = L"Failed to create the camera scene node";
-               return false;
-       }
-       if (m_wieldmgr == NULL)
-       {
-               error_message = L"Failed to create the wielded item scene manager";
-               return false;
-       }
-       if (m_wieldnode == NULL)
-       {
-               error_message = L"Failed to create the wielded item scene node";
-               return false;
+       if (!m_playernode) {
+               error_message = "Failed to create the player scene node";
+       } else if (!m_headnode) {
+               error_message = "Failed to create the head scene node";
+       } else if (!m_cameranode) {
+               error_message = "Failed to create the camera scene node";
+       } else if (!m_wieldmgr) {
+               error_message = "Failed to create the wielded item scene manager";
+       } else if (!m_wieldnode) {
+               error_message = "Failed to create the wielded item scene node";
+       } else {
+               error_message.clear();
        }
-       return true;
+       return error_message.empty();
 }
 
 // Returns the fractional part of x
@@ -177,55 +161,37 @@ void Camera::step(f32 dtime)
        {
                //f32 offset = dtime * m_view_bobbing_speed * 0.035;
                f32 offset = dtime * m_view_bobbing_speed * 0.030;
-               if (m_view_bobbing_state == 2)
-               {
-#if 0
+               if (m_view_bobbing_state == 2) {
                        // Animation is getting turned off
-                       if (m_view_bobbing_anim < 0.5)
+                       if (m_view_bobbing_anim < 0.25) {
                                m_view_bobbing_anim -= offset;
-                       else
+                       } else if (m_view_bobbing_anim > 0.75) {
                                m_view_bobbing_anim += offset;
-                       if (m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1)
-                       {
-                               m_view_bobbing_anim = 0;
-                               m_view_bobbing_state = 0;
                        }
-#endif
-#if 1
-                       // Animation is getting turned off
-                       if(m_view_bobbing_anim < 0.25)
-                       {
-                               m_view_bobbing_anim -= offset;
-                       } else if(m_view_bobbing_anim > 0.75) {
-                               m_view_bobbing_anim += offset;
-                       }
-                       if(m_view_bobbing_anim < 0.5)
-                       {
+
+                       if (m_view_bobbing_anim < 0.5) {
                                m_view_bobbing_anim += offset;
-                               if(m_view_bobbing_anim > 0.5)
+                               if (m_view_bobbing_anim > 0.5)
                                        m_view_bobbing_anim = 0.5;
                        } else {
                                m_view_bobbing_anim -= offset;
-                               if(m_view_bobbing_anim < 0.5)
+                               if (m_view_bobbing_anim < 0.5)
                                        m_view_bobbing_anim = 0.5;
                        }
-                       if(m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1 ||
-                                       fabs(m_view_bobbing_anim - 0.5) < 0.01)
-                       {
+
+                       if (m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1 ||
+                                       fabs(m_view_bobbing_anim - 0.5) < 0.01) {
                                m_view_bobbing_anim = 0;
                                m_view_bobbing_state = 0;
                        }
-#endif
                }
-               else
-               {
+               else {
                        float was = m_view_bobbing_anim;
                        m_view_bobbing_anim = my_modf(m_view_bobbing_anim + offset);
                        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);
                        }
@@ -272,7 +238,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
        {
                f32 oldy = old_player_position.Y;
                f32 newy = player_position.Y;
-               f32 t = exp(-10*frametime);
+               f32 t = exp(-23*frametime);
                player_position.Y = oldy * t + newy * (1-t);
        }
 
@@ -309,7 +275,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                PlayerEyeOffset += player->eye_offset_first;
        else
                PlayerEyeOffset += player->eye_offset_third;
-       
+
        // Set head node transformation
        m_headnode->setPosition(PlayerEyeOffset+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0));
        m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength));
@@ -371,7 +337,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
 
        // Seperate camera position for calculation
        v3f my_cp = m_camera_position;
-       
+
        // Reposition the camera for third person view
        if (m_camera_mode > CAMERA_MODE_FIRST)
        {
@@ -382,7 +348,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
 
                // Calculate new position
                bool abort = false;
-               for (int i = BS; i <= BS*2; i++)
+               for (int i = BS; i <= BS*2.75; 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;
@@ -415,7 +381,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                        (((s16)(my_cp.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP);
        m_camera_offset.Z += CAMERA_OFFSET_STEP*
                        (((s16)(my_cp.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP);
-       
+
        // Set camera node transformation
        m_cameranode->setPosition(my_cp-intToFloat(m_camera_offset, BS));
        m_cameranode->setUpVector(abs_cam_up);
@@ -468,7 +434,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
                wield_position.X -= 50 * sin(pow(digfrac, 0.8f) * M_PI);
                wield_position.Y += 24 * sin(digfrac * 1.8 * M_PI);
                wield_position.Z += 25 * 0.5;
-       
+
                // Euler angles are PURE EVIL, so why not use quaternions?
                core::quaternion quat_begin(wield_rotation * core::DEGTORAD);
                core::quaternion quat_end(v3f(80, 30, 100) * core::DEGTORAD);
@@ -484,24 +450,24 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
        m_wieldnode->setPosition(wield_position);
        m_wieldnode->setRotation(wield_rotation);
 
-       // Shine light upon the wield mesh
-       video::SColor black(255,0,0,0);
-       m_wieldmgr->setAmbientLight(player->light_color.getInterpolated(black, 0.7));
-       m_wieldlightnode->getLightData().DiffuseColor = player->light_color.getInterpolated(black, 0.3);
-       m_wieldlightnode->setPosition(v3f(30+5*sin(2*player->getYaw()*M_PI/180), -50, 0));
+       m_wieldnode->setColor(player->light_color);
 
        // Render distance feedback loop
        updateViewingRange(frametime, busytime);
 
-       // If the player seems to be walking on solid ground,
+       // If the player is walking, swimming, or climbing,
        // view bobbing is enabled and free_move is off,
        // start (or continue) the view bobbing animation.
        v3f speed = player->getSpeed();
-       if ((hypot(speed.X, speed.Z) > BS) &&
-               (player->touching_ground) &&
-               (m_cache_view_bobbing == true) &&
-               (g_settings->getBool("free_move") == false ||
-                               !m_gamedef->checkLocalPrivilege("fly")))
+       const bool movement_XZ = hypot(speed.X, speed.Z) > BS;
+       const bool movement_Y = abs(speed.Y) > BS;
+
+       const bool walking = movement_XZ && player->touching_ground;
+       const bool swimming = (movement_XZ || player->swimming_vertical) && player->in_liquid;
+       const bool climbing = movement_Y && player->is_climbing;
+       if ((walking || swimming || climbing) &&
+                       m_cache_view_bobbing &&
+                       (!g_settings->getBool("free_move") || !m_gamedef->checkLocalPrivilege("fly")))
        {
                // Start animation
                m_view_bobbing_state = 1;
@@ -539,12 +505,12 @@ void Camera::updateViewingRange(f32 frametime_in, f32 busytime_in)
                        <<std::endl;*/
 
        // Get current viewing range and FPS settings
-       f32 viewing_range_min = m_cache_viewing_range_min;
+       f32 viewing_range_min = g_settings->getFloat("viewing_range_nodes_min");
        viewing_range_min = MYMAX(15.0, viewing_range_min);
 
-       f32 viewing_range_max = m_cache_viewing_range_max;
+       f32 viewing_range_max = g_settings->getFloat("viewing_range_nodes_max");
        viewing_range_max = MYMAX(viewing_range_min, viewing_range_max);
-       
+
        // Immediately apply hard limits
        if(m_draw_control.wanted_range < viewing_range_min)
                m_draw_control.wanted_range = viewing_range_min;
@@ -641,7 +607,7 @@ void Camera::updateViewingRange(f32 frametime_in, f32 busytime_in)
        }
 
        new_range += wanted_range_change;
-       
+
        //f32 new_range_unclamped = new_range;
        new_range = MYMAX(new_range, viewing_range_min);
        new_range = MYMIN(new_range, viewing_range_max);