/* Minetest-c55 Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU 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 "camera.h" #include "debug.h" #include "main.h" // for g_settings #include "map.h" #include "player.h" #include "utility.h" #include Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_smgr(smgr), m_playernode(NULL), m_cameranode(NULL), m_draw_control(draw_control), m_viewing_range_min(5.0), m_viewing_range_max(5.0), m_camera_position(0,0,0), m_camera_direction(0,0,0), m_aspect(1.0), m_fov_x(1.0), m_fov_y(1.0), m_wanted_frametime(0.0), m_added_frametime(0), m_added_frames(0), m_range_old(0), m_frametime_old(0), m_frametime_counter(0), m_time_per_range(30. / 50), // a sane default of 30ms per 50 nodes of range m_view_bobbing_anim(0), m_view_bobbing_anim_left(0) { dstream<<__FUNCTION_NAME<addEmptySceneNode(smgr->getRootSceneNode()); m_cameranode = smgr->addCameraSceneNode(m_playernode); updateSettings(); } Camera::~Camera() { } void Camera::step(f32 dtime) { } void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) { if (m_playernode == NULL || m_cameranode == NULL) return; // FOV and and aspect ratio m_aspect = (f32)screensize.X / (f32) screensize.Y; m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y)); m_cameranode->setAspectRatio(m_aspect); m_cameranode->setFOV(m_fov_y); // Just so big a value that everything rendered is visible // Some more allowance that m_viewing_range_max * BS because of active objects etc. m_cameranode->setFarValue(m_viewing_range_max * BS * 10); m_camera_position = player->getEyePosition(); // TODO bobbing m_cameranode->setPosition(m_camera_position); m_camera_direction = v3f(0,0,1); m_camera_direction.rotateYZBy(player->getPitch()); m_camera_direction.rotateXZBy(player->getYaw()); // *100.0 helps in large map coordinates m_cameranode->setTarget(m_camera_position + m_camera_direction * 100.0); // Render distance feedback loop updateViewingRange(frametime); // Check if view bobbing is active v3f speed = player->getSpeed(); f32 epsilon = BS / 1000.0; if (speed.X * speed.X + speed.Z * speed.Z > epsilon*epsilon && speed.Y < epsilon && g_settings.getBool("view_bobbing") == true && g_settings.getBool("free_move") == false) { // The player seems to be walking on solid ground. // Enable view bobbing. //dstream << "View bobbing active" << std::endl; } else { //dstream << "View bobbing inactive" << std::endl; } } void Camera::updateViewingRange(f32 frametime_in) { if (m_draw_control.range_all) return; m_added_frametime += frametime_in; m_added_frames += 1; // Actually this counter kind of sucks because frametime is busytime m_frametime_counter -= frametime_in; if (m_frametime_counter > 0) return; m_frametime_counter = 0.2; dstream<<__FUNCTION_NAME <<": Collected "<