X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcamera.cpp;h=7e83dadebf949ef6010a24f197df51a493e373e4;hb=f151b2322003bbc89c2cd3c603ef1e1ab9d46439;hp=94bbe9880386f9c16fc42d4ec85e371abc1d7aba;hpb=13e7589fecfc8b6c247839ddaac66e9d045e513c;p=dragonfireclient.git diff --git a/src/camera.cpp b/src/camera.cpp index 94bbe9880..7e83dadeb 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -27,20 +27,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "wieldmesh.h" #include "noise.h" // easeCurve -#include "gamedef.h" #include "sound.h" #include "event.h" #include "profiler.h" #include "util/numeric.h" -#include "util/mathconstants.h" #include "constants.h" +#include "fontengine.h" #define CAMERA_OFFSET_STEP 200 #include "nodedef.h" Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, - IGameDef *gamedef): + Client *client): m_playernode(NULL), m_headnode(NULL), m_cameranode(NULL), @@ -49,7 +48,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_wieldnode(NULL), m_draw_control(draw_control), - m_gamedef(gamedef), + m_client(client), m_camera_position(0,0,0), m_camera_direction(0,0,0), @@ -59,13 +58,6 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_fov_x(1.0), m_fov_y(1.0), - m_added_busytime(0), - m_added_frames(0), - m_range_old(0), - m_busytime_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_state(0), m_view_bobbing_speed(0), @@ -81,6 +73,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, { //dstream<getVideoDriver(); // note: making the camera node a child of the player node // would lead to unexpected behaviour, so we don't do that. m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode()); @@ -93,7 +86,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_wieldmgr = smgr->createNewSceneManager(); m_wieldmgr->addCameraSceneNode(); m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, false); - m_wieldnode->setItem(ItemStack(), m_gamedef); + m_wieldnode->setItem(ItemStack(), m_client); m_wieldnode->drop(); // m_wieldmgr grabbed it /* TODO: Add a callback function so these can be updated when a setting @@ -107,9 +100,10 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, */ m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount"); m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount"); - m_cache_wanted_fps = g_settings->getFloat("wanted_fps"); m_cache_fov = g_settings->getFloat("fov"); + m_cache_zoom_fov = g_settings->getFloat("zoom_fov"); m_cache_view_bobbing = g_settings->getBool("view_bobbing"); + m_nametags.clear(); } Camera::~Camera() @@ -155,7 +149,7 @@ void Camera::step(f32 dtime) m_wield_change_timer = MYMIN(m_wield_change_timer + dtime, 0.125); if (m_wield_change_timer >= 0 && was_under_zero) - m_wieldnode->setItem(m_wield_item_next, m_gamedef); + m_wieldnode->setItem(m_wield_item_next, m_client); if (m_view_bobbing_state != 0) { @@ -193,7 +187,7 @@ void Camera::step(f32 dtime) (was > 0.5f && m_view_bobbing_anim <= 0.5f)); if(step) { MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } } @@ -214,10 +208,10 @@ void Camera::step(f32 dtime) if(m_digging_button == 0) { MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } else if(m_digging_button == 1) { MtEvent *e = new SimpleTriggerEvent("CameraPunchRight"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } } @@ -356,7 +350,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, my_cp.Y = m_camera_position.Y + (m_camera_direction.Y*-i); // Prevent camera positioned inside nodes - INodeDefManager *nodemgr = m_gamedef->ndef(); + INodeDefManager *nodemgr = m_client->ndef(); MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS)); const ContentFeatures& features = nodemgr->get(n); if(features.walkable) @@ -392,10 +386,14 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, if (m_camera_mode == CAMERA_MODE_THIRD_FRONT) m_camera_position = my_cp; - // Get FOV setting - f32 fov_degrees = m_cache_fov; - fov_degrees = MYMAX(fov_degrees, 10.0); - fov_degrees = MYMIN(fov_degrees, 170.0); + // Get FOV + f32 fov_degrees; + if (player->getPlayerControl().zoom && m_client->checkLocalPrivilege("zoom")) { + fov_degrees = m_cache_zoom_fov; + } else { + fov_degrees = m_cache_fov; + } + fov_degrees = rangelim(fov_degrees, 7.0, 160.0); // FOV and aspect ratio m_aspect = (f32) porting::getWindowSize().X / (f32) porting::getWindowSize().Y; @@ -406,9 +404,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, m_cameranode->setAspectRatio(m_aspect); m_cameranode->setFOV(m_fov_y); + float wieldmesh_offset_Y = -35 + player->getPitch() * 0.05; + wieldmesh_offset_Y = rangelim(wieldmesh_offset_Y, -52, -32); + // Position the wielded item //v3f wield_position = v3f(45, -35, 65); - v3f wield_position = v3f(55, -35, 65); + v3f wield_position = v3f(55, wieldmesh_offset_Y, 65); //v3f wield_rotation = v3f(-100, 120, -100); v3f wield_rotation = v3f(-100, 120, -100); wield_position.Y += fabs(m_wield_change_timer)*320 - 40; @@ -452,8 +453,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, m_wieldnode->setColor(player->light_color); - // Render distance feedback loop - updateViewingRange(frametime, busytime); + // Set render distance + updateViewingRange(); // If the player is walking, swimming, or climbing, // view bobbing is enabled and free_move is off, @@ -467,11 +468,11 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, const bool climbing = movement_Y && player->is_climbing; if ((walking || swimming || climbing) && m_cache_view_bobbing && - (!g_settings->getBool("free_move") || !m_gamedef->checkLocalPrivilege("fly"))) + (!g_settings->getBool("free_move") || !m_client->checkLocalPrivilege("fly"))) { // Start animation m_view_bobbing_state = 1; - m_view_bobbing_speed = MYMIN(speed.getLength(), 40); + m_view_bobbing_speed = MYMIN(speed.getLength(), 70); } else if (m_view_bobbing_state == 1) { @@ -481,143 +482,15 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, } } -void Camera::updateViewingRange(f32 frametime_in, f32 busytime_in) +void Camera::updateViewingRange() { - if (m_draw_control.range_all) - return; - - m_added_busytime += busytime_in; - m_added_frames += 1; - - m_frametime_counter -= frametime_in; - if (m_frametime_counter > 0) + f32 viewing_range = g_settings->getFloat("viewing_range"); + m_draw_control.wanted_range = viewing_range; + if (m_draw_control.range_all) { + m_cameranode->setFarValue(100000.0); return; - m_frametime_counter = 0.2; // Same as ClientMap::updateDrawList interval - - /*dstream<getFloat("viewing_range_nodes_max"); - viewing_range_max = MYMAX(viewing_range_min, viewing_range_max); - - // Immediately apply hard limits - if(m_draw_control.wanted_range < viewing_range_min) - m_draw_control.wanted_range = viewing_range_min; - if(m_draw_control.wanted_range > viewing_range_max) - m_draw_control.wanted_range = viewing_range_max; - - // Just so big a value that everything rendered is visible - // Some more allowance than viewing_range_max * BS because of clouds, - // active objects, etc. - if(viewing_range_max < 200*BS) - m_cameranode->setFarValue(200 * BS * 10); - else - m_cameranode->setFarValue(viewing_range_max * BS * 10); - - f32 wanted_fps = m_cache_wanted_fps; - wanted_fps = MYMAX(wanted_fps, 1.0); - f32 wanted_frametime = 1.0 / wanted_fps; - - m_draw_control.wanted_min_range = viewing_range_min; - m_draw_control.wanted_max_blocks = (2.0*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_busytime / m_added_frames / block_draw_ratio; - - m_added_busytime = 0.0; - m_added_frames = 0; - - f32 wanted_frametime_change = wanted_frametime - frametime; - //dstream<<"wanted_frametime_change="<avg("wanted_frametime_change", wanted_frametime_change); - - // If needed frametime change is small, just return - // This value was 0.4 for many months until 2011-10-18 by c55; - if (fabs(wanted_frametime_change) < wanted_frametime*0.33) - { - //dstream<<"ignoring small wanted_frametime_change"<setFarValue((viewing_range < 2000) ? 2000 * BS : viewing_range * BS); } void Camera::setDigging(s32 button) @@ -628,7 +501,8 @@ void Camera::setDigging(s32 button) void Camera::wield(const ItemStack &item) { - if (item.name != m_wield_item_next.name) { + if (item.name != m_wield_item_next.name || + item.metadata != m_wield_item_next.metadata) { m_wield_item_next = item; if (m_wield_change_timer > 0) m_wield_change_timer = -m_wield_change_timer; @@ -662,3 +536,54 @@ void Camera::drawWieldedTool(irr::core::matrix4* translation) } m_wieldmgr->drawAll(); } + +void Camera::drawNametags() +{ + core::matrix4 trans = m_cameranode->getProjectionMatrix(); + trans *= m_cameranode->getViewMatrix(); + + for (std::list::const_iterator + i = m_nametags.begin(); + i != m_nametags.end(); ++i) { + Nametag *nametag = *i; + if (nametag->nametag_color.getAlpha() == 0) { + // Enforce hiding nametag, + // because if freetype is enabled, a grey + // shadow can remain. + continue; + } + v3f pos = nametag->parent_node->getAbsolutePosition() + v3f(0.0, 1.1 * BS, 0.0); + f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f }; + trans.multiplyWith1x4Matrix(transformed_pos); + if (transformed_pos[3] > 0) { + core::dimension2d textsize = + g_fontengine->getFont()->getDimension( + utf8_to_wide(nametag->nametag_text).c_str()); + f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : + core::reciprocal(transformed_pos[3]); + v2u32 screensize = m_driver->getScreenSize(); + v2s32 screen_pos; + screen_pos.X = screensize.X * + (0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2; + screen_pos.Y = screensize.Y * + (0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2; + core::rect size(0, 0, textsize.Width, textsize.Height); + g_fontengine->getFont()->draw(utf8_to_wide(nametag->nametag_text).c_str(), + size + screen_pos, nametag->nametag_color); + } + } +} + +Nametag *Camera::addNametag(scene::ISceneNode *parent_node, + std::string nametag_text, video::SColor nametag_color) +{ + Nametag *nametag = new Nametag(parent_node, nametag_text, nametag_color); + m_nametags.push_back(nametag); + return nametag; +} + +void Camera::removeNametag(Nametag *nametag) +{ + m_nametags.remove(nametag); + delete nametag; +}