From 09970b7b6daa82ba0cb71540ebb70e671637782f Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 27 Apr 2014 16:09:21 +0200 Subject: [PATCH] Add support for interlaced polarized 3d screens Add (experimental) support for topbottom as well as sidebyside 3d mode --- minetest.conf.example | 12 +- src/CMakeLists.txt | 1 + src/camera.cpp | 79 ++++-- src/camera.h | 25 +- src/client.cpp | 11 +- src/clientmap.cpp | 8 +- src/clientmap.h | 3 +- src/content_cao.cpp | 297 +++++++++++++--------- src/defaultsettings.cpp | 4 +- src/drawscene.cpp | 529 ++++++++++++++++++++++++++++++++++++++++ src/drawscene.h | 37 +++ src/game.cpp | 266 +++----------------- src/hud.cpp | 4 - src/localplayer.cpp | 6 +- src/localplayer.h | 14 +- src/sky.cpp | 30 +-- src/sky.h | 8 +- 17 files changed, 910 insertions(+), 424 deletions(-) create mode 100644 src/drawscene.cpp create mode 100644 src/drawscene.h diff --git a/minetest.conf.example b/minetest.conf.example index c13444657..0b92d1847 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -127,9 +127,15 @@ #view_bobbing_amount = 1.0 # Amount of fall bobbing (0 = no fall bobbing, 1.0 = normal, 2.0 = double) #fall_bobbing_amount = 0.0 -# Anaglyph stereo -#anaglyph = false -#anaglyph_strength = 0.1 +# 3d support, +# right now: +# "none" = no 3d output, +# "anaglyph" = cyan/magenta color 3d, +# "interlaced" = odd/even line based polarisation screen support, +# "topbottom" = split screen top boton, +# "sidebyside" = split screen side by side +#3d_mode = none +#3d_paralax_strength = 0.025 # In-game chat console background color (R,G,B) #console_color = (0,0,0) # In-game chat console background alpha (opaqueness, between 0 and 255) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 09964321a..0992ea176 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -460,6 +460,7 @@ set(minetest_SRCS guiEngine.cpp guiFileSelectMenu.cpp convert_json.cpp + drawscene.cpp ${minetest_SCRIPT_SRCS} ) diff --git a/src/camera.cpp b/src/camera.cpp index 254827803..d961d45b9 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -82,7 +82,9 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_wield_change_timer(0.125), m_wield_mesh_next(NULL), m_previous_playeritem(-1), - m_previous_itemname("") + m_previous_itemname(""), + + m_camera_mode(CAMERA_MODE_FIRST) { //dstream<<__FUNCTION_NAME< 0.125) m_wield_change_timer = 0.125; - if(m_wield_change_timer >= 0 && was_under_zero) { - if(m_wield_mesh_next) { + if(m_wield_change_timer >= 0 && was_under_zero) + { + if(m_wield_mesh_next) + { m_wieldnode->setMesh(m_wield_mesh_next); m_wieldnode->setVisible(true); } else { @@ -189,11 +193,14 @@ void Camera::step(f32 dtime) #endif #if 1 // Animation is getting turned off - if(m_view_bobbing_anim < 0.25){ + if(m_view_bobbing_anim < 0.25) + { m_view_bobbing_anim -= offset; - } else if(m_view_bobbing_anim > 0.75){ + } else if(m_view_bobbing_anim > 0.75) { m_view_bobbing_anim += offset; - } if(m_view_bobbing_anim < 0.5){ + } + if(m_view_bobbing_anim < 0.5) + { m_view_bobbing_anim += offset; if(m_view_bobbing_anim > 0.5) m_view_bobbing_anim = 0.5; @@ -217,7 +224,8 @@ void Camera::step(f32 dtime) bool step = (was == 0 || (was < 0.5f && m_view_bobbing_anim >= 0.5f) || (was > 0.5f && m_view_bobbing_anim <= 0.5f)); - if(step){ + if(step) + { MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep"); m_gamedef->event()->put(e); } @@ -237,10 +245,11 @@ void Camera::step(f32 dtime) float lim = 0.15; if(m_digging_anim_was < lim && m_digging_anim >= lim) { - if(m_digging_button == 0){ + if(m_digging_button == 0) + { MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft"); m_gamedef->event()->put(e); - } else if(m_digging_button == 1){ + } else if(m_digging_button == 1) { MtEvent *e = new SimpleTriggerEvent("CameraPunchRight"); m_gamedef->event()->put(e); } @@ -249,8 +258,7 @@ void Camera::step(f32 dtime) } void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, - f32 tool_reload_ratio, - int current_camera_mode, ClientEnvironment &c_env) + f32 tool_reload_ratio, ClientEnvironment &c_env) { // Get player position // Smooth the movement when walking up stairs @@ -278,7 +286,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, // Fall bobbing animation float fall_bobbing = 0; - if(player->camera_impact >= 1 && current_camera_mode < CAMERA_MODE_THIRD) + if(player->camera_impact >= 1 && m_camera_mode < CAMERA_MODE_THIRD) { if(m_view_bobbing_fall == -1) // Effect took place and has finished player->camera_impact = m_view_bobbing_fall = 0; @@ -297,7 +305,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, // Calculate players eye offset for different camera modes v3f PlayerEyeOffset = player->getEyeOffset(); - if (current_camera_mode == CAMERA_MODE_FIRST) + if (m_camera_mode == CAMERA_MODE_FIRST) PlayerEyeOffset += player->eye_offset_first; else PlayerEyeOffset += player->eye_offset_third; @@ -312,7 +320,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, v3f rel_cam_target = v3f(0,0,1); v3f rel_cam_up = v3f(0,1,0); - if (m_view_bobbing_anim != 0 && current_camera_mode < CAMERA_MODE_THIRD) + if (m_view_bobbing_anim != 0 && m_camera_mode < CAMERA_MODE_THIRD) { f32 bobfrac = my_modf(m_view_bobbing_anim * 2); f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0; @@ -365,16 +373,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, v3f my_cp = m_camera_position; // Reposition the camera for third person view - if (current_camera_mode > CAMERA_MODE_FIRST) { - - if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + if (m_camera_mode > CAMERA_MODE_FIRST) + { + if (m_camera_mode == CAMERA_MODE_THIRD_FRONT) m_camera_direction *= -1; my_cp.Y += 2; // Calculate new position bool abort = false; - for (int i = BS; i <= BS*2; i++) { + for (int i = BS; i <= BS*2; i++) + { my_cp.X = m_camera_position.X + m_camera_direction.X*-i; my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i; if (i > 12) @@ -384,7 +393,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, INodeDefManager *nodemgr = m_gamedef->ndef(); MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS)); const ContentFeatures& features = nodemgr->get(n); - if(features.walkable) { + if(features.walkable) + { my_cp.X += m_camera_direction.X*-1*-BS/2; my_cp.Z += m_camera_direction.Z*-1*-BS/2; my_cp.Y += m_camera_direction.Y*-1*-BS/2; @@ -413,7 +423,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction); // update the camera position in front-view mode to render blocks behind player - if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + if (m_camera_mode == CAMERA_MODE_THIRD_FRONT) m_camera_position = my_cp; // Get FOV setting @@ -439,7 +449,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, wield_position.Y -= 40 + m_wield_change_timer*320; else wield_position.Y -= 40 - m_wield_change_timer*320; - if(m_digging_anim < 0.05 || m_digging_anim > 0.5){ + if(m_digging_anim < 0.05 || m_digging_anim > 0.5) + { f32 frac = 1.0; if(m_digging_anim > 0.5) frac = 2.0 * (m_digging_anim - 0.5); @@ -468,8 +479,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI)); quat_slerp.toEuler(wield_rotation); wield_rotation *= core::RADTODEG; - } - else { + } else { f32 bobfrac = my_modf(m_view_bobbing_anim); wield_position.X -= sin(bobfrac*M_PI*2.0) * 3.0; wield_position.Y += sin(my_modf(bobfrac*2.0)*M_PI) * 3.0; @@ -654,12 +664,14 @@ void Camera::wield(const ItemStack &item, u16 playeritem) std::string itemname = item.getDefinition(idef).name; m_wield_mesh_next = idef->getWieldMesh(itemname, m_gamedef); if(playeritem != m_previous_playeritem && - !(m_previous_itemname == "" && itemname == "")) { + !(m_previous_itemname == "" && itemname == "")) + { m_previous_playeritem = playeritem; m_previous_itemname = itemname; if(m_wield_change_timer >= 0.125) m_wield_change_timer = -0.125; - else if(m_wield_change_timer > 0) { + else if(m_wield_change_timer > 0) + { m_wield_change_timer = -m_wield_change_timer; } } else { @@ -670,7 +682,8 @@ void Camera::wield(const ItemStack &item, u16 playeritem) m_wieldnode->setVisible(false); } m_wield_mesh_next = NULL; - if(m_previous_itemname != itemname) { + if(m_previous_itemname != itemname) + { m_previous_itemname = itemname; m_wield_change_timer = 0; } @@ -679,7 +692,7 @@ void Camera::wield(const ItemStack &item, u16 playeritem) } } -void Camera::drawWieldedTool() +void Camera::drawWieldedTool(irr::core::matrix4* translation) { // Set vertex colors of wield mesh according to light level u8 li = m_wieldlight; @@ -695,5 +708,17 @@ void Camera::drawWieldedTool() cam->setFOV(72.0*M_PI/180.0); cam->setNearValue(0.1); cam->setFarValue(100); + if (translation != NULL) + { + irr::core::matrix4 startMatrix = cam->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (cam->getTarget() + - cam->getAbsolutePosition()).setLength(1) + + cam->getAbsolutePosition(); + + irr::core::vector3df camera_pos = + (startMatrix * *translation).getTranslation(); + cam->setPosition(camera_pos); + cam->setTarget(focusPoint); + } m_wieldmgr->drawAll(); } diff --git a/src/camera.h b/src/camera.h index 63d109f1f..8831257cc 100644 --- a/src/camera.h +++ b/src/camera.h @@ -33,7 +33,7 @@ class LocalPlayer; struct MapDrawControl; class IGameDef; -enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; +enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; /* Client camera class, manages the player and camera scene nodes, the viewing distance @@ -117,8 +117,7 @@ public: // Update the camera from the local player's position. // busytime is used to adjust the viewing range. void update(LocalPlayer* player, f32 frametime, f32 busytime, - f32 tool_reload_ratio, - int current_camera_mode, ClientEnvironment &c_env); + f32 tool_reload_ratio, ClientEnvironment &c_env); // Render distance feedback loop void updateViewingRange(f32 frametime_in, f32 busytime_in); @@ -133,7 +132,23 @@ public: // Draw the wielded tool. // This has to happen *after* the main scene is drawn. // Warning: This clears the Z buffer. - void drawWieldedTool(); + void drawWieldedTool(irr::core::matrix4* translation=NULL); + + // Toggle the current camera mode + void toggleCameraMode() { + if (m_camera_mode == CAMERA_MODE_FIRST) + m_camera_mode = CAMERA_MODE_THIRD; + else if (m_camera_mode == CAMERA_MODE_THIRD) + m_camera_mode = CAMERA_MODE_THIRD_FRONT; + else + m_camera_mode = CAMERA_MODE_FIRST; + } + + //read the current camera mode + inline CameraMode getCameraMode() + { + return m_camera_mode; + } private: // Nodes @@ -196,6 +211,8 @@ private: scene::IMesh *m_wield_mesh_next; u16 m_previous_playeritem; std::string m_previous_itemname; + + CameraMode m_camera_mode; }; #endif diff --git a/src/client.cpp b/src/client.cpp index 6b5072267..5f3c3f590 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -51,6 +51,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/directiontables.h" #include "util/pointedthing.h" #include "version.h" +#include "drawscene.h" + +extern gui::IGUIEnvironment* guienv; /* QueuedMeshUpdate @@ -2648,10 +2651,6 @@ float Client::mediaReceiveProgress() return 1.0; // downloader only exists when not yet done } -void draw_load_screen(const std::wstring &text, - IrrlichtDevice* device, gui::IGUIFont* font, - float dtime=0 ,int percent=0, bool clouds=true); - void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font) { infostream<<"Client::afterContentReceived() started"< names = m_itemdef->getAll(); size_t size = names.size(); size_t count = 0; @@ -2693,7 +2692,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font) count++; percent = count*100/size; if (count%50 == 0) // only update every 50 item - draw_load_screen(text,device,font,0,percent); + draw_load_screen(text, device, guienv, font, 0, percent); } delete[] text; } diff --git a/src/clientmap.cpp b/src/clientmap.cpp index 0a5d00b99..e061a5998 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -856,7 +856,7 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor, return ret; } -void ClientMap::renderPostFx() +void ClientMap::renderPostFx(CameraMode cam_mode) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -867,8 +867,6 @@ void ClientMap::renderPostFx() v3f camera_position = m_camera_position; m_camera_mutex.Unlock(); - LocalPlayer *player = m_client->getEnv().getLocalPlayer(); - MapNode n = getNodeNoEx(floatToInt(camera_position, BS)); // - If the player is in a solid node, make everything black. @@ -876,7 +874,9 @@ void ClientMap::renderPostFx() // - Do not if player is in third person mode const ContentFeatures& features = nodemgr->get(n); video::SColor post_effect_color = features.post_effect_color; - if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")) && player->camera_mode == CAMERA_MODE_FIRST) + if(features.solidness == 2 && !(g_settings->getBool("noclip") && + m_gamedef->checkLocalPrivilege("noclip")) && + cam_mode == CAMERA_MODE_FIRST) { post_effect_color = video::SColor(255, 0, 0, 0); } diff --git a/src/clientmap.h b/src/clientmap.h index e695411be..91f58a70c 100644 --- a/src/clientmap.h +++ b/src/clientmap.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "map.h" +#include "camera.h" #include #include @@ -126,7 +127,7 @@ public: int getBackgroundBrightness(float max_d, u32 daylight_factor, int oldvalue, bool *sunlight_seen_result); - void renderPostFx(); + void renderPostFx(CameraMode cam_mode); // For debug printing virtual void PrintInfo(std::ostream &out); diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 30384a313..b7923ff80 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -84,7 +84,8 @@ void SmoothTranslator::update(v3f vect_new, bool is_end_position, float update_i aim_is_end = is_end_position; vect_old = vect_show; vect_aim = vect_new; - if(update_interval > 0){ + if(update_interval > 0) + { anim_time = update_interval; } else { if(anim_time < 0.001 || anim_time > 1.0) @@ -582,8 +583,10 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env): ClientActiveObject::registerType(getType(), create); } -bool GenericCAO::getCollisionBox(aabb3f *toset) { - if (m_prop.physical) { +bool GenericCAO::getCollisionBox(aabb3f *toset) +{ + if (m_prop.physical) + { //update collision box toset->MinEdge = m_prop.collisionbox.MinEdge * BS; toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS; @@ -597,7 +600,8 @@ bool GenericCAO::getCollisionBox(aabb3f *toset) { return false; } -bool GenericCAO::collideWithObjects() { +bool GenericCAO::collideWithObjects() +{ return m_prop.collideWithObjects; } @@ -635,7 +639,8 @@ void GenericCAO::initialize(const std::string &data) return; } - for(int i=0; igetPlayer(m_name.c_str()); - if(player && player->isLocal()){ + if(player && player->isLocal()) + { m_is_local_player = true; + m_is_visible = false; + LocalPlayer* localplayer = dynamic_cast(player); + + assert( localplayer != NULL ); + localplayer->setCAO(this); } m_env->addPlayerName(m_name.c_str()); } @@ -654,7 +666,8 @@ void GenericCAO::initialize(const std::string &data) GenericCAO::~GenericCAO() { - if(m_is_player){ + if(m_is_player) + { m_env->removePlayerName(m_name.c_str()); } } @@ -668,7 +681,8 @@ core::aabbox3d* GenericCAO::getSelectionBox() v3f GenericCAO::getPosition() { - if(getParent() != NULL){ + if(getParent() != NULL) + { if(m_meshnode) return m_meshnode->getAbsolutePosition(); if(m_animated_meshnode) @@ -711,9 +725,12 @@ ClientActiveObject* GenericCAO::getParent() ClientActiveObject *obj = NULL; for(std::vector >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++) { - if(cii->X == getId()){ // This ID is our child - if(cii->Y > 0){ // A parent ID exists for our child - if(cii->X != cii->Y){ // The parent and child ID are not the same + if(cii->X == getId()) // This ID is our child + { + if(cii->Y > 0) // A parent ID exists for our child + { + if(cii->X != cii->Y) // The parent and child ID are not the same + { obj = m_env->getActiveObject(cii->Y); } } @@ -730,18 +747,21 @@ void GenericCAO::removeFromScene(bool permanent) if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals) { // Detach this object's children - for(std::vector >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++) + for(std::vector >::iterator ii = m_env->attachment_list.begin(); + ii != m_env->attachment_list.end(); ii++) { if(ii->Y == getId()) // Is a child of our object { ii->Y = 0; - ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child + // Get the object of the child + ClientActiveObject *obj = m_env->getActiveObject(ii->X); if(obj) obj->setAttachments(); } } // Delete this object from the attachments list - for(std::vector >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++) + for(std::vector >::iterator ii = m_env->attachment_list.begin(); + ii != m_env->attachment_list.end(); ii++) { if(ii->X == getId()) // Is our object { @@ -751,15 +771,18 @@ void GenericCAO::removeFromScene(bool permanent) } } - if(m_meshnode){ + if(m_meshnode) + { m_meshnode->remove(); m_meshnode = NULL; } - if(m_animated_meshnode){ + if(m_animated_meshnode) + { m_animated_meshnode->remove(); m_animated_meshnode = NULL; } - if(m_spritenode){ + if(m_spritenode) + { m_spritenode->remove(); m_spritenode = NULL; } @@ -781,7 +804,8 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, //video::IVideoDriver* driver = smgr->getVideoDriver(); - if(m_prop.visual == "sprite"){ + if(m_prop.visual == "sprite") + { infostream<<"GenericCAO::addToScene(): single_sprite"<addBillboardSceneNode( NULL, v2f(1, 1), v3f(0,0,0), -1); @@ -801,8 +825,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, txs, tys, 0, 0); } } - else if(m_prop.visual == "upright_sprite") - { + else if(m_prop.visual == "upright_sprite") { scene::SMesh *mesh = new scene::SMesh(); double dx = BS*m_prop.visual_size.X/2; double dy = BS*m_prop.visual_size.Y/2; @@ -856,7 +879,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, // This is needed for changing the texture in the future m_meshnode->setReadOnlyMaterials(true); } - else if(m_prop.visual == "cube"){ + else if(m_prop.visual == "cube") { infostream<<"GenericCAO::addToScene(): cube"<addMeshSceneNode(mesh, NULL); @@ -873,7 +896,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, m_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); } - else if(m_prop.visual == "mesh"){ + else if(m_prop.visual == "mesh") { infostream<<"GenericCAO::addToScene(): mesh"<getMesh(m_prop.mesh); if(mesh) @@ -895,7 +918,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, else errorstream<<"GenericCAO::addToScene(): Could not load mesh "<= 1){ @@ -949,7 +972,8 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void GenericCAO::updateLight(u8 light_at_pos) { u8 li = decode_light(light_at_pos); - if(li != m_last_light){ + if(li != m_last_light) + { m_last_light = li; video::SColor color(255,li,li,li); if(m_meshnode) @@ -972,19 +996,22 @@ void GenericCAO::updateNodePos() return; v3s16 camera_offset = m_env->getCameraOffset(); - if(m_meshnode){ + if(m_meshnode) + { m_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS)); v3f rot = m_meshnode->getRotation(); rot.Y = -m_yaw; m_meshnode->setRotation(rot); } - if(m_animated_meshnode){ + if(m_animated_meshnode) + { m_animated_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS)); v3f rot = m_animated_meshnode->getRotation(); rot.Y = -m_yaw; m_animated_meshnode->setRotation(rot); } - if(m_spritenode){ + if(m_spritenode) + { m_spritenode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS)); } } @@ -992,13 +1019,14 @@ void GenericCAO::updateNodePos() void GenericCAO::step(float dtime, ClientEnvironment *env) { // Handel model of local player instantly to prevent lags - if(m_is_local_player) { + if(m_is_local_player) + { LocalPlayer *player = m_env->getLocalPlayer(); - if (player->camera_mode > CAMERA_MODE_FIRST) { + if (m_is_visible) + { int old_anim = player->last_animation; float old_anim_speed = player->last_animation_speed; - m_is_visible = true; m_position = player->getPosition() + v3f(0,BS,0); m_velocity = v3f(0,0,0); m_acceleration = v3f(0,0,0); @@ -1026,7 +1054,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) if(controls.sneak && walking) new_speed /= 2; - if(walking && (controls.LMB || controls.RMB)) { + if(walking && (controls.LMB || controls.RMB)) + { new_anim = player->local_animations[3]; player->last_animation = WD_ANIM; } else if(walking) { @@ -1039,7 +1068,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) // Apply animations if input detected and not attached // or set idle animation - if ((new_anim.X + new_anim.Y) > 0 && !player->isAttached) { + if ((new_anim.X + new_anim.Y) > 0 && !player->isAttached) + { allow_update = true; m_animation_range = new_anim; m_animation_speed = new_speed; @@ -1047,36 +1077,42 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } else { player->last_animation = NO_ANIM; - if (old_anim != NO_ANIM) { + if (old_anim != NO_ANIM) + { m_animation_range = player->local_animations[0]; updateAnimation(); } } // Update local player animations - if ((player->last_animation != old_anim || m_animation_speed != old_anim_speed) && + if ((player->last_animation != old_anim || + m_animation_speed != old_anim_speed) && player->last_animation != NO_ANIM && allow_update) updateAnimation(); - } else { - m_is_visible = false; } } if(m_visuals_expired && m_smgr && m_irr){ m_visuals_expired = false; - // Attachments, part 1: All attached objects must be unparented first, or Irrlicht causes a segmentation fault - for(std::vector >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++) + // Attachments, part 1: All attached objects must be unparented first, + // or Irrlicht causes a segmentation fault + for(std::vector >::iterator ii = m_env->attachment_list.begin(); + ii != m_env->attachment_list.end(); ii++) { if(ii->Y == getId()) // This is a child of our parent { - ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child + // Get the object of the child + ClientActiveObject *obj = m_env->getActiveObject(ii->X); if(obj) { - scene::IMeshSceneNode *m_child_meshnode = obj->getMeshSceneNode(); - scene::IAnimatedMeshSceneNode *m_child_animated_meshnode = obj->getAnimatedMeshSceneNode(); - scene::IBillboardSceneNode *m_child_spritenode = obj->getSpriteSceneNode(); + scene::IMeshSceneNode *m_child_meshnode + = obj->getMeshSceneNode(); + scene::IAnimatedMeshSceneNode *m_child_animated_meshnode + = obj->getAnimatedMeshSceneNode(); + scene::IBillboardSceneNode *m_child_spritenode + = obj->getSpriteSceneNode(); if(m_child_meshnode) m_child_meshnode->setParent(m_smgr->getRootSceneNode()); if(m_child_animated_meshnode) @@ -1091,11 +1127,13 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) addToScene(m_smgr, m_gamedef->tsrc(), m_irr); // Attachments, part 2: Now that the parent has been refreshed, put its attachments back - for(std::vector >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++) + for(std::vector >::iterator ii = m_env->attachment_list.begin(); + ii != m_env->attachment_list.end(); ii++) { if(ii->Y == getId()) // This is a child of our parent { - ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child + // Get the object of the child + ClientActiveObject *obj = m_env->getActiveObject(ii->X); if(obj) obj->setAttachments(); } @@ -1126,12 +1164,11 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) player->overridePosition = getParent()->getPosition(); m_env->getLocalPlayer()->parent = getParent(); } - } - else - { + } else { v3f lastpos = pos_translator.vect_show; - if(m_prop.physical){ + if(m_prop.physical) + { core::aabbox3d box = m_prop.collisionbox; box.MinEdge *= BS; box.MaxEdge *= BS; @@ -1156,16 +1193,19 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } else { m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration; m_velocity += dtime * m_acceleration; - pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time); + pos_translator.update(m_position, pos_translator.aim_is_end, + pos_translator.anim_time); pos_translator.translate(dtime); updateNodePos(); } float moved = lastpos.getDistanceFrom(pos_translator.vect_show); m_step_distance_counter += moved; - if(m_step_distance_counter > 1.5*BS){ + if(m_step_distance_counter > 1.5*BS) + { m_step_distance_counter = 0; - if(!m_is_local_player && m_prop.makes_footstep_sound){ + if(!m_is_local_player && m_prop.makes_footstep_sound) + { INodeDefManager *ndef = m_gamedef->ndef(); v3s16 p = floatToInt(getPosition() + v3f(0, (m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS); @@ -1177,7 +1217,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } m_anim_timer += dtime; - if(m_anim_timer >= m_anim_framelength){ + if(m_anim_timer >= m_anim_framelength) + { m_anim_timer -= m_anim_framelength; m_anim_frame++; if(m_anim_frame >= m_anim_num_frames) @@ -1186,28 +1227,33 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) updateTexturePos(); - if(m_reset_textures_timer >= 0){ + if(m_reset_textures_timer >= 0) + { m_reset_textures_timer -= dtime; if(m_reset_textures_timer <= 0){ m_reset_textures_timer = -1; updateTextures(""); } } - if(getParent() == NULL && fabs(m_prop.automatic_rotate) > 0.001){ + if(getParent() == NULL && fabs(m_prop.automatic_rotate) > 0.001) + { m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI; updateNodePos(); } if (getParent() == NULL && m_prop.automatic_face_movement_dir && - (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)){ - m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI + m_prop.automatic_face_movement_dir_offset; + (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)) + { + m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI + + m_prop.automatic_face_movement_dir_offset; updateNodePos(); } } void GenericCAO::updateTexturePos() { - if(m_spritenode){ + if(m_spritenode) + { scene::ICameraSceneNode* camera = m_spritenode->getSceneManager()->getActiveCamera(); if(!camera) @@ -1226,7 +1272,8 @@ void GenericCAO::updateTexturePos() else if(cam_to_entity.Y < -0.75) col += 4; else{ - float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.; + float mob_dir = + atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.; float dir = mob_dir - m_yaw; dir = wrapDegrees_180(dir); //infostream<<"id="<getMaterialCount(); ++i) + for (u32 i = 0; i < m_prop.textures.size() && + i < m_animated_meshnode->getMaterialCount(); ++i) { std::string texturestring = m_prop.textures[i]; if(texturestring == "") @@ -1310,11 +1358,15 @@ void GenericCAO::updateTextures(const std::string &mod) material.setFlag(video::EMF_LIGHTING, false); material.setFlag(video::EMF_BILINEAR_FILTER, false); - m_animated_meshnode->getMaterial(i).setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); - m_animated_meshnode->getMaterial(i).setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); - m_animated_meshnode->getMaterial(i).setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); } - for (u32 i = 0; i < m_prop.colors.size() && i < m_animated_meshnode->getMaterialCount(); ++i) + for (u32 i = 0; i < m_prop.colors.size() && + i < m_animated_meshnode->getMaterialCount(); ++i) { // This allows setting per-material colors. However, until a real lighting // system is added, the code below will have no effect. Once MineTest @@ -1436,7 +1488,10 @@ void GenericCAO::updateBonePosition() return; m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render - for(std::map >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ + for(std::map >::const_iterator ii = m_bone_position.begin(); + ii != m_bone_position.end(); ++ii) + { std::string bone_name = (*ii).first; v3f bone_pos = (*ii).second.X; v3f bone_rot = (*ii).second.Y; @@ -1451,8 +1506,14 @@ void GenericCAO::updateBonePosition() void GenericCAO::updateAttachments() { - m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); - m_is_visible = !m_attached_to_local; // Objects attached to the local player should always be hidden + + // localplayer itself can't be attached to localplayer + if (!m_is_local_player) + { + m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); + // Objects attached to the local player should always be hidden + m_is_visible = !m_attached_to_local; + } if(getParent() == NULL || m_attached_to_local) // Detach or don't attach { @@ -1503,12 +1564,17 @@ void GenericCAO::updateAttachments() scene::IBoneSceneNode *parent_bone = NULL; if(parent_animated_mesh && m_attachment_bone != "") - parent_bone = parent_animated_mesh->getJointNode(m_attachment_bone.c_str()); - - // The spaghetti code below makes sure attaching works if either the parent or child is a spritenode, meshnode, or animatedmeshnode + { + parent_bone = + parent_animated_mesh->getJointNode(m_attachment_bone.c_str()); + } + // The spaghetti code below makes sure attaching works if either the + // parent or child is a spritenode, meshnode, or animatedmeshnode // TODO: Perhaps use polymorphism here to save code duplication - if(m_meshnode){ - if(parent_bone){ + if(m_meshnode) + { + if(parent_bone) + { m_meshnode->setParent(parent_bone); m_meshnode->setPosition(m_attachment_position); m_meshnode->setRotation(m_attachment_rotation); @@ -1516,19 +1582,20 @@ void GenericCAO::updateAttachments() } else { - if(parent_mesh){ + if(parent_mesh) + { m_meshnode->setParent(parent_mesh); m_meshnode->setPosition(m_attachment_position); m_meshnode->setRotation(m_attachment_rotation); m_meshnode->updateAbsolutePosition(); } - else if(parent_animated_mesh){ + else if(parent_animated_mesh) { m_meshnode->setParent(parent_animated_mesh); m_meshnode->setPosition(m_attachment_position); m_meshnode->setRotation(m_attachment_rotation); m_meshnode->updateAbsolutePosition(); } - else if(parent_sprite){ + else if(parent_sprite) { m_meshnode->setParent(parent_sprite); m_meshnode->setPosition(m_attachment_position); m_meshnode->setRotation(m_attachment_rotation); @@ -1536,8 +1603,10 @@ void GenericCAO::updateAttachments() } } } - if(m_animated_meshnode){ - if(parent_bone){ + if(m_animated_meshnode) + { + if(parent_bone) + { m_animated_meshnode->setParent(parent_bone); m_animated_meshnode->setPosition(m_attachment_position); m_animated_meshnode->setRotation(m_attachment_rotation); @@ -1545,19 +1614,18 @@ void GenericCAO::updateAttachments() } else { - if(parent_mesh){ + if(parent_mesh) + { m_animated_meshnode->setParent(parent_mesh); m_animated_meshnode->setPosition(m_attachment_position); m_animated_meshnode->setRotation(m_attachment_rotation); m_animated_meshnode->updateAbsolutePosition(); - } - else if(parent_animated_mesh){ + } else if(parent_animated_mesh) { m_animated_meshnode->setParent(parent_animated_mesh); m_animated_meshnode->setPosition(m_attachment_position); m_animated_meshnode->setRotation(m_attachment_rotation); m_animated_meshnode->updateAbsolutePosition(); - } - else if(parent_sprite){ + } else if(parent_sprite) { m_animated_meshnode->setParent(parent_sprite); m_animated_meshnode->setPosition(m_attachment_position); m_animated_meshnode->setRotation(m_attachment_rotation); @@ -1565,28 +1633,29 @@ void GenericCAO::updateAttachments() } } } - if(m_spritenode){ - if(parent_bone){ + if(m_spritenode) + { + if(parent_bone) + { m_spritenode->setParent(parent_bone); m_spritenode->setPosition(m_attachment_position); m_spritenode->setRotation(m_attachment_rotation); m_spritenode->updateAbsolutePosition(); - } - else - { - if(parent_mesh){ + } else { + if(parent_mesh) + { m_spritenode->setParent(parent_mesh); m_spritenode->setPosition(m_attachment_position); m_spritenode->setRotation(m_attachment_rotation); m_spritenode->updateAbsolutePosition(); } - else if(parent_animated_mesh){ + else if(parent_animated_mesh) { m_spritenode->setParent(parent_animated_mesh); m_spritenode->setPosition(m_attachment_position); m_spritenode->setRotation(m_attachment_rotation); m_spritenode->updateAbsolutePosition(); } - else if(parent_sprite){ + else if(parent_sprite) { m_spritenode->setParent(parent_sprite); m_spritenode->setPosition(m_attachment_position); m_spritenode->setRotation(m_attachment_rotation); @@ -1649,7 +1718,8 @@ void GenericCAO::processMessage(const std::string &data) if(getParent() != NULL) // Just in case return; - if(do_interpolate){ + if(do_interpolate) + { if(!m_prop.physical) pos_translator.update(m_position, is_end_position, update_interval); } else { @@ -1657,13 +1727,11 @@ void GenericCAO::processMessage(const std::string &data) } updateNodePos(); } - else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) - { + else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) { std::string mod = deSerializeString(is); updateTextures(mod); } - else if(cmd == GENERIC_CMD_SET_SPRITE) - { + else if(cmd == GENERIC_CMD_SET_SPRITE) { v2s16 p = readV2S16(is); int num_frames = readU16(is); float framelength = readF1000(is); @@ -1676,8 +1744,7 @@ void GenericCAO::processMessage(const std::string &data) updateTexturePos(); } - else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) - { + else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) { float override_speed = readF1000(is); float override_jump = readF1000(is); float override_gravity = readF1000(is); @@ -1696,8 +1763,7 @@ void GenericCAO::processMessage(const std::string &data) player->physics_override_sneak_glitch = sneak_glitch; } } - else if(cmd == GENERIC_CMD_SET_ANIMATION) - { + else if(cmd == GENERIC_CMD_SET_ANIMATION) { // TODO: change frames send as v2s32 value v2f range = readV2F1000(is); if (!m_is_local_player) { @@ -1707,7 +1773,8 @@ void GenericCAO::processMessage(const std::string &data) updateAnimation(); } else { LocalPlayer *player = m_env->getLocalPlayer(); - if(player->last_animation == NO_ANIM) { + if(player->last_animation == NO_ANIM) + { m_animation_range = v2s32((s32)range.X, (s32)range.Y); m_animation_speed = readF1000(is); m_animation_blend = readF1000(is); @@ -1715,7 +1782,8 @@ void GenericCAO::processMessage(const std::string &data) // update animation only if local animations present // and received animation is unknown (except idle animation) bool is_known = false; - for (int i = 1;i<4;i++) { + for (int i = 1;i<4;i++) + { if(m_animation_range.Y == player->local_animations[i].Y) is_known = true; } @@ -1726,8 +1794,7 @@ void GenericCAO::processMessage(const std::string &data) } } } - else if(cmd == GENERIC_CMD_SET_BONE_POSITION) - { + else if(cmd == GENERIC_CMD_SET_BONE_POSITION) { std::string bone = deSerializeString(is); v3f position = readV3F1000(is); v3f rotation = readV3F1000(is); @@ -1735,8 +1802,7 @@ void GenericCAO::processMessage(const std::string &data) updateBonePosition(); } - else if(cmd == GENERIC_CMD_SET_ATTACHMENT) - { + else if(cmd == GENERIC_CMD_SET_ATTACHMENT) { // If an entry already exists for this object, delete it first to avoid duplicates for(std::vector >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++) { @@ -1753,8 +1819,7 @@ void GenericCAO::processMessage(const std::string &data) updateAttachments(); } - else if(cmd == GENERIC_CMD_PUNCHED) - { + else if(cmd == GENERIC_CMD_PUNCHED) { /*s16 damage =*/ readS16(is); s16 result_hp = readS16(is); @@ -1763,8 +1828,10 @@ void GenericCAO::processMessage(const std::string &data) m_hp = result_hp; - if (damage > 0) { - if (m_hp <= 0) { + if (damage > 0) + { + if (m_hp <= 0) + { // TODO: Execute defined fast response // As there is no definition, make a smoke puff ClientSimpleObject *simple = createSmokePuff( @@ -1781,11 +1848,11 @@ void GenericCAO::processMessage(const std::string &data) } } } - else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) - { + else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { m_armor_groups.clear(); int armor_groups_size = readU16(is); - for(int i=0; ifirst<<"="<second<<", "; } os<<"}"; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 945804ba8..6ba7057bd 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -56,8 +56,8 @@ void set_default_settings(Settings *settings) settings->setDefault("keymap_camera_mode", "KEY_F7"); settings->setDefault("keymap_increase_viewing_range_min", "+"); settings->setDefault("keymap_decrease_viewing_range_min", "-"); - settings->setDefault("anaglyph", "false"); - settings->setDefault("anaglyph_strength", "0.1"); + settings->setDefault("3d_mode", "none"); + settings->setDefault("3d_paralax_strength", "0.025"); settings->setDefault("aux1_descends", "false"); settings->setDefault("doubletap_jump", "false"); settings->setDefault("always_fly_fast", "true"); diff --git a/src/drawscene.cpp b/src/drawscene.cpp new file mode 100644 index 000000000..491101563 --- /dev/null +++ b/src/drawscene.cpp @@ -0,0 +1,529 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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 "drawscene.h" +#include "main.h" // for g_settings +#include "settings.h" +#include "clouds.h" +#include "util/timetaker.h" + +typedef enum { + LEFT = -1, + RIGHT = 1, + EYECOUNT = 2 +} paralax_sign; + +void draw_selectionbox(video::IVideoDriver* driver, Hud& hud, + std::vector& hilightboxes, bool show_hud) +{ + if (!show_hud) + return; + + video::SMaterial oldmaterial = driver->getMaterial2D(); + video::SMaterial m; + m.Thickness = 3; + m.Lighting = false; + driver->setMaterial(m); + hud.drawSelectionBoxes(hilightboxes); + driver->setMaterial(oldmaterial); +} + +void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud, + std::vector hilightboxes, video::IVideoDriver* driver, + scene::ISceneManager* smgr, bool draw_wield_tool, Client& client, + gui::IGUIEnvironment* guienv ) +{ + + /* preserve old setup*/ + irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); + irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); + + irr::core::matrix4 startMatrix = + camera.getCameraNode()->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() + - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + + camera.getCameraNode()->getAbsolutePosition(); + + + //Left eye... + irr::core::vector3df leftEye; + irr::core::matrix4 leftMove; + leftMove.setTranslation( + irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"), + 0.0f, 0.0f)); + leftEye = (startMatrix * leftMove).getTranslation(); + + //clear the depth buffer, and color + driver->beginScene( true, true, irr::video::SColor(0, 200, 200, 255)); + driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED; + driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; + driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT + + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW; + camera.getCameraNode()->setPosition(leftEye); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + if (show_hud) + { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if (draw_wield_tool) + camera.drawWieldedTool(&leftMove); + } + + guienv->drawAll(); + + //Right eye... + irr::core::vector3df rightEye; + irr::core::matrix4 rightMove; + rightMove.setTranslation( + irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"), + 0.0f, 0.0f)); + rightEye = (startMatrix * rightMove).getTranslation(); + + //clear the depth buffer + driver->clearZBuffer(); + driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN + + irr::video::ECP_BLUE; + driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; + driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT + + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW; + camera.getCameraNode()->setPosition(rightEye); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + if (show_hud) + { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if (draw_wield_tool) + camera.drawWieldedTool(&rightMove); + } + + guienv->drawAll(); + + driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL; + driver->getOverrideMaterial().EnableFlags = 0; + driver->getOverrideMaterial().EnablePasses = 0; + camera.getCameraNode()->setPosition(oldPosition); + camera.getCameraNode()->setTarget(oldTarget); +} + +void init_texture(video::IVideoDriver* driver, const v2u32& screensize, + video::ITexture** texture) +{ + static v2u32 last_screensize = v2u32(0,0); + + if (( *texture == NULL ) || (screensize != last_screensize)) + { + if (*texture != NULL) + { + driver->removeTexture(*texture); + } + *texture = driver->addRenderTargetTexture( + core::dimension2d(screensize.X, screensize.Y)); + last_screensize = screensize; + } +} + +video::ITexture* draw_image(const v2u32& screensize, + paralax_sign psign, const irr::core::matrix4& startMatrix, + const irr::core::vector3df& focusPoint, bool show_hud, + video::IVideoDriver* driver, Camera& camera, scene::ISceneManager* smgr, + Hud& hud, std::vector& hilightboxes, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, + video::SColor skycolor ) +{ + static video::ITexture* images[2] = { NULL, NULL }; + + video::ITexture* image = NULL; + + if (psign == RIGHT) + { + init_texture(driver, screensize, &images[1]); + image = images[1]; + } else { + init_texture(driver, screensize, &images[0]); + image = images[0]; + } + + driver->setRenderTarget(image, true, true, + irr::video::SColor(255, + skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue())); + + irr::core::vector3df eye_pos; + irr::core::matrix4 movement; + movement.setTranslation( + irr::core::vector3df((int) psign * + g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f)); + eye_pos = (startMatrix * movement).getTranslation(); + + //clear the depth buffer + driver->clearZBuffer(); + camera.getCameraNode()->setPosition(eye_pos); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + + if (show_hud) + { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if (draw_wield_tool) + camera.drawWieldedTool(&movement); + } + + guienv->drawAll(); + + /* switch back to real renderer */ + driver->setRenderTarget(0, true, true, + irr::video::SColor(0, + skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue())); + + return image; +} + +video::ITexture* draw_hud(video::IVideoDriver* driver, const v2u32& screensize, + bool show_hud, Hud& hud, Client& client, bool draw_crosshair, + video::SColor skycolor, gui::IGUIEnvironment* guienv, Camera& camera ) +{ + static video::ITexture* image = NULL; + init_texture(driver, screensize, &image); + driver->setRenderTarget(image, true, true, + irr::video::SColor(255,0,0,0)); + + if (show_hud) + { + if (draw_crosshair) + hud.drawCrosshair(); + hud.drawHotbar(client.getPlayerItem()); + hud.drawLuaElements(camera.getOffset()); + + guienv->drawAll(); + } + + driver->setRenderTarget(0, true, true, + irr::video::SColor(0, + skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue())); + + return image; +} + +void draw_interlaced_3d_mode(Camera& camera, bool show_hud, + Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + scene::ISceneManager* smgr, const v2u32& screensize, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, + video::SColor skycolor ) +{ + /* save current info */ + irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); + irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); + irr::core::matrix4 startMatrix = + camera.getCameraNode()->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() + - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + + camera.getCameraNode()->getAbsolutePosition(); + + /* create left view */ + video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, + focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + draw_wield_tool, client, guienv, skycolor); + + //Right eye... + irr::core::vector3df rightEye; + irr::core::matrix4 rightMove; + rightMove.setTranslation( + irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"), + 0.0f, 0.0f)); + rightEye = (startMatrix * rightMove).getTranslation(); + + //clear the depth buffer + driver->clearZBuffer(); + camera.getCameraNode()->setPosition(rightEye); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + + if (show_hud) + { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if(draw_wield_tool) + camera.drawWieldedTool(&rightMove); + } + guienv->drawAll(); + + for (unsigned int i = 0; i < screensize.Y; i+=2 ) { + driver->draw2DImage(left_image, irr::core::position2d(0, screensize.Y-i), + irr::core::rect(0, i,screensize.X, i+1), 0, + irr::video::SColor(255, 255, 255, 255), + false); + } + + /* cleanup */ + camera.getCameraNode()->setPosition(oldPosition); + camera.getCameraNode()->setTarget(oldTarget); +} + +void draw_sidebyside_3d_mode(Camera& camera, bool show_hud, + Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + scene::ISceneManager* smgr, const v2u32& screensize, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, + video::SColor skycolor ) +{ + /* save current info */ + irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); + irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); + irr::core::matrix4 startMatrix = + camera.getCameraNode()->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() + - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + + camera.getCameraNode()->getAbsolutePosition(); + + /* create left view */ + video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, + focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + draw_wield_tool, client, guienv, skycolor); + + /* create right view */ + video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix, + focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + draw_wield_tool, client, guienv, skycolor); + + /* create hud overlay */ + video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client, + false, skycolor, guienv, camera ); + driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0)); + //makeColorKeyTexture mirrors texture so we do it twice to get it right again + driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0)); + + driver->draw2DImage(left_image, + irr::core::rect(0, 0, screensize.X/2, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, false); + + driver->draw2DImage(hudtexture, + irr::core::rect(0, 0, screensize.X/2, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, true); + + driver->draw2DImage(right_image, + irr::core::rect(screensize.X/2, 0, screensize.X, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, false); + + driver->draw2DImage(hudtexture, + irr::core::rect(screensize.X/2, 0, screensize.X, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, true); + + left_image = NULL; + right_image = NULL; + + /* cleanup */ + camera.getCameraNode()->setPosition(oldPosition); + camera.getCameraNode()->setTarget(oldTarget); +} + +void draw_top_bottom_3d_mode(Camera& camera, bool show_hud, + Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + scene::ISceneManager* smgr, const v2u32& screensize, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, + video::SColor skycolor ) +{ + /* save current info */ + irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); + irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); + irr::core::matrix4 startMatrix = + camera.getCameraNode()->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() + - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + + camera.getCameraNode()->getAbsolutePosition(); + + /* create left view */ + video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, + focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + draw_wield_tool, client, guienv, skycolor); + + /* create right view */ + video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix, + focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + draw_wield_tool, client, guienv, skycolor); + + /* create hud overlay */ + video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client, + false, skycolor, guienv, camera ); + driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0)); + //makeColorKeyTexture mirrors texture so we do it twice to get it right again + driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0)); + + driver->draw2DImage(left_image, + irr::core::rect(0, 0, screensize.X, screensize.Y/2), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, false); + + driver->draw2DImage(hudtexture, + irr::core::rect(0, 0, screensize.X, screensize.Y/2), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, true); + + driver->draw2DImage(right_image, + irr::core::rect(0, screensize.Y/2, screensize.X, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, false); + + driver->draw2DImage(hudtexture, + irr::core::rect(0, screensize.Y/2, screensize.X, screensize.Y), + irr::core::rect(0, 0, screensize.X, screensize.Y), 0, 0, true); + + left_image = NULL; + right_image = NULL; + + /* cleanup */ + camera.getCameraNode()->setPosition(oldPosition); + camera.getCameraNode()->setTarget(oldTarget); +} + +void draw_plain(Camera& camera, bool show_hud, Hud& hud, + std::vector hilightboxes, video::IVideoDriver* driver, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv) +{ + + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if(draw_wield_tool) + camera.drawWieldedTool(); +} + +void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr, + Camera& camera, Client& client, LocalPlayer* player, Hud& hud, + gui::IGUIEnvironment* guienv, std::vector hilightboxes, + const v2u32& screensize, video::SColor skycolor, bool show_hud) +{ + //TODO check if usefull + u32 scenetime = 0; + { + TimeTaker timer("smgr"); + + bool draw_wield_tool = (show_hud && + (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) && + camera.getCameraMode() < CAMERA_MODE_THIRD ); + + bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) && + (camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT)); + + std::string draw_mode = g_settings->get("3d_mode"); + + smgr->drawAll(); + + if (draw_mode == "anaglyph") + { + draw_anaglyph_3d_mode(camera, show_hud, hud, hilightboxes, driver, + smgr, draw_wield_tool, client, guienv); + draw_crosshair = false; + } + else if (draw_mode == "interlaced") + { + draw_interlaced_3d_mode(camera, show_hud, hud, hilightboxes, driver, + smgr, screensize, draw_wield_tool, client, guienv, skycolor); + draw_crosshair = false; + } + else if (draw_mode == "sidebyside") + { + draw_sidebyside_3d_mode(camera, show_hud, hud, hilightboxes, driver, + smgr, screensize, draw_wield_tool, client, guienv, skycolor); + show_hud = false; + } + else if (draw_mode == "topbottom") + { + draw_top_bottom_3d_mode(camera, show_hud, hud, hilightboxes, driver, + smgr, screensize, draw_wield_tool, client, guienv, skycolor); + show_hud = false; + } + else { + draw_plain(camera, show_hud, hud, hilightboxes, driver, + draw_wield_tool, client, guienv); + } + //TODO how to make those 3d too + if (show_hud) + { + if (draw_crosshair) + hud.drawCrosshair(); + hud.drawHotbar(client.getPlayerItem()); + hud.drawLuaElements(camera.getOffset()); + + guienv->drawAll(); + } + + scenetime = timer.stop(true); + } + +} + +/* + Draws a screen with a single text on it. + Text will be removed when the screen is drawn the next time. + Additionally, a progressbar can be drawn when percent is set between 0 and 100. +*/ +/*gui::IGUIStaticText **/ +void draw_load_screen(const std::wstring &text, IrrlichtDevice* device, + gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime, + int percent, bool clouds ) +{ + video::IVideoDriver* driver = device->getVideoDriver(); + v2u32 screensize = driver->getScreenSize(); + const wchar_t *loadingtext = text.c_str(); + core::vector2d textsize_u = font->getDimension(loadingtext); + core::vector2d textsize(textsize_u.X,textsize_u.Y); + core::vector2d center(screensize.X/2, screensize.Y/2); + core::rect textrect(center - textsize/2, center + textsize/2); + + gui::IGUIStaticText *guitext = guienv->addStaticText( + loadingtext, textrect, false, false); + guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); + + bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); + if (cloud_menu_background) + { + g_menuclouds->step(dtime*3); + g_menuclouds->render(); + driver->beginScene(true, true, video::SColor(255,140,186,250)); + g_menucloudsmgr->drawAll(); + } + else + driver->beginScene(true, true, video::SColor(255,0,0,0)); + + if (percent >= 0 && percent <= 100) // draw progress bar + { + core::vector2d barsize(256,32); + core::rect barrect(center-barsize/2, center+barsize/2); + driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border + driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect ( + barrect.UpperLeftCorner+1, + barrect.LowerRightCorner-1), NULL); // black inside the bar + driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect ( + barrect.UpperLeftCorner+1, + core::vector2d( + barrect.LowerRightCorner.X-(barsize.X-1)+percent*(barsize.X-2)/100, + barrect.LowerRightCorner.Y-1)), NULL); // the actual progress + } + guienv->drawAll(); + driver->endScene(); + + guitext->remove(); + + //return guitext; +} diff --git a/src/drawscene.h b/src/drawscene.h new file mode 100644 index 000000000..062552516 --- /dev/null +++ b/src/drawscene.h @@ -0,0 +1,37 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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 DRAWSCENE_H_ +#define DRAWSCENE_H_ + +#include "camera.h" +#include "hud.h" +#include "irrlichttypes_extrabloated.h" + + +void draw_load_screen(const std::wstring &text, IrrlichtDevice* device, + gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime=0, + int percent=0, bool clouds=true); + +void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr, + Camera& camera, Client& client, LocalPlayer* player, Hud& hud, + gui::IGUIEnvironment* guienv, std::vector hilightboxes, + const v2u32& screensize, video::SColor skycolor, bool show_hud); + +#endif /* DRAWSCENE_H_ */ diff --git a/src/game.cpp b/src/game.cpp index 0b28c7d17..d7dfa11b1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -68,6 +68,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "util/directiontables.h" #include "util/pointedthing.h" +#include "drawscene.h" +#include "content_cao.h" /* Text input system @@ -418,59 +420,6 @@ PointedThing getPointedThing(Client *client, v3f player_position, return result; } -/* - Draws a screen with a single text on it. - Text will be removed when the screen is drawn the next time. - Additionally, a progressbar can be drawn when percent is set between 0 and 100. -*/ -/*gui::IGUIStaticText **/ -void draw_load_screen(const std::wstring &text, IrrlichtDevice* device, - gui::IGUIFont* font, float dtime=0 ,int percent=0, bool clouds=true) -{ - video::IVideoDriver* driver = device->getVideoDriver(); - v2u32 screensize = driver->getScreenSize(); - const wchar_t *loadingtext = text.c_str(); - core::vector2d textsize_u = font->getDimension(loadingtext); - core::vector2d textsize(textsize_u.X,textsize_u.Y); - core::vector2d center(screensize.X/2, screensize.Y/2); - core::rect textrect(center - textsize/2, center + textsize/2); - - gui::IGUIStaticText *guitext = guienv->addStaticText( - loadingtext, textrect, false, false); - guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); - - bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); - if (cloud_menu_background) - { - g_menuclouds->step(dtime*3); - g_menuclouds->render(); - driver->beginScene(true, true, video::SColor(255,140,186,250)); - g_menucloudsmgr->drawAll(); - } - else - driver->beginScene(true, true, video::SColor(255,0,0,0)); - if (percent >= 0 && percent <= 100) // draw progress bar - { - core::vector2d barsize(256,32); - core::rect barrect(center-barsize/2, center+barsize/2); - driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border - driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect ( - barrect.UpperLeftCorner+1, - barrect.LowerRightCorner-1), NULL); // black inside the bar - driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect ( - barrect.UpperLeftCorner+1, - core::vector2d( - barrect.LowerRightCorner.X-(barsize.X-1)+percent*(barsize.X-2)/100, - barrect.LowerRightCorner.Y-1)), NULL); // the actual progress - } - guienv->drawAll(); - driver->endScene(); - - guitext->remove(); - - //return guitext; -} - /* Profiler display */ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler, @@ -1113,7 +1062,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, { wchar_t* text = wgettext("Loading..."); - draw_load_screen(text, device, font,0,0); + draw_load_screen(text, device, guienv, font, 0, 0); delete[] text; } @@ -1173,7 +1122,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, if(address == ""){ wchar_t* text = wgettext("Creating server...."); - draw_load_screen(text, device, font,0,25); + draw_load_screen(text, device, guienv, font, 0, 25); delete[] text; infostream<<"Creating server"<getRootSceneNode(), smgr, -1, client.getEnv().getLocalPlayer()); + sky = new Sky(smgr->getRootSceneNode(), smgr, -1); scene::ISceneNode* skybox = NULL; @@ -1605,7 +1553,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, */ u32 drawtime = 0; u32 beginscenetime = 0; - u32 scenetime = 0; u32 endscenetime = 0; float recent_turn_speed = 0.0; @@ -2281,7 +2228,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, else{ s32 dx = input->getMousePos().X - (driver->getScreenSize().Width/2); s32 dy = input->getMousePos().Y - (driver->getScreenSize().Height/2); - if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT) { + if(invert_mouse || camera.getCameraMode() == CAMERA_MODE_THIRD_FRONT) { dy = -dy; } //infostream<<"window active, pos difference "<wasKeyDown(getKeySetting("keymap_camera_mode"))) { + camera.toggleCameraMode(); + GenericCAO* playercao = player->getCAO(); - if (current_camera_mode == CAMERA_MODE_FIRST) - current_camera_mode = CAMERA_MODE_THIRD; - else if (current_camera_mode == CAMERA_MODE_THIRD) - current_camera_mode = CAMERA_MODE_THIRD_FRONT; - else - current_camera_mode = CAMERA_MODE_FIRST; - + assert( playercao != NULL ); + if (camera.getCameraMode() > CAMERA_MODE_FIRST) { + playercao->setVisible(true); + } + else { + playercao->setVisible(false); + } } - player->camera_mode = current_camera_mode; tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0); camera.update(player, dtime, busytime, tool_reload_ratio, - current_camera_mode, client.getEnv()); + client.getEnv()); camera.step(dtime); v3f player_position = player->getPosition(); @@ -2736,7 +2684,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, camera_position + camera_direction * BS * (d+1)); // prevent player pointing anything in front-view - if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + if (camera.getCameraMode() == CAMERA_MODE_THIRD_FRONT) shootline = core::line3d(0,0,0,0,0,0); ClientActiveObject *selected_object = NULL; @@ -3148,7 +3096,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input, + time_of_day * todsm; sky->update(time_of_day_smooth, time_brightness, direct_brightness, - sunlight_seen); + sunlight_seen,camera.getCameraMode(), player->getYaw(), + player->getPitch()); video::SColor bgcolor = sky->getBgColor(); video::SColor skycolor = sky->getSkyColor(); @@ -3417,141 +3366,22 @@ void the_game(bool &kill, bool random_input, InputHandler *input, /* Drawing begins */ - TimeTaker tt_draw("mainloop: draw"); - { TimeTaker timer("beginScene"); - //driver->beginScene(false, true, bgcolor); - //driver->beginScene(true, true, bgcolor); driver->beginScene(true, true, skycolor); beginscenetime = timer.stop(true); } + - //timer3.stop(); - - //infostream<<"smgr->drawAll()"<drawAll(); - - if(g_settings->getBool("anaglyph")) - { - irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); - irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); - - irr::core::matrix4 startMatrix = camera.getCameraNode()->getAbsoluteTransformation(); - - irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() - - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + - camera.getCameraNode()->getAbsolutePosition() ; - - //Left eye... - irr::core::vector3df leftEye; - irr::core::matrix4 leftMove; - - leftMove.setTranslation( irr::core::vector3df(-g_settings->getFloat("anaglyph_strength"),0.0f,0.0f) ); - leftEye=(startMatrix*leftMove).getTranslation(); - - //clear the depth buffer, and color - driver->beginScene( true, true, irr::video::SColor(0,200,200,255) ); - - driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED; - driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + - irr::scene::ESNRP_SOLID + - irr::scene::ESNRP_TRANSPARENT + - irr::scene::ESNRP_TRANSPARENT_EFFECT + - irr::scene::ESNRP_SHADOW; - - camera.getCameraNode()->setPosition( leftEye ); - camera.getCameraNode()->setTarget( focusPoint ); - - smgr->drawAll(); // 'smgr->drawAll();' may go here - - driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - - if (show_hud) - hud.drawSelectionBoxes(hilightboxes); - - - //Right eye... - irr::core::vector3df rightEye; - irr::core::matrix4 rightMove; - - rightMove.setTranslation( irr::core::vector3df(g_settings->getFloat("anaglyph_strength"),0.0f,0.0f) ); - rightEye=(startMatrix*rightMove).getTranslation(); - - //clear the depth buffer - driver->clearZBuffer(); - - driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN + irr::video::ECP_BLUE; - driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + - irr::scene::ESNRP_SOLID + - irr::scene::ESNRP_TRANSPARENT + - irr::scene::ESNRP_TRANSPARENT_EFFECT + - irr::scene::ESNRP_SHADOW; - - camera.getCameraNode()->setPosition( rightEye ); - camera.getCameraNode()->setTarget( focusPoint ); - - smgr->drawAll(); // 'smgr->drawAll();' may go here - - driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - - if (show_hud) - hud.drawSelectionBoxes(hilightboxes); - - - //driver->endScene(); - - driver->getOverrideMaterial().Material.ColorMask=irr::video::ECP_ALL; - driver->getOverrideMaterial().EnableFlags=0; - driver->getOverrideMaterial().EnablePasses=0; - - camera.getCameraNode()->setPosition( oldPosition ); - camera.getCameraNode()->setTarget( oldTarget ); - } - - scenetime = timer.stop(true); - } - - { - //TimeTaker timer9("auxiliary drawings"); - // 0ms - - //timer9.stop(); - //TimeTaker //timer10("//timer10"); - - video::SMaterial m; - //m.Thickness = 10; - m.Thickness = 3; - m.Lighting = false; - driver->setMaterial(m); - - driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - if((!g_settings->getBool("anaglyph")) && (show_hud)) - { - hud.drawSelectionBoxes(hilightboxes); - } - - /* - Wielded tool - */ - if(show_hud && - (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) && - current_camera_mode < CAMERA_MODE_THIRD) - { - // Warning: This clears the Z buffer. - camera.drawWieldedTool(); - } + draw_scene(driver, smgr, camera, client, player, hud, guienv, + hilightboxes, screensize, skycolor, show_hud); /* Post effects */ { - client.getEnv().getClientMap().renderPostFx(); + client.getEnv().getClientMap().renderPostFx(camera.getCameraMode()); } /* @@ -3562,26 +3392,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, graph.draw(10, screensize.Y - 10, driver, font); } - /* - Draw crosshair - */ - if (show_hud) - hud.drawCrosshair(); - - } // timer - - //timer10.stop(); - //TimeTaker //timer11("//timer11"); - - - /* - Draw hotbar - */ - if (show_hud) - { - hud.drawHotbar(client.getPlayerItem()); - } - /* Damage flash */ @@ -3605,18 +3415,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, player->hurt_tilt_strength = 0; } - /* - Draw lua hud items - */ - if (show_hud) - hud.drawLuaElements(camera.getOffset()); - - /* - Draw gui - */ - // 0-1ms - guienv->drawAll(); - /* End scene */ @@ -3659,7 +3457,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, { /*gui::IGUIStaticText *gui_shuttingdowntext = */ wchar_t* text = wgettext("Shutting down stuff..."); - draw_load_screen(text, device, font, 0, -1, false); + draw_load_screen(text, device, guienv, font, 0, -1, false); delete[] text; /*driver->beginScene(true, true, video::SColor(255,0,0,0)); guienv->drawAll(); @@ -3728,5 +3526,3 @@ void the_game(bool &kill, bool random_input, InputHandler *input, << driver-> getMaterialRendererCount () << " (note: irrlicht doesn't support removing renderers)"<< std::endl; } - - diff --git a/src/hud.cpp b/src/hud.cpp index 7b601ec87..6d0fc8a89 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -435,10 +435,6 @@ void Hud::drawHotbar(u16 playeritem) { void Hud::drawCrosshair() { - if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) || - (player->camera_mode == CAMERA_MODE_THIRD_FRONT)) { - return; - } if (use_crosshair_image) { video::ITexture *crosshair = tsrc->getTexture("crosshair.png"); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index a7a105fc5..1a238cb47 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -43,7 +43,6 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): last_pitch(0), last_yaw(0), last_keyPressed(0), - camera_mode(0), eye_offset_first(v3f(0,0,0)), eye_offset_third(v3f(0,0,0)), last_animation(NO_ANIM), @@ -54,7 +53,8 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_need_to_get_new_sneak_node(true), - m_can_jump(false) + m_can_jump(false), + m_cao(NULL) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points @@ -505,7 +505,7 @@ void LocalPlayer::applyControl(float dtime) if(control.jump) { if(free_move) - { + { if(g_settings->getBool("aux1_descends") || g_settings->getBool("always_fly_fast")) { if(fast_move) diff --git a/src/localplayer.h b/src/localplayer.h index 38e7a4cd9..bfe476b70 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include class Environment; - +class GenericCAO; class ClientActiveObject; enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both @@ -62,7 +62,6 @@ public: unsigned int last_keyPressed; float camera_impact; - int camera_mode; v3f eye_offset_first; v3f eye_offset_third; @@ -72,6 +71,15 @@ public: std::string hotbar_image; std::string hotbar_selected_image; + GenericCAO* getCAO() const { + return m_cao; + } + + void setCAO(GenericCAO* toset) { + assert( m_cao == NULL ); + m_cao = toset; + } + private: // This is used for determining the sneaking range v3s16 m_sneak_node; @@ -84,6 +92,8 @@ private: // Whether recalculation of the sneak node is needed bool m_need_to_get_new_sneak_node; bool m_can_jump; + + GenericCAO* m_cao; }; #endif diff --git a/src/sky.cpp b/src/sky.cpp index be7798407..17d8d46ce 100644 --- a/src/sky.cpp +++ b/src/sky.cpp @@ -13,7 +13,7 @@ #include "camera.h" // CameraModes //! constructor -Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player): +Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id), m_visible(true), m_fallback_bg_color(255,255,255,255), @@ -22,8 +22,7 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlay m_cloud_brightness(0.5), m_bgcolor_bright_f(1,1,1,1), m_skycolor_bright_f(1,1,1,1), - m_cloudcolor_bright_f(1,1,1,1), - m_player(player) + m_cloudcolor_bright_f(1,1,1,1) { setAutomaticCulling(scene::EAC_OFF); Box.MaxEdge.set(0,0,0); @@ -66,14 +65,14 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlay m_materials[3].setTexture(0, m_sun_texture); m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; if (m_sun_tonemap) - m_materials[3].Lighting = true; + m_materials[3].Lighting = true; } if (m_moon_texture){ m_materials[4] = mat; m_materials[4].setTexture(0, m_moon_texture); m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; if (m_moon_tonemap) - m_materials[4].Lighting = true; + m_materials[4].Lighting = true; } for(u32 i=0; ilock(); video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue()); - m_sun_tonemap->unlock(); + m_sun_tonemap->unlock(); m_materials[3].EmissiveColor = texel_color; } if (m_moon_tonemap){ u8 * texels = (u8 *)m_moon_tonemap->lock(); video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue()); - m_moon_tonemap->unlock(); + m_moon_tonemap->unlock(); m_materials[4].EmissiveColor = texel_color; } @@ -263,7 +262,7 @@ void Sky::render() } // Draw sun - if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85){ + if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85){ if (!m_sun_texture){ driver->setMaterial(m_materials[1]); float d = sunsize * 1.7; @@ -411,7 +410,7 @@ void Sky::render() vertices[i].Pos.rotateXZBy(-90); vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90); } - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); } } @@ -485,7 +484,8 @@ void Sky::render() } void Sky::update(float time_of_day, float time_brightness, - float direct_brightness, bool sunlight_seen) + float direct_brightness, bool sunlight_seen, + CameraMode cam_mode, float yaw, float pitch) { // Stabilize initial brightness and color values by flooding updates if(m_first_update){ @@ -496,7 +496,7 @@ void Sky::update(float time_of_day, float time_brightness, m_first_update = false; for(u32 i=0; i<100; i++){ update(time_of_day, time_brightness, direct_brightness, - sunlight_seen); + sunlight_seen, cam_mode, yaw, pitch); } return; } @@ -580,16 +580,16 @@ void Sky::update(float time_of_day, float time_brightness, { // calculate hemisphere value from yaw, (inverted in third person front view) s8 dir_factor = 1; - if (m_player->camera_mode > CAMERA_MODE_THIRD) + if (cam_mode > CAMERA_MODE_THIRD) dir_factor = -1; - f32 pointcolor_blend = wrapDegrees_0_360(m_player->getYaw()*dir_factor + 90); + f32 pointcolor_blend = wrapDegrees_0_360( yaw*dir_factor + 90); if (pointcolor_blend > 180) pointcolor_blend = 360 - pointcolor_blend; pointcolor_blend /= 180; // bound view angle to determine where transition starts and ends pointcolor_blend = rangelim(1 - pointcolor_blend * 1.375, 0, 1 / 1.375) * 1.375; // combine the colors when looking up or down, otherwise turning looks weird - pointcolor_blend += (0.5 - pointcolor_blend) * (1 - MYMIN((90 - std::abs(m_player->getPitch())) / 90 * 1.5, 1)); + pointcolor_blend += (0.5 - pointcolor_blend) * (1 - MYMIN((90 - std::abs(pitch)) / 90 * 1.5, 1)); // invert direction to match where the sun and moon are rising if (m_time_of_day > 0.5) pointcolor_blend = 1 - pointcolor_blend; diff --git a/src/sky.h b/src/sky.h index aaa2faf57..d7dabedb8 100644 --- a/src/sky.h +++ b/src/sky.h @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include -#include "localplayer.h" +#include "camera.h" #ifndef SKY_HEADER #define SKY_HEADER @@ -32,7 +32,7 @@ class Sky : public scene::ISceneNode { public: //! constructor - Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, LocalPlayer* player); + Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id); virtual void OnRegisterSceneNode(); @@ -50,7 +50,8 @@ public: { return SKY_MATERIAL_COUNT; } void update(float m_time_of_day, float time_brightness, - float direct_brightness, bool sunlight_seen); + float direct_brightness, bool sunlight_seen, CameraMode cam_mode, + float yaw, float pitch); float getBrightness(){ return m_brightness; } @@ -126,7 +127,6 @@ private: video::SColorf m_cloudcolor_f; v3f m_stars[SKY_STAR_COUNT]; video::S3DVertex m_star_vertices[SKY_STAR_COUNT*4]; - LocalPlayer* m_player; video::ITexture* m_sun_texture; video::ITexture* m_moon_texture; video::ITexture* m_sun_tonemap;