+ // Get player position
+ // Smooth the movement when walking up stairs
+ v3f old_player_position = m_playernode->getPosition();
+ v3f player_position = player->getPosition();
+ //if(player->touching_ground && player_position.Y > old_player_position.Y)
+ if(player->touching_ground &&
+ player_position.Y > old_player_position.Y)
+ {
+ f32 oldy = old_player_position.Y;
+ f32 newy = player_position.Y;
+ f32 t = exp(-23*frametime);
+ player_position.Y = oldy * t + newy * (1-t);
+ }
+
+ // Set player node transformation
+ m_playernode->setPosition(player_position);
+ m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0));
+ m_playernode->updateAbsolutePosition();
+
+ //Get camera tilt timer (hurt animation)
+ float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75);
+
+ // Set head node transformation
+ m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength,0));
+ m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength));
+ m_headnode->updateAbsolutePosition();
+
+ // Compute relative camera position and target
+ v3f rel_cam_pos = v3f(0,0,0);
+ v3f rel_cam_target = v3f(0,0,1);
+ v3f rel_cam_up = v3f(0,1,0);
+
+ if (m_view_bobbing_anim != 0)
+ {
+ f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
+ f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
+
+ #if 1
+ f32 bobknob = 1.2;
+ f32 bobtmp = sin(pow(bobfrac, bobknob) * M_PI);
+ //f32 bobtmp2 = cos(pow(bobfrac, bobknob) * M_PI);
+
+ v3f bobvec = v3f(
+ 0.3 * bobdir * sin(bobfrac * M_PI),
+ -0.28 * bobtmp * bobtmp,
+ 0.);
+
+ //rel_cam_pos += 0.2 * bobvec;
+ //rel_cam_target += 0.03 * bobvec;
+ //rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * M_PI);
+ float f = 1.0;
+ f *= g_settings->getFloat("view_bobbing_amount");
+ rel_cam_pos += bobvec * f;
+ //rel_cam_target += 0.995 * bobvec * f;
+ rel_cam_target += bobvec * f;
+ rel_cam_target.Z -= 0.005 * bobvec.Z * f;
+ //rel_cam_target.X -= 0.005 * bobvec.X * f;
+ //rel_cam_target.Y -= 0.005 * bobvec.Y * f;
+ rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * M_PI * f);
+ #else
+ f32 angle_deg = 1 * bobdir * sin(bobfrac * M_PI);
+ f32 angle_rad = angle_deg * M_PI / 180;
+ f32 r = 0.05;
+ v3f off = v3f(
+ r * sin(angle_rad),
+ r * (cos(angle_rad) - 1),
+ 0);
+ rel_cam_pos += off;
+ //rel_cam_target += off;
+ rel_cam_up.rotateXYBy(angle_deg);
+ #endif
+
+ }
+
+ // Compute absolute camera position and target
+ m_headnode->getAbsoluteTransformation().transformVect(m_camera_position, rel_cam_pos);
+ m_headnode->getAbsoluteTransformation().rotateVect(m_camera_direction, rel_cam_target - rel_cam_pos);
+
+ v3f abs_cam_up;
+ m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
+
+ // Set camera node transformation
+ m_cameranode->setPosition(m_camera_position);
+ m_cameranode->setUpVector(abs_cam_up);
+ // *100.0 helps in large map coordinates
+ m_cameranode->setTarget(m_camera_position + 100 * m_camera_direction);
+
+ // Get FOV setting
+ f32 fov_degrees = g_settings->getFloat("fov");
+ fov_degrees = MYMAX(fov_degrees, 10.0);
+ fov_degrees = MYMIN(fov_degrees, 170.0);