From c0b35fa429c68b49b2d6a5124aff6dcc31400b63 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Wed, 7 Sep 2011 19:21:28 +0200 Subject: Removed unused camera_position and camera_direction fields from Client. Moved ClientEnvironment::drawPostFx to ClientMap::renderPostFx -- this will make the camera management classes easier to write, as ClientMap already knows the camera position but ClientEnvironment doesn't and has to be told about it. This also eliminates the need for Client::getEnv(). Made the post effect color a content feature defined in content_mapnode.h. --- src/map.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/map.h') diff --git a/src/map.h b/src/map.h index e0b67eb6e..5bea4a137 100644 --- a/src/map.h +++ b/src/map.h @@ -552,6 +552,8 @@ public: void renderMap(video::IVideoDriver* driver, s32 pass); + void renderPostFx(); + /* Methods for setting temporary modifications to nodes for drawing. -- cgit v1.2.3 From baf7da9d4a7fc0566840b159903999d76d99a228 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 8 Sep 2011 01:08:47 +0200 Subject: Collected and moved existing camera infrastructure from game.cpp to camera.cpp and camera.h. Introduced configuration settings 'fov' which chooses the camera's (vertical) field of view and 'view_bobbing' which currently does nothing. Other code refactored to not expect the FOV to be a build time constant. --- src/CMakeLists.txt | 1 + src/camera.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ src/camera.h | 141 ++++++++++++++++++++++++++++ src/client.cpp | 14 +-- src/client.h | 4 +- src/constants.h | 3 - src/defaultsettings.cpp | 2 + src/game.cpp | 205 +++++----------------------------------- src/map.cpp | 7 +- src/map.h | 4 +- src/server.cpp | 2 +- src/utility.cpp | 7 +- src/utility.h | 4 +- 13 files changed, 428 insertions(+), 209 deletions(-) create mode 100644 src/camera.cpp create mode 100644 src/camera.h (limited to 'src/map.h') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c3b0960a..80ee0fc64 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,6 +142,7 @@ set(minetest_SRCS mapblock_mesh.cpp farmesh.cpp keycode.cpp + camera.cpp clouds.cpp clientobject.cpp guiMainMenu.cpp diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 000000000..30df439ed --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,243 @@ +/* +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 "< + +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. +*/ + +#ifndef CAMERA_HEADER +#define CAMERA_HEADER + +#include "common_irrlicht.h" +#include "utility.h" + +class LocalPlayer; +class MapDrawControl; + +/* + Client camera class, manages the player and camera scene nodes, the viewing distance + and performs view bobbing etc. +*/ +class Camera +{ +public: + Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control); + ~Camera(); + + // Get player scene node. + // This node is positioned at the player's torso (without any view bobbing), + // as given by Player::m_position, Player::m_pitch and Player::m_yaw. + // Things like wielded tools should be positioned relative to this node. + inline scene::ISceneNode* getPlayerNode() const + { + return m_playernode; + } + + // Get camera scene node. + // The camera node is a child of the player node. + // It has the eye transformation and view bobbing applied. + inline scene::ICameraSceneNode* getCameraNode() const + { + return m_cameranode; + } + + // Get the camera position (in absolute scene coordinates). + // This has view bobbing applied. + inline v3f getPosition() const + { + return m_camera_position; + } + + // Get the camera direction (in absolute camera coordinates). + // This has view bobbing applied. + inline v3f getDirection() const + { + return m_camera_direction; + } + + // Horizontal field of view + inline f32 getFovX() const + { + return m_fov_x; + } + + // Vertical field of view + inline f32 getFovY() const + { + return m_fov_y; + } + + // Get maximum of getFovX() and getFovY() + inline f32 getFovMax() const + { + return MYMAX(m_fov_x, m_fov_y); + } + + // Step the camera: updates the viewing range and view bobbing. + void step(f32 dtime); + + // Update the camera from the local player's position. + // frametime is used to adjust the viewing range. + void update(LocalPlayer* player, f32 frametime, v2u32 screensize); + + // Render distance feedback loop + void updateViewingRange(f32 frametime_in); + + // Update settings from g_settings + void updateSettings(); + +private: + // Scene manager and nodes + scene::ISceneManager* m_smgr; + scene::ISceneNode* m_playernode; + scene::ICameraSceneNode* m_cameranode; + + // draw control + MapDrawControl& m_draw_control; + + // viewing_range_min_nodes setting + f32 m_viewing_range_min; + // viewing_range_max_nodes setting + f32 m_viewing_range_max; + + // Absolute camera position + v3f m_camera_position; + // Absolute camera direction + v3f m_camera_direction; + + // Field of view and aspect ratio stuff + f32 m_aspect; + f32 m_fov_x; + f32 m_fov_y; + + // Stuff for viewing range calculations + f32 m_wanted_frametime; + f32 m_added_frametime; + s16 m_added_frames; + f32 m_range_old; + f32 m_frametime_old; + f32 m_frametime_counter; + f32 m_time_per_range; + + // View bobbing animation frame (0 <= m_view_bobbing < 0x10000) + u32 m_view_bobbing_anim; + // Number of frames to continue the view bobbing animation. + u32 m_view_bobbing_anim_left; +}; + +#endif + diff --git a/src/client.cpp b/src/client.cpp index df792d116..81dedd144 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1978,9 +1978,9 @@ void Client::addNode(v3s16 p, MapNode n) } } -void Client::updateCamera(v3f pos, v3f dir) +void Client::updateCamera(v3f pos, v3f dir, f32 fov) { - m_env.getClientMap().updateCamera(pos, dir); + m_env.getClientMap().updateCamera(pos, dir, fov); } void Client::renderPostFx() @@ -2004,16 +2004,6 @@ LocalPlayer* Client::getLocalPlayer() return m_env.getLocalPlayer(); } -v3f Client::getPlayerPosition(v3f *eye_position) -{ - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - LocalPlayer *player = m_env.getLocalPlayer(); - assert(player != NULL); - if (eye_position) - *eye_position = player->getEyePosition(); - return player->getPosition(); -} - void Client::setPlayerControl(PlayerControl &control) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index 9c942ff9a..930987c02 100644 --- a/src/client.h +++ b/src/client.h @@ -199,7 +199,7 @@ public: // locks envlock void addNode(v3s16 p, MapNode n); - void updateCamera(v3f pos, v3f dir); + void updateCamera(v3f pos, v3f dir, f32 fov); void renderPostFx(); @@ -210,8 +210,6 @@ public: LocalPlayer* getLocalPlayer(); - v3f getPlayerPosition(v3f *eye_position); - void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); diff --git a/src/constants.h b/src/constants.h index 1af5f1f1b..9ba10b51c 100644 --- a/src/constants.h +++ b/src/constants.h @@ -44,9 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PI 3.14159 -// This is the same as in minecraft and everything else -#define FOV_ANGLE (PI/2.5) - // The absolute working limit is (2^15 - viewing_range). // I really don't want to make every algorithm to check if it's // going near the limit or not, so this is lower. diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 1e17f2f3a..163ed0884 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -59,6 +59,8 @@ void set_default_settings() g_settings.setDefault("random_input", "false"); g_settings.setDefault("client_unload_unused_data_timeout", "600"); g_settings.setDefault("enable_fog", "true"); + g_settings.setDefault("fov", "72"); + g_settings.setDefault("view_bobbing", "true"); g_settings.setDefault("new_style_water", "false"); g_settings.setDefault("new_style_leaves", "true"); g_settings.setDefault("smooth_lighting", "true"); diff --git a/src/game.cpp b/src/game.cpp index afe1ce80f..fc1486b73 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "materials.h" #include "config.h" #include "clouds.h" +#include "camera.h" #include "farmesh.h" #include "mapblock.h" @@ -49,8 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define FIELD_OF_VIEW_TEST 0 -MapDrawControl draw_control; - // Chat data struct ChatLine { @@ -143,144 +142,6 @@ struct TextDestSignNode : public TextDest Client *m_client; }; -/* - Render distance feedback loop -*/ -void updateViewingRange(f32 frametime_in, Client *client) -{ - if(draw_control.range_all == true) - return; - - static f32 added_frametime = 0; - static s16 added_frames = 0; - - added_frametime += frametime_in; - added_frames += 1; - - // Actually this counter kind of sucks because frametime is busytime - static f32 counter = 0; - counter -= frametime_in; - if(counter > 0) - return; - //counter = 0.1; - counter = 0.2; - - /*dstream<<__FUNCTION_NAME - <<": Collected "< range_max) - new_range = range_max; - - /*dstream<<"new_range="<addCameraSceneNode( - 0, // Camera parent - v3f(BS*100, BS*2, BS*100), // Look from - v3f(BS*100+1, BS*2, BS*100), // Look to - -1 // Camera ID - ); - - if(camera == NULL) + Camera camera(smgr, draw_control); + if (camera.getPlayerNode() == NULL) + { + error_message = L"Failed to create the player node"; + return; + } + if (camera.getCameraNode() == NULL) { error_message = L"Failed to create the camera node"; return; } - camera->setFOV(FOV_ANGLE); - - // Just so big a value that everything rendered is visible - camera->setFarValue(100000*BS); - f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" @@ -1168,12 +1023,6 @@ void the_game( // Necessary for device->getTimer()->getTime() device->run(); - /* - Viewing range - */ - - updateViewingRange(busytime, &client); - /* FPS limiter */ @@ -1565,10 +1414,6 @@ void the_game( } } - // Get player position - v3f camera_position; - v3f player_position = client.getPlayerPosition(&camera_position); - //TimeTaker //timer2("//timer2"); /* @@ -1621,25 +1466,25 @@ void the_game( first_loop_after_window_activation = true; } - camera_yaw = wrapDegrees(camera_yaw); - camera_pitch = wrapDegrees(camera_pitch); - - v3f camera_direction = v3f(0,0,1); - camera_direction.rotateYZBy(camera_pitch); - camera_direction.rotateXZBy(camera_yaw); + LocalPlayer* player = client.getLocalPlayer(); + camera.update(player, busytime, screensize); + camera.step(dtime); - camera->setPosition(camera_position); - // *100.0 helps in large map coordinates - camera->setTarget(camera_position + camera_direction * 100.0); + v3f player_position = player->getPosition(); + v3f camera_position = camera.getPosition(); + v3f camera_direction = camera.getDirection(); + f32 camera_fov = camera.getFovMax(); - if(FIELD_OF_VIEW_TEST){ - client.updateCamera(v3f(0,0,0), v3f(0,0,1)); + if(FIELD_OF_VIEW_TEST) + { + client.updateCamera(v3f(0,0,0), v3f(0,0,1), M_PI); } - else{ - //TimeTaker timer("client.updateCamera"); - client.updateCamera(camera_position, camera_direction); + else + { + client.updateCamera(camera_position, + camera_direction, camera_fov); } - + //timer2.stop(); //TimeTaker //timer3("//timer3"); @@ -2010,8 +1855,6 @@ void the_game( Calculate stuff for drawing */ - camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y); - u32 daynight_ratio = client.getDayNightRatio(); u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000); video::SColor bgcolor = video::SColor( diff --git a/src/map.cpp b/src/map.cpp index 6f22498fe..b1908fe2e 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3604,7 +3604,8 @@ ClientMap::ClientMap( m_client(client), m_control(control), m_camera_position(0,0,0), - m_camera_direction(0,0,1) + m_camera_direction(0,0,1), + m_camera_fov(M_PI) { m_camera_mutex.Init(); assert(m_camera_mutex.IsInitialized()); @@ -3713,6 +3714,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) m_camera_mutex.Lock(); v3f camera_position = m_camera_position; v3f camera_direction = m_camera_direction; + f32 camera_fov = m_camera_fov; m_camera_mutex.Unlock(); /* @@ -3805,7 +3807,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) float d = 0.0; if(isBlockInSight(block->getPos(), camera_position, - camera_direction, range, &d) == false) + camera_direction, camera_fov, + range, &d) == false) { continue; } diff --git a/src/map.h b/src/map.h index 5bea4a137..cb649addd 100644 --- a/src/map.h +++ b/src/map.h @@ -518,11 +518,12 @@ public: ISceneNode::drop(); } - void updateCamera(v3f pos, v3f dir) + void updateCamera(v3f pos, v3f dir, f32 fov) { JMutexAutoLock lock(m_camera_mutex); m_camera_position = pos; m_camera_direction = dir; + m_camera_fov = fov; } /* @@ -603,6 +604,7 @@ private: v3f m_camera_position; v3f m_camera_direction; + f32 m_camera_fov; JMutex m_camera_mutex; core::map m_last_drawn_sectors; diff --git a/src/server.cpp b/src/server.cpp index 14d8942cb..fd93d7523 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -584,7 +584,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Don't generate or send if not in sight */ - if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false) + if(isBlockInSight(p, camera_pos, camera_dir, M_PI, 10000*BS) == false) { continue; } diff --git a/src/utility.cpp b/src/utility.cpp index 0721100cb..9c1edc8a9 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -162,8 +162,8 @@ void mysrand(unsigned seed) camera_dir: an unit vector pointing to camera direction range: viewing range */ -bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, - f32 *distance_ptr) +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr) { v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; @@ -211,8 +211,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, cosangle += block_max_radius / dforward; // If block is not in the field of view, skip it - //if(cosangle < cos(FOV_ANGLE/2)) - if(cosangle < cos(FOV_ANGLE/2. * 4./3.)) + if(cosangle < cos(camera_fov / 2)) return false; } diff --git a/src/utility.h b/src/utility.h index ea7c11846..d331bafbb 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1765,8 +1765,8 @@ inline int myrand_range(int min, int max) Miscellaneous functions */ -bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, - f32 *distance_ptr=NULL); +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr=NULL); /* Queue with unique values with fast checking of value existence -- cgit v1.2.3