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.

This commit is contained in:
Kahrl 2011-09-08 01:08:47 +02:00
parent c0b35fa429
commit baf7da9d4a
13 changed files with 428 additions and 209 deletions

View File

@ -142,6 +142,7 @@ set(minetest_SRCS
mapblock_mesh.cpp mapblock_mesh.cpp
farmesh.cpp farmesh.cpp
keycode.cpp keycode.cpp
camera.cpp
clouds.cpp clouds.cpp
clientobject.cpp clientobject.cpp
guiMainMenu.cpp guiMainMenu.cpp

243
src/camera.cpp Normal file
View File

@ -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;
}

141
src/camera.h Normal file
View File

@ -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

View File

@ -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() void Client::renderPostFx()
@ -2004,16 +2004,6 @@ LocalPlayer* Client::getLocalPlayer()
return m_env.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) void Client::setPlayerControl(PlayerControl &control)
{ {
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out

View File

@ -199,7 +199,7 @@ public:
// locks envlock // locks envlock
void addNode(v3s16 p, MapNode n); void addNode(v3s16 p, MapNode n);
void updateCamera(v3f pos, v3f dir); void updateCamera(v3f pos, v3f dir, f32 fov);
void renderPostFx(); void renderPostFx();
@ -210,8 +210,6 @@ public:
LocalPlayer* getLocalPlayer(); LocalPlayer* getLocalPlayer();
v3f getPlayerPosition(v3f *eye_position);
void setPlayerControl(PlayerControl &control); void setPlayerControl(PlayerControl &control);
void selectPlayerItem(u16 item); void selectPlayerItem(u16 item);

View File

@ -44,9 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PI 3.14159 #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). // The absolute working limit is (2^15 - viewing_range).
// I really don't want to make every algorithm to check if it's // I really don't want to make every algorithm to check if it's
// going near the limit or not, so this is lower. // going near the limit or not, so this is lower.

View File

@ -59,6 +59,8 @@ void set_default_settings()
g_settings.setDefault("random_input", "false"); g_settings.setDefault("random_input", "false");
g_settings.setDefault("client_unload_unused_data_timeout", "600"); g_settings.setDefault("client_unload_unused_data_timeout", "600");
g_settings.setDefault("enable_fog", "true"); 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_water", "false");
g_settings.setDefault("new_style_leaves", "true"); g_settings.setDefault("new_style_leaves", "true");
g_settings.setDefault("smooth_lighting", "true"); g_settings.setDefault("smooth_lighting", "true");

View File

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "materials.h" #include "materials.h"
#include "config.h" #include "config.h"
#include "clouds.h" #include "clouds.h"
#include "camera.h"
#include "farmesh.h" #include "farmesh.h"
#include "mapblock.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 #define FIELD_OF_VIEW_TEST 0
MapDrawControl draw_control;
// Chat data // Chat data
struct ChatLine struct ChatLine
{ {
@ -143,144 +142,6 @@ struct TextDestSignNode : public TextDest
Client *m_client; 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 "<<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 Hotbar draw routine
*/ */
@ -847,6 +708,7 @@ void the_game(
draw_load_screen(L"Creating client...", driver, font); draw_load_screen(L"Creating client...", driver, font);
std::cout<<DTIME<<"Creating client"<<std::endl; std::cout<<DTIME<<"Creating client"<<std::endl;
MapDrawControl draw_control;
Client client(device, playername.c_str(), password, draw_control); Client client(device, playername.c_str(), password, draw_control);
draw_load_screen(L"Resolving address...", driver, font); draw_load_screen(L"Resolving address...", driver, font);
@ -950,25 +812,18 @@ void the_game(
/* /*
Create the camera node Create the camera node
*/ */
Camera camera(smgr, draw_control);
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode( if (camera.getPlayerNode() == NULL)
0, // Camera parent {
v3f(BS*100, BS*2, BS*100), // Look from error_message = L"Failed to create the player node";
v3f(BS*100+1, BS*2, BS*100), // Look to return;
-1 // Camera ID }
); if (camera.getCameraNode() == NULL)
if(camera == NULL)
{ {
error_message = L"Failed to create the camera node"; error_message = L"Failed to create the camera node";
return; 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_yaw = 0; // "right/left"
f32 camera_pitch = 0; // "up/down" f32 camera_pitch = 0; // "up/down"
@ -1168,12 +1023,6 @@ void the_game(
// Necessary for device->getTimer()->getTime() // Necessary for device->getTimer()->getTime()
device->run(); device->run();
/*
Viewing range
*/
updateViewingRange(busytime, &client);
/* /*
FPS limiter 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"); //TimeTaker //timer2("//timer2");
/* /*
@ -1621,25 +1466,25 @@ void the_game(
first_loop_after_window_activation = true; first_loop_after_window_activation = true;
} }
camera_yaw = wrapDegrees(camera_yaw); LocalPlayer* player = client.getLocalPlayer();
camera_pitch = wrapDegrees(camera_pitch); camera.update(player, busytime, screensize);
camera.step(dtime);
v3f camera_direction = v3f(0,0,1);
camera_direction.rotateYZBy(camera_pitch);
camera_direction.rotateXZBy(camera_yaw);
camera->setPosition(camera_position); v3f player_position = player->getPosition();
// *100.0 helps in large map coordinates v3f camera_position = camera.getPosition();
camera->setTarget(camera_position + camera_direction * 100.0); v3f camera_direction = camera.getDirection();
f32 camera_fov = camera.getFovMax();
if(FIELD_OF_VIEW_TEST){ if(FIELD_OF_VIEW_TEST)
client.updateCamera(v3f(0,0,0), v3f(0,0,1)); {
client.updateCamera(v3f(0,0,0), v3f(0,0,1), M_PI);
} }
else{ else
//TimeTaker timer("client.updateCamera"); {
client.updateCamera(camera_position, camera_direction); client.updateCamera(camera_position,
camera_direction, camera_fov);
} }
//timer2.stop(); //timer2.stop();
//TimeTaker //timer3("//timer3"); //TimeTaker //timer3("//timer3");
@ -2010,8 +1855,6 @@ void the_game(
Calculate stuff for drawing Calculate stuff for drawing
*/ */
camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);
u32 daynight_ratio = client.getDayNightRatio(); u32 daynight_ratio = client.getDayNightRatio();
u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000); u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000);
video::SColor bgcolor = video::SColor( video::SColor bgcolor = video::SColor(

View File

@ -3604,7 +3604,8 @@ ClientMap::ClientMap(
m_client(client), m_client(client),
m_control(control), m_control(control),
m_camera_position(0,0,0), 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(); m_camera_mutex.Init();
assert(m_camera_mutex.IsInitialized()); assert(m_camera_mutex.IsInitialized());
@ -3713,6 +3714,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
m_camera_mutex.Lock(); m_camera_mutex.Lock();
v3f camera_position = m_camera_position; v3f camera_position = m_camera_position;
v3f camera_direction = m_camera_direction; v3f camera_direction = m_camera_direction;
f32 camera_fov = m_camera_fov;
m_camera_mutex.Unlock(); m_camera_mutex.Unlock();
/* /*
@ -3805,7 +3807,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
float d = 0.0; float d = 0.0;
if(isBlockInSight(block->getPos(), camera_position, if(isBlockInSight(block->getPos(), camera_position,
camera_direction, range, &d) == false) camera_direction, camera_fov,
range, &d) == false)
{ {
continue; continue;
} }

View File

@ -518,11 +518,12 @@ public:
ISceneNode::drop(); ISceneNode::drop();
} }
void updateCamera(v3f pos, v3f dir) void updateCamera(v3f pos, v3f dir, f32 fov)
{ {
JMutexAutoLock lock(m_camera_mutex); JMutexAutoLock lock(m_camera_mutex);
m_camera_position = pos; m_camera_position = pos;
m_camera_direction = dir; m_camera_direction = dir;
m_camera_fov = fov;
} }
/* /*
@ -603,6 +604,7 @@ private:
v3f m_camera_position; v3f m_camera_position;
v3f m_camera_direction; v3f m_camera_direction;
f32 m_camera_fov;
JMutex m_camera_mutex; JMutex m_camera_mutex;
core::map<v2s16, bool> m_last_drawn_sectors; core::map<v2s16, bool> m_last_drawn_sectors;

View File

@ -584,7 +584,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
Don't generate or send if not in sight 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; continue;
} }

View File

@ -162,8 +162,8 @@ void mysrand(unsigned seed)
camera_dir: an unit vector pointing to camera direction camera_dir: an unit vector pointing to camera direction
range: viewing range range: viewing range
*/ */
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
f32 *distance_ptr) f32 camera_fov, f32 range, f32 *distance_ptr)
{ {
v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; 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; cosangle += block_max_radius / dforward;
// If block is not in the field of view, skip it // If block is not in the field of view, skip it
//if(cosangle < cos(FOV_ANGLE/2)) if(cosangle < cos(camera_fov / 2))
if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
return false; return false;
} }

View File

@ -1765,8 +1765,8 @@ inline int myrand_range(int min, int max)
Miscellaneous functions Miscellaneous functions
*/ */
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range, bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
f32 *distance_ptr=NULL); f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
/* /*
Queue with unique values with fast checking of value existence Queue with unique values with fast checking of value existence