aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKahrl <kahrl@gmx.net>2011-09-08 01:08:47 +0200
committerKahrl <kahrl@gmx.net>2011-09-08 01:08:47 +0200
commitbaf7da9d4a7fc0566840b159903999d76d99a228 (patch)
tree66ed23105449fcf51e971d5f8fcbf03d04973fb7 /src
parentc0b35fa429c68b49b2d6a5124aff6dcc31400b63 (diff)
downloadminetest-baf7da9d4a7fc0566840b159903999d76d99a228.tar.gz
minetest-baf7da9d4a7fc0566840b159903999d76d99a228.tar.bz2
minetest-baf7da9d4a7fc0566840b159903999d76d99a228.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/camera.cpp243
-rw-r--r--src/camera.h141
-rw-r--r--src/client.cpp14
-rw-r--r--src/client.h4
-rw-r--r--src/constants.h3
-rw-r--r--src/defaultsettings.cpp2
-rw-r--r--src/game.cpp205
-rw-r--r--src/map.cpp7
-rw-r--r--src/map.h4
-rw-r--r--src/server.cpp2
-rw-r--r--src/utility.cpp7
-rw-r--r--src/utility.h4
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;
}
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<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