diff options
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/camera.cpp | 243 | ||||
-rw-r--r-- | src/camera.h | 141 | ||||
-rw-r--r-- | src/client.cpp | 14 | ||||
-rw-r--r-- | src/client.h | 4 | ||||
-rw-r--r-- | src/constants.h | 3 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 2 | ||||
-rw-r--r-- | src/game.cpp | 205 | ||||
-rw-r--r-- | src/map.cpp | 7 | ||||
-rw-r--r-- | src/map.h | 4 | ||||
-rw-r--r-- | src/server.cpp | 2 | ||||
-rw-r--r-- | src/utility.cpp | 7 | ||||
-rw-r--r-- | src/utility.h | 4 |
13 files changed, 428 insertions, 209 deletions
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 <celeron55@gmail.com> + +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 <cmath> + +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<<std::endl; + + m_playernode = smgr->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 "<<m_added_frames<<" frames, total of " + <<m_added_frametime<<"s."<<std::endl; + + dstream<<"m_draw_control.blocks_drawn=" + <<m_draw_control.blocks_drawn + <<", m_draw_control.blocks_would_have_drawn=" + <<m_draw_control.blocks_would_have_drawn + <<std::endl; + + m_draw_control.wanted_min_range = m_viewing_range_min; + m_draw_control.wanted_max_blocks = (1.5*m_draw_control.blocks_would_have_drawn)+1; + if (m_draw_control.wanted_max_blocks < 10) + m_draw_control.wanted_max_blocks = 10; + + f32 block_draw_ratio = 1.0; + if (m_draw_control.blocks_would_have_drawn != 0) + { + block_draw_ratio = (f32)m_draw_control.blocks_drawn + / (f32)m_draw_control.blocks_would_have_drawn; + } + + // Calculate the average frametime in the case that all wanted + // blocks had been drawn + f32 frametime = m_added_frametime / m_added_frames / block_draw_ratio; + + m_added_frametime = 0.0; + m_added_frames = 0; + + f32 wanted_frametime_change = m_wanted_frametime - frametime; + dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl; + + // If needed frametime change is small, just return + if (fabs(wanted_frametime_change) < m_wanted_frametime*0.4) + { + dstream<<"ignoring small wanted_frametime_change"<<std::endl; + return; + } + + f32 range = m_draw_control.wanted_range; + f32 new_range = range; + + f32 d_range = range - m_range_old; + f32 d_frametime = frametime - m_frametime_old; + if (d_range != 0) + { + m_time_per_range = d_frametime / d_range; + } + + // The minimum allowed calculated frametime-range derivative: + // Practically this sets the maximum speed of changing the range. + // The lower this value, the higher the maximum changing speed. + // A low value here results in wobbly range (0.001) + // A high value here results in slow changing range (0.0025) + // SUGG: This could be dynamically adjusted so that when + // the camera is turning, this is lower + //f32 min_time_per_range = 0.0015; + f32 min_time_per_range = 0.0010; + //f32 min_time_per_range = 0.05 / range; + if(m_time_per_range < min_time_per_range) + { + m_time_per_range = min_time_per_range; + dstream<<"m_time_per_range="<<m_time_per_range<<" (min)"<<std::endl; + } + else + { + dstream<<"m_time_per_range="<<m_time_per_range<<std::endl; + } + + f32 wanted_range_change = wanted_frametime_change / m_time_per_range; + // Dampen the change a bit to kill oscillations + //wanted_range_change *= 0.9; + //wanted_range_change *= 0.75; + wanted_range_change *= 0.5; + dstream<<"wanted_range_change="<<wanted_range_change<<std::endl; + + // If needed range change is very small, just return + if(fabs(wanted_range_change) < 0.001) + { + dstream<<"ignoring small wanted_range_change"<<std::endl; + return; + } + + new_range += wanted_range_change; + + f32 new_range_unclamped = new_range; + new_range = MYMAX(new_range, m_viewing_range_min); + new_range = MYMIN(new_range, m_viewing_range_max); + dstream<<"new_range="<<new_range_unclamped + <<", clamped to "<<new_range<<std::endl; + + m_draw_control.wanted_range = new_range; + + m_range_old = new_range; + m_frametime_old = frametime; +} + +void Camera::updateSettings() +{ + m_viewing_range_min = g_settings.getS16("viewing_range_nodes_min"); + m_viewing_range_min = MYMAX(5.0, m_viewing_range_min); + + m_viewing_range_max = g_settings.getS16("viewing_range_nodes_max"); + m_viewing_range_max = MYMAX(m_viewing_range_min, m_viewing_range_max); + + f32 fov_degrees = g_settings.getFloat("fov"); + fov_degrees = MYMAX(fov_degrees, 10.0); + fov_degrees = MYMIN(fov_degrees, 170.0); + m_fov_y = fov_degrees * M_PI / 180.0; + + f32 wanted_fps = g_settings.getFloat("wanted_fps"); + wanted_fps = MYMAX(wanted_fps, 1.0); + m_wanted_frametime = 1.0 / wanted_fps; +} + diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 000000000..88f03e66d --- /dev/null +++ b/src/camera.h @@ -0,0 +1,141 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 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 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 { @@ -144,144 +143,6 @@ struct TextDestSignNode : public TextDest }; /* - 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 "<<added_frames<<" frames, total of " - <<added_frametime<<"s."<<std::endl;*/ - - /*dstream<<"draw_control.blocks_drawn=" - <<draw_control.blocks_drawn - <<", draw_control.blocks_would_have_drawn=" - <<draw_control.blocks_would_have_drawn - <<std::endl;*/ - - float range_min = g_settings.getS16("viewing_range_nodes_min"); - float range_max = g_settings.getS16("viewing_range_nodes_max"); - - // Limit minimum to keep the feedback loop stable - if(range_min < 5) - range_min = 5; - - draw_control.wanted_min_range = range_min; - //draw_control.wanted_max_blocks = (1.5*draw_control.blocks_drawn)+1; - draw_control.wanted_max_blocks = (1.5*draw_control.blocks_would_have_drawn)+1; - if(draw_control.wanted_max_blocks < 10) - draw_control.wanted_max_blocks = 10; - - float block_draw_ratio = 1.0; - if(draw_control.blocks_would_have_drawn != 0) - { - block_draw_ratio = (float)draw_control.blocks_drawn - / (float)draw_control.blocks_would_have_drawn; - } - - // Calculate the average frametime in the case that all wanted - // blocks had been drawn - f32 frametime = added_frametime / added_frames / block_draw_ratio; - - added_frametime = 0.0; - added_frames = 0; - - float wanted_fps = g_settings.getFloat("wanted_fps"); - float wanted_frametime = 1.0 / wanted_fps; - - f32 wanted_frametime_change = wanted_frametime - frametime; - //dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl; - - // If needed frametime change is small, just return - if(fabs(wanted_frametime_change) < wanted_frametime*0.4) - { - //dstream<<"ignoring small wanted_frametime_change"<<std::endl; - return; - } - - float range = draw_control.wanted_range; - float new_range = range; - - static s16 range_old = 0; - static f32 frametime_old = 0; - - float d_range = range - range_old; - f32 d_frametime = frametime - frametime_old; - // A sane default of 30ms per 50 nodes of range - static f32 time_per_range = 30. / 50; - if(d_range != 0) - { - time_per_range = d_frametime / d_range; - } - - // The minimum allowed calculated frametime-range derivative: - // Practically this sets the maximum speed of changing the range. - // The lower this value, the higher the maximum changing speed. - // A low value here results in wobbly range (0.001) - // A high value here results in slow changing range (0.0025) - // SUGG: This could be dynamically adjusted so that when - // the camera is turning, this is lower - //float min_time_per_range = 0.0015; - float min_time_per_range = 0.0010; - //float min_time_per_range = 0.05 / range; - if(time_per_range < min_time_per_range) - { - time_per_range = min_time_per_range; - //dstream<<"time_per_range="<<time_per_range<<" (min)"<<std::endl; - } - else - { - //dstream<<"time_per_range="<<time_per_range<<std::endl; - } - - f32 wanted_range_change = wanted_frametime_change / time_per_range; - // Dampen the change a bit to kill oscillations - //wanted_range_change *= 0.9; - //wanted_range_change *= 0.75; - wanted_range_change *= 0.5; - //dstream<<"wanted_range_change="<<wanted_range_change<<std::endl; - - // If needed range change is very small, just return - if(fabs(wanted_range_change) < 0.001) - { - //dstream<<"ignoring small wanted_range_change"<<std::endl; - return; - } - - new_range += wanted_range_change; - - //float new_range_unclamped = new_range; - if(new_range < range_min) - new_range = range_min; - if(new_range > range_max) - new_range = range_max; - - /*dstream<<"new_range="<<new_range_unclamped - <<", clamped to "<<new_range<<std::endl;*/ - - draw_control.wanted_range = new_range; - - range_old = new_range; - frametime_old = frametime; -} - -/* Hotbar draw routine */ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, @@ -847,6 +708,7 @@ void the_game( draw_load_screen(L"Creating client...", driver, font); std::cout<<DTIME<<"Creating client"<<std::endl; + MapDrawControl draw_control; Client client(device, playername.c_str(), password, draw_control); draw_load_screen(L"Resolving address...", driver, font); @@ -950,25 +812,18 @@ void the_game( /* Create the camera node */ - - scene::ICameraSceneNode* camera = smgr->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" @@ -1169,12 +1024,6 @@ void the_game( 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; } @@ -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<v2s16, bool> 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 |