diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 1ca5f16dc..79a64c2db 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -279,6 +279,9 @@ enable_clouds (Clouds) bool true # Use 3D cloud look instead of flat. enable_3d_clouds (3D clouds) bool true +# Method used to highlight selected object. +node_highlighting (Node highlighting) enum box box,halo + [***Filtering] # Use mip mapping to scale textures. May slightly increase performance. @@ -482,9 +485,6 @@ desynchronize_mapblock_texture_animation (Desynchronize block animation) bool tr # Useful if there's something to be displayed right or left of hotbar. hud_hotbar_max_width (Maximum hotbar width) float 1.0 -# Enable selection highlighting for nodes (disables selectionbox). -enable_node_highlighting (Node highlighting) bool false - # Enables caching of facedir rotated meshes. enable_mesh_cache (Mesh cache) bool false diff --git a/client/shaders/default_shader/opengl_fragment.glsl b/client/shaders/default_shader/opengl_fragment.glsl new file mode 100644 index 000000000..925ab6e1d --- /dev/null +++ b/client/shaders/default_shader/opengl_fragment.glsl @@ -0,0 +1,4 @@ +void main(void) +{ + gl_FragColor = gl_Color; +} diff --git a/client/shaders/default_shader/opengl_vertex.glsl b/client/shaders/default_shader/opengl_vertex.glsl new file mode 100644 index 000000000..0f4609177 --- /dev/null +++ b/client/shaders/default_shader/opengl_vertex.glsl @@ -0,0 +1,9 @@ +uniform mat4 mWorldViewProj; + +void main(void) +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = mWorldViewProj * gl_Vertex; + + gl_FrontColor = gl_BackColor = gl_Color; +} diff --git a/client/shaders/selection_shader/opengl_fragment.glsl b/client/shaders/selection_shader/opengl_fragment.glsl new file mode 100644 index 000000000..c679d0e12 --- /dev/null +++ b/client/shaders/selection_shader/opengl_fragment.glsl @@ -0,0 +1,9 @@ +uniform sampler2D baseTexture; + +void main(void) +{ + vec2 uv = gl_TexCoord[0].st; + vec4 color = texture2D(baseTexture, uv); + color.rgb *= gl_Color.rgb; + gl_FragColor = color; +} diff --git a/client/shaders/selection_shader/opengl_vertex.glsl b/client/shaders/selection_shader/opengl_vertex.glsl new file mode 100644 index 000000000..0f4609177 --- /dev/null +++ b/client/shaders/selection_shader/opengl_vertex.glsl @@ -0,0 +1,9 @@ +uniform mat4 mWorldViewProj; + +void main(void) +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = mWorldViewProj * gl_Vertex; + + gl_FrontColor = gl_BackColor = gl_Color; +} diff --git a/minetest.conf.example b/minetest.conf.example index 198b93238..1bf56720e 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -555,9 +555,9 @@ # type: float # hud_hotbar_max_width = 1.0 -# Enable selection highlighting for nodes (disables selectionbox). -# type: bool -# enable_node_highlighting = false +# Selection highlighting method (box or halo) +# type: string +# node_highlighting = box # Enables caching of facedir rotated meshes. # type: bool diff --git a/src/client.cpp b/src/client.cpp index 8e49ee3ba..a845277bd 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -235,11 +235,9 @@ Client::Client( m_inventory_updated(false), m_inventory_from_server(NULL), m_inventory_from_server_age(0.0), - m_show_highlighted(false), m_animation_time(0), m_crack_level(-1), m_crack_pos(0,0,0), - m_highlighted_pos(0,0,0), m_map_seed(0), m_password(password), m_chosen_auth_mech(AUTH_MECHANISM_NONE), @@ -1508,15 +1506,6 @@ int Client::getCrackLevel() return m_crack_level; } -void Client::setHighlighted(v3s16 pos, bool show_highlighted) -{ - m_show_highlighted = show_highlighted; - v3s16 old_highlighted_pos = m_highlighted_pos; - m_highlighted_pos = pos; - addUpdateMeshTaskForNode(old_highlighted_pos, false, true); - addUpdateMeshTaskForNode(m_highlighted_pos, false, true); -} - void Client::setCrack(int level, v3s16 pos) { int old_crack_level = m_crack_level; @@ -1601,7 +1590,6 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent) // Debug: 1-6ms, avg=2ms data->fill(b); data->setCrack(m_crack_level, m_crack_pos); - data->setHighlighted(m_highlighted_pos, m_show_highlighted); data->setSmoothLighting(m_cache_smooth_lighting); } diff --git a/src/client.h b/src/client.h index 07fb79dca..98a8bc129 100644 --- a/src/client.h +++ b/src/client.h @@ -456,9 +456,6 @@ public: int getCrackLevel(); void setCrack(int level, v3s16 pos); - void setHighlighted(v3s16 pos, bool show_higlighted); - v3s16 getHighlighted(){ return m_highlighted_pos; } - u16 getHP(); u16 getBreath(); @@ -609,12 +606,10 @@ private: Inventory *m_inventory_from_server; float m_inventory_from_server_age; PacketCounter m_packetcounter; - bool m_show_highlighted; // Block mesh animation parameters float m_animation_time; int m_crack_level; v3s16 m_crack_pos; - v3s16 m_highlighted_pos; // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT //s32 m_daynight_i; //u32 m_daynight_ratio; diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 01a06b6cd..ab8091dee 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -171,7 +171,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, MeshCollector &collector) { INodeDefManager *nodedef = data->m_gamedef->ndef(); - ITextureSource *tsrc = data->m_gamedef->tsrc(); scene::ISceneManager* smgr = data->m_gamedef->getSceneManager(); scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator(); @@ -1615,55 +1614,5 @@ void mapblock_mesh_generate_special(MeshMakeData *data, break;} } } - - /* - Caused by incorrect alpha blending, selection mesh needs to be created as - last element to ensure it gets blended correct over nodes with alpha channel - */ - // Create selection mesh - v3s16 p = data->m_highlighted_pos_relative; - if (data->m_show_hud && - (p.X >= 0) && (p.X < MAP_BLOCKSIZE) && - (p.Y >= 0) && (p.Y < MAP_BLOCKSIZE) && - (p.Z >= 0) && (p.Z < MAP_BLOCKSIZE)) { - - MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); - if(n.getContent() != CONTENT_AIR) { - // Get selection mesh light level - static const v3s16 dirs[7] = { - v3s16( 0, 0, 0), - v3s16( 0, 1, 0), - v3s16( 0,-1, 0), - v3s16( 1, 0, 0), - v3s16(-1, 0, 0), - v3s16( 0, 0, 1), - v3s16( 0, 0,-1) - }; - - u16 l = 0; - u16 l1 = 0; - for (u8 i = 0; i < 7; i++) { - MapNode n1 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dirs[i]); - l1 = getInteriorLight(n1, -4, nodedef); - if (l1 > l) - l = l1; - } - video::SColor c = MapBlock_LightColor(255, l, 0); - data->m_highlight_mesh_color = c; - std::vector boxes = n.getSelectionBoxes(nodedef); - TileSpec h_tile; - h_tile.material_flags |= MATERIAL_FLAG_HIGHLIGHTED; - h_tile.texture = tsrc->getTextureForMesh("halo.png",&h_tile.texture_id); - v3f pos = intToFloat(p, BS); - f32 d = 0.05 * BS; - for (std::vector::iterator i = boxes.begin(); - i != boxes.end(); ++i) { - aabb3f box = *i; - box.MinEdge += v3f(-d, -d, -d) + pos; - box.MaxEdge += v3f(d, d, d) + pos; - makeCuboid(&collector, box, &h_tile, 1, c, NULL); - } - } - } } diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 669987d00..ddd7b5fe1 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -137,8 +137,9 @@ void set_default_settings(Settings *settings) settings->setDefault("console_color", "(0,0,0)"); settings->setDefault("console_alpha", "200"); settings->setDefault("selectionbox_color", "(0,0,0)"); - settings->setDefault("enable_node_highlighting", "false"); + settings->setDefault("selectionbox_width", "2"); settings->setDefault("inventory_items_animations", "false"); + settings->setDefault("node_highlighting", "box"); settings->setDefault("crosshair_color", "(255,255,255)"); settings->setDefault("crosshair_alpha", "255"); settings->setDefault("hud_scaling", "1.0"); @@ -149,8 +150,7 @@ void set_default_settings(Settings *settings) settings->setDefault("enable_sound", "true"); settings->setDefault("sound_volume", "0.8"); settings->setDefault("desynchronize_mapblock_texture_animation", "true"); - settings->setDefault("selectionbox_width","2"); - settings->setDefault("hud_hotbar_max_width","1.0"); + settings->setDefault("hud_hotbar_max_width", "1.0"); settings->setDefault("enable_local_map_saving", "false"); settings->setDefault("mip_map", "false"); diff --git a/src/drawscene.cpp b/src/drawscene.cpp index c716ca0d4..32eafeb29 100644 --- a/src/drawscene.cpp +++ b/src/drawscene.cpp @@ -31,27 +31,9 @@ typedef enum { EYECOUNT = 2 } paralax_sign; - -void draw_selectionbox(video::IVideoDriver* driver, Hud& hud, - std::vector& hilightboxes, bool show_hud) -{ - static const s16 selectionbox_width = rangelim(g_settings->getS16("selectionbox_width"), 1, 5); - - if (!show_hud) - return; - - video::SMaterial oldmaterial = driver->getMaterial2D(); - video::SMaterial m; - m.Thickness = selectionbox_width; - 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, + video::IVideoDriver* driver, scene::ISceneManager* smgr, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv ) { @@ -85,10 +67,8 @@ void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud, camera.getCameraNode()->setTarget(focusPoint); smgr->drawAll(); driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - if (show_hud) - { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + if (show_hud) { + hud.drawSelectionMesh(); if (draw_wield_tool) camera.drawWieldedTool(&leftMove); } @@ -115,10 +95,8 @@ void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud, camera.getCameraNode()->setTarget(focusPoint); smgr->drawAll(); driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - if (show_hud) - { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + if (show_hud) { + hud.drawSelectionMesh(); if (draw_wield_tool) camera.drawWieldedTool(&rightMove); } @@ -144,16 +122,15 @@ void init_texture(video::IVideoDriver* driver, const v2u32& screensize, irr::video::ECF_A8R8G8B8); } -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 ) +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, bool draw_wield_tool, Client &client, + gui::IGUIEnvironment *guienv, const video::SColor &skycolor) { static video::ITexture* images[2] = { NULL, NULL }; - static v2u32 last_screensize = v2u32(0,0); + static v2u32 last_screensize = v2u32(0, 0); video::ITexture* image = NULL; @@ -187,10 +164,8 @@ video::ITexture* draw_image(const v2u32& screensize, driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - if (show_hud) - { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + if (show_hud) { + hud.drawSelectionMesh(); if (draw_wield_tool) camera.drawWieldedTool(&movement); } @@ -232,7 +207,7 @@ video::ITexture* draw_hud(video::IVideoDriver* driver, const v2u32& screensize, } void draw_interlaced_3d_mode(Camera& camera, bool show_hud, - Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + Hud& hud, video::IVideoDriver* driver, scene::ISceneManager* smgr, const v2u32& screensize, bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, video::SColor skycolor ) @@ -248,7 +223,7 @@ void draw_interlaced_3d_mode(Camera& camera, bool show_hud, /* create left view */ video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, - focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + focusPoint, show_hud, driver, camera, smgr, hud, draw_wield_tool, client, guienv, skycolor); //Right eye... @@ -267,10 +242,8 @@ void draw_interlaced_3d_mode(Camera& camera, bool show_hud, driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - if (show_hud) - { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + if (show_hud) { + hud.drawSelectionMesh(); if(draw_wield_tool) camera.drawWieldedTool(&rightMove); } @@ -293,7 +266,7 @@ void draw_interlaced_3d_mode(Camera& camera, bool show_hud, } void draw_sidebyside_3d_mode(Camera& camera, bool show_hud, - Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + Hud& hud, video::IVideoDriver* driver, scene::ISceneManager* smgr, const v2u32& screensize, bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, video::SColor skycolor ) @@ -309,12 +282,12 @@ void draw_sidebyside_3d_mode(Camera& camera, bool show_hud, /* create left view */ video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, - focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + focusPoint, show_hud, driver, camera, smgr, hud, 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, + focusPoint, show_hud, driver, camera, smgr, hud, draw_wield_tool, client, guienv, skycolor); /* create hud overlay */ @@ -349,7 +322,7 @@ void draw_sidebyside_3d_mode(Camera& camera, bool show_hud, } void draw_top_bottom_3d_mode(Camera& camera, bool show_hud, - Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + Hud& hud, video::IVideoDriver* driver, scene::ISceneManager* smgr, const v2u32& screensize, bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, video::SColor skycolor ) @@ -365,12 +338,12 @@ void draw_top_bottom_3d_mode(Camera& camera, bool show_hud, /* create left view */ video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix, - focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes, + focusPoint, show_hud, driver, camera, smgr, hud, 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, + focusPoint, show_hud, driver, camera, smgr, hud, draw_wield_tool, client, guienv, skycolor); /* create hud overlay */ @@ -405,7 +378,7 @@ void draw_top_bottom_3d_mode(Camera& camera, bool show_hud, } void draw_pageflip_3d_mode(Camera& camera, bool show_hud, - Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + Hud& hud, video::IVideoDriver* driver, scene::ISceneManager* smgr, const v2u32& screensize, bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, video::SColor skycolor) @@ -438,11 +411,9 @@ void draw_pageflip_3d_mode(Camera& camera, bool show_hud, driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); if (show_hud) { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + hud.drawSelectionMesh(); if (draw_wield_tool) camera.drawWieldedTool(&leftMove); - hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); } @@ -467,11 +438,9 @@ void draw_pageflip_3d_mode(Camera& camera, bool show_hud, driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); if (show_hud) { - draw_selectionbox(driver, hud, hilightboxes, show_hud); - + hud.drawSelectionMesh(); if (draw_wield_tool) camera.drawWieldedTool(&rightMove); - hud.drawHotbar(client.getPlayerItem()); hud.drawLuaElements(camera.getOffset()); } @@ -482,23 +451,24 @@ void draw_pageflip_3d_mode(Camera& camera, bool show_hud, 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) +void draw_plain(Camera &camera, bool show_hud, Hud &hud, + video::IVideoDriver *driver, bool draw_wield_tool, + Client &client, gui::IGUIEnvironment *guienv) { driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - - draw_selectionbox(driver, hud, hilightboxes, show_hud); - - if(draw_wield_tool) - camera.drawWieldedTool(); + if (show_hud) { + hud.drawSelectionMesh(); + if (draw_wield_tool) { + camera.drawWieldedTool(); + } + } } void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr, Camera &camera, Client& client, LocalPlayer *player, Hud &hud, Mapper &mapper, gui::IGUIEnvironment *guienv, - std::vector hilightboxes, const v2u32 &screensize, - video::SColor skycolor, bool show_hud, bool show_minimap) + const v2u32 &screensize, const video::SColor &skycolor, + bool show_hud, bool show_minimap) { TimeTaker timer("smgr"); @@ -522,37 +492,37 @@ void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr, if (draw_mode == "anaglyph") { - draw_anaglyph_3d_mode(camera, show_hud, hud, hilightboxes, driver, + draw_anaglyph_3d_mode(camera, show_hud, hud, 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, + draw_interlaced_3d_mode(camera, show_hud, hud, 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, + draw_sidebyside_3d_mode(camera, show_hud, hud, 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, + draw_top_bottom_3d_mode(camera, show_hud, hud, driver, smgr, screensize, draw_wield_tool, client, guienv, skycolor); show_hud = false; } else if (draw_mode == "pageflip") { - draw_pageflip_3d_mode(camera, show_hud, hud, hilightboxes, driver, + draw_pageflip_3d_mode(camera, show_hud, hud, driver, smgr, screensize, draw_wield_tool, client, guienv, skycolor); draw_crosshair = false; show_hud = false; } else { - draw_plain(camera, show_hud, hud, hilightboxes, driver, + draw_plain(camera, show_hud, hud, driver, draw_wield_tool, client, guienv); } diff --git a/src/drawscene.h b/src/drawscene.h index 0630f2970..364fcd499 100644 --- a/src/drawscene.h +++ b/src/drawscene.h @@ -31,9 +31,9 @@ void draw_load_screen(const std::wstring &text, IrrlichtDevice *device, bool clouds = true); void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr, - Camera &camera, Client &client, LocalPlayer *player, Hud &hud, - Mapper &mapper, gui::IGUIEnvironment *guienv, - std::vector hilightboxes, const v2u32 &screensize, - video::SColor skycolor, bool show_hud, bool show_minimap); + Camera &camera, Client &client, LocalPlayer *player, + Hud &hud, Mapper &mapper, gui::IGUIEnvironment *guienv, + const v2u32 &screensize, const video::SColor &skycolor, + bool show_hud, bool show_minimap); #endif /* DRAWSCENE_H_ */ diff --git a/src/game.cpp b/src/game.cpp index 3902c50bb..cae468d4c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -57,6 +57,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/pointedthing.h" #include "version.h" #include "minimap.h" +#include "mapblock_mesh.h" #include "sound.h" @@ -288,14 +289,16 @@ inline bool isPointableNode(const MapNode &n, /* Find what the player is pointing at */ -PointedThing getPointedThing(Client *client, v3f player_position, - v3f camera_direction, v3f camera_position, core::line3d shootline, - f32 d, bool liquids_pointable, bool look_for_object, v3s16 camera_offset, - std::vector &hilightboxes, ClientActiveObject *&selected_object) +PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_position, + const v3f &camera_direction, const v3f &camera_position, + core::line3d shootline, f32 d, bool liquids_pointable, + bool look_for_object, const v3s16 &camera_offset, + ClientActiveObject *&selected_object) { PointedThing result; - hilightboxes.clear(); + std::vector *selectionboxes = hud->getSelectionBoxes(); + selectionboxes->clear(); selected_object = NULL; INodeDefManager *nodedef = client->getNodeDefManager(); @@ -316,9 +319,9 @@ PointedThing getPointedThing(Client *client, v3f player_position, assert(selection_box); v3f pos = selected_object->getPosition(); - hilightboxes.push_back(aabb3f( - selection_box->MinEdge + pos - intToFloat(camera_offset, BS), - selection_box->MaxEdge + pos - intToFloat(camera_offset, BS))); + selectionboxes->push_back(aabb3f( + selection_box->MinEdge, selection_box->MaxEdge)); + hud->setSelectionPos(pos, camera_offset); } mindistance = (selected_object->getPosition() - camera_position).getLength(); @@ -414,22 +417,56 @@ PointedThing getPointedThing(Client *client, v3f player_position, result.node_abovesurface = np_above; mindistance = distance; - hilightboxes.clear(); - - if (!g_settings->getBool("enable_node_highlighting")) { - for (std::vector::const_iterator - i2 = boxes.begin(); - i2 != boxes.end(); ++i2) { - aabb3f box = *i2; - box.MinEdge += npf + v3f(-d, -d, -d) - intToFloat(camera_offset, BS); - box.MaxEdge += npf + v3f(d, d, d) - intToFloat(camera_offset, BS); - hilightboxes.push_back(box); - } + selectionboxes->clear(); + for (std::vector::const_iterator + i2 = boxes.begin(); + i2 != boxes.end(); ++i2) { + aabb3f box = *i2; + box.MinEdge += v3f(-d, -d, -d); + box.MaxEdge += v3f(d, d, d); + selectionboxes->push_back(box); } + hud->setSelectionPos(npf, camera_offset); } } } // for coords + // Update selection mesh light level and vertex colors + if (selectionboxes->size() > 0) { + v3f pf = hud->getSelectionPos(); + v3s16 p = floatToInt(pf, BS); + + // Get selection mesh light level + MapNode n = map.getNodeNoEx(p); + u16 node_light = getInteriorLight(n, -1, nodedef); + u16 light_level = node_light; + + for (u8 i = 0; i < 6; i++) { + n = map.getNodeNoEx(p + g_6dirs[i]); + node_light = getInteriorLight(n, -1, nodedef); + if (node_light > light_level) + light_level = node_light; + } + + video::SColor c = MapBlock_LightColor(255, light_level, 0); + u8 day = c.getRed(); + u8 night = c.getGreen(); + u32 daynight_ratio = client->getEnv().getDayNightRatio(); + finalColorBlend(c, day, night, daynight_ratio); + + // Modify final color a bit with time + u32 timer = porting::getTimeMs() % 5000; + float timerf = (float)(irr::core::PI * ((timer / 2500.0) - 0.5)); + float sin_r = 0.08 * sin(timerf); + float sin_g = 0.08 * sin(timerf + irr::core::PI * 0.5); + float sin_b = 0.08 * sin(timerf + irr::core::PI); + c.setRed(core::clamp(core::round32(c.getRed() * (0.8 + sin_r)), 0, 255)); + c.setGreen(core::clamp(core::round32(c.getGreen() * (0.8 + sin_g)), 0, 255)); + c.setBlue(core::clamp(core::round32(c.getBlue() * (0.8 + sin_b)), 0, 255)); + + // Set mesh final color + hud->setSelectionMeshColor(c); + } return result; } @@ -1522,8 +1559,7 @@ protected: void updateCamera(VolatileRunFlags *flags, u32 busy_time, f32 dtime, float time_from_last_punch); void updateSound(f32 dtime); - void processPlayerInteraction(std::vector &highlight_boxes, - GameRunData *runData, f32 dtime, bool show_hud, + void processPlayerInteraction(GameRunData *runData, f32 dtime, bool show_hud, bool show_debug); void handlePointingAtNothing(GameRunData *runData, const ItemStack &playerItem); void handlePointingAtNode(GameRunData *runData, @@ -1535,8 +1571,7 @@ protected: void handleDigging(GameRunData *runData, const PointedThing &pointed, const v3s16 &nodepos, const ToolCapabilities &playeritem_toolcap, f32 dtime); - void updateFrame(std::vector &highlight_boxes, ProfilerGraph *graph, - RunStats *stats, GameRunData *runData, + void updateFrame(ProfilerGraph *graph, RunStats *stats, GameRunData *runData, f32 dtime, const VolatileRunFlags &flags, const CameraOrientation &cam); void updateGui(float *statustext_time, const RunStats &stats, const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags, @@ -1630,7 +1665,6 @@ private: * a later release. */ bool m_cache_doubletap_jump; - bool m_cache_enable_node_highlighting; bool m_cache_enable_clouds; bool m_cache_enable_particles; bool m_cache_enable_fog; @@ -1668,8 +1702,6 @@ Game::Game() : { g_settings->registerChangedCallback("doubletap_jump", &settingChangedCallback, this); - g_settings->registerChangedCallback("enable_node_highlighting", - &settingChangedCallback, this); g_settings->registerChangedCallback("enable_clouds", &settingChangedCallback, this); g_settings->registerChangedCallback("enable_particles", @@ -1719,8 +1751,6 @@ Game::~Game() g_settings->deregisterChangedCallback("doubletap_jump", &settingChangedCallback, this); - g_settings->deregisterChangedCallback("enable_node_highlighting", - &settingChangedCallback, this); g_settings->deregisterChangedCallback("enable_clouds", &settingChangedCallback, this); g_settings->deregisterChangedCallback("enable_particles", @@ -1807,8 +1837,6 @@ void Game::run() &runData.fog_range, client)); - std::vector highlight_boxes; - set_light_table(g_settings->getFloat("display_gamma")); #ifdef __ANDROID__ @@ -1858,10 +1886,9 @@ void Game::run() updateCamera(&flags, draw_times.busy_time, dtime, runData.time_from_last_punch); updateSound(dtime); - processPlayerInteraction(highlight_boxes, &runData, dtime, - flags.show_hud, flags.show_debug); - updateFrame(highlight_boxes, &graph, &stats, &runData, dtime, - flags, cam_view); + processPlayerInteraction(&runData, dtime, flags.show_hud, + flags.show_debug); + updateFrame(&graph, &stats, &runData, dtime, flags, cam_view); updateProfilerGraphs(&graph); // Update if minimap has been disabled by the server @@ -2888,8 +2915,6 @@ void Game::toggleHud(float *statustext_time, bool *flag) *flag = !*flag; *statustext_time = 0; statustext = msg[*flag]; - if (g_settings->getBool("enable_node_highlighting")) - client->setHighlighted(client->getHighlighted(), *flag); } void Game::toggleMinimap(float *statustext_time, bool *flag, @@ -3475,8 +3500,8 @@ void Game::updateSound(f32 dtime) } -void Game::processPlayerInteraction(std::vector &highlight_boxes, - GameRunData *runData, f32 dtime, bool show_hud, bool show_debug) +void Game::processPlayerInteraction(GameRunData *runData, + f32 dtime, bool show_hud, bool show_debug) { LocalPlayer *player = client->getEnv().getLocalPlayer(); @@ -3534,25 +3559,17 @@ void Game::processPlayerInteraction(std::vector &highlight_boxes, PointedThing pointed = getPointedThing( // input - client, player_position, camera_direction, + client, hud, player_position, camera_direction, camera_position, shootline, d, playeritem_def.liquids_pointable, !runData->ldown_for_dig, camera_offset, // output - highlight_boxes, runData->selected_object); if (pointed != runData->pointed_old) { infostream << "Pointing at " << pointed.dump() << std::endl; - - if (m_cache_enable_node_highlighting) { - if (pointed.type == POINTEDTHING_NODE) { - client->setHighlighted(pointed.node_undersurface, show_hud); - } else { - client->setHighlighted(pointed.node_undersurface, false); - } - } + hud->updateSelectionMesh(camera_offset); } /* @@ -3576,6 +3593,7 @@ void Game::processPlayerInteraction(std::vector &highlight_boxes, infostream << "Pointing away from node" << " (stopped digging)" << std::endl; runData->digging = false; + hud->updateSelectionMesh(camera_offset); } } @@ -3900,9 +3918,9 @@ void Game::handleDigging(GameRunData *runData, } -void Game::updateFrame(std::vector &highlight_boxes, - ProfilerGraph *graph, RunStats *stats, GameRunData *runData, - f32 dtime, const VolatileRunFlags &flags, const CameraOrientation &cam) +void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, + GameRunData *runData, f32 dtime, const VolatileRunFlags &flags, + const CameraOrientation &cam) { LocalPlayer *player = client->getEnv().getLocalPlayer(); @@ -4094,7 +4112,7 @@ void Game::updateFrame(std::vector &highlight_boxes, } draw_scene(driver, smgr, *camera, *client, player, *hud, *mapper, - guienv, highlight_boxes, screensize, skycolor, flags.show_hud, + guienv, screensize, skycolor, flags.show_hud, flags.show_minimap); /* @@ -4374,7 +4392,6 @@ void Game::settingChangedCallback(const std::string &setting_name, void *data) void Game::readSettings() { m_cache_doubletap_jump = g_settings->getBool("doubletap_jump"); - m_cache_enable_node_highlighting = g_settings->getBool("enable_node_highlighting"); m_cache_enable_clouds = g_settings->getBool("enable_clouds"); m_cache_enable_particles = g_settings->getBool("enable_particles"); m_cache_enable_fog = g_settings->getBool("enable_fog"); diff --git a/src/hud.cpp b/src/hud.cpp index 1c144b021..0a77a1a28 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "fontengine.h" #include "guiscalingfilter.h" +#include "mesh.h" #include #ifdef HAVE_TOUCHSCREENGUI @@ -80,6 +81,39 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, use_hotbar_image = false; hotbar_selected_image = ""; use_hotbar_selected_image = false; + + m_selection_mesh = NULL; + m_selection_boxes.clear(); + m_selection_pos = v3f(0.0, 0.0, 0.0); + std::string mode = g_settings->get("node_highlighting"); + m_selection_material.Lighting = false; + + if (g_settings->getBool("enable_shaders")) { + IShaderSource *shdrsrc = gamedef->getShaderSource(); + u16 shader_id = shdrsrc->getShader( + mode == "halo" ? "selection_shader" : "default_shader", 1, 1); + m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material; + } else { + m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + } + + if (mode == "box") { + m_use_selection_mesh = false; + m_selection_material.Thickness = + rangelim(g_settings->getS16("selectionbox_width"), 1, 5); + } else if (mode == "halo") { + m_use_selection_mesh = true; + m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png")); + m_selection_material.setFlag(video::EMF_BACK_FACE_CULLING, true); + } else { + m_selection_material.MaterialType = video::EMT_SOLID; + } +} + +Hud::~Hud() +{ + if (m_selection_mesh) + m_selection_mesh->drop(); } void Hud::drawItem(const ItemStack &item, const core::rect& rect, @@ -239,7 +273,7 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset, } -void Hud::drawLuaElements(v3s16 camera_offset) { +void Hud::drawLuaElements(const v3s16 &camera_offset) { u32 text_height = g_fontengine->getTextHeight(); irr::gui::IGUIFont* font = g_fontengine->getFont(); for (size_t i = 0; i != player->maxHudId(); i++) { @@ -466,15 +500,85 @@ void Hud::drawCrosshair() { } } - -void Hud::drawSelectionBoxes(std::vector &hilightboxes) { - for (std::vector::const_iterator - i = hilightboxes.begin(); - i != hilightboxes.end(); ++i) { - driver->draw3DBox(*i, selectionbox_argb); +void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset) +{ + m_camera_offset = camera_offset; + m_selection_pos = pos; + m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS); +} + +void Hud::drawSelectionMesh() +{ + if (!m_use_selection_mesh) { + // Draw 3D selection boxes + video::SMaterial oldmaterial = driver->getMaterial2D(); + driver->setMaterial(m_selection_material); + for (std::vector::const_iterator + i = m_selection_boxes.begin(); + i != m_selection_boxes.end(); ++i) { + aabb3f box = aabb3f( + i->MinEdge + m_selection_pos_with_offset, + i->MaxEdge + m_selection_pos_with_offset); + + u32 r = (selectionbox_argb.getRed() * + m_selection_mesh_color.getRed() / 255); + u32 g = (selectionbox_argb.getGreen() * + m_selection_mesh_color.getGreen() / 255); + u32 b = (selectionbox_argb.getBlue() * + m_selection_mesh_color.getBlue() / 255); + driver->draw3DBox(box, video::SColor(255, r, g, b)); + } + driver->setMaterial(oldmaterial); + } else if (m_selection_mesh) { + // Draw selection mesh + video::SMaterial oldmaterial = driver->getMaterial2D(); + driver->setMaterial(m_selection_material); + setMeshColor(m_selection_mesh, m_selection_mesh_color); + scene::IMesh* mesh = cloneMesh(m_selection_mesh); + translateMesh(mesh, m_selection_pos_with_offset); + u32 mc = m_selection_mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; i++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + driver->drawMeshBuffer(buf); + } + mesh->drop(); + driver->setMaterial(oldmaterial); } } +void Hud::updateSelectionMesh(const v3s16 &camera_offset) +{ + m_camera_offset = camera_offset; + if (!m_use_selection_mesh) + return; + + if (m_selection_mesh) { + m_selection_mesh->drop(); + m_selection_mesh = NULL; + } + + if (!m_selection_boxes.size()) { + // No pointed object + return; + } + + // New pointed object, create new mesh. + + // Texture UV coordinates for selection boxes + static f32 texture_uv[24] = { + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1 + }; + + m_selection_mesh = convertNodeboxesToMesh(m_selection_boxes, texture_uv); + + // scale final halo mesh + scaleMesh(m_selection_mesh, v3f(1.08, 1.08, 1.08)); +} void Hud::resizeHotbar() { if (m_screensize != porting::getWindowSize()) { diff --git a/src/hud.h b/src/hud.h index f373d4fe2..d0158b2f8 100644 --- a/src/hud.h +++ b/src/hud.h @@ -119,17 +119,31 @@ public: bool use_hotbar_image; std::string hotbar_selected_image; bool use_hotbar_selected_image; - v3s16 camera_offset; Hud(video::IVideoDriver *driver,scene::ISceneManager* smgr, gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player, Inventory *inventory); + ~Hud(); void drawHotbar(u16 playeritem); void resizeHotbar(); void drawCrosshair(); - void drawSelectionBoxes(std::vector &hilightboxes); - void drawLuaElements(v3s16 camera_offset); + void drawSelectionMesh(); + void updateSelectionMesh(const v3s16 &camera_offset); + + std::vector *getSelectionBoxes() + { return &m_selection_boxes; } + + void setSelectionPos(const v3f &pos, const v3s16 &camera_offset); + + v3f getSelectionPos() const + { return m_selection_pos; } + + void setSelectionMeshColor(const video::SColor &c) + { m_selection_mesh_color = c; } + + void drawLuaElements(const v3s16 &camera_offset); + private: void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count, v2s32 offset, v2s32 size=v2s32()); @@ -140,11 +154,21 @@ private: void drawItem(const ItemStack &item, const core::rect& rect, bool selected); + v3s16 m_camera_offset; v2u32 m_screensize; v2s32 m_displaycenter; s32 m_hotbar_imagesize; s32 m_padding; video::SColor hbar_colors[4]; + + std::vector m_selection_boxes; + v3f m_selection_pos; + v3f m_selection_pos_with_offset; + + scene::IMesh* m_selection_mesh; + video::SColor m_selection_mesh_color; + video::SMaterial m_selection_material; + bool m_use_selection_mesh; }; enum ItemRotationKind { diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 9bcc4fa6a..9486220e0 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -47,10 +47,8 @@ MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders): m_vmanip(), m_blockpos(-1337,-1337,-1337), m_crack_pos_relative(-1337, -1337, -1337), - m_highlighted_pos_relative(-1337, -1337, -1337), m_smooth_lighting(false), m_show_hud(false), - m_highlight_mesh_color(255, 255, 255, 255), m_gamedef(gamedef), m_use_shaders(use_shaders) {} @@ -138,12 +136,6 @@ void MeshMakeData::setCrack(int crack_level, v3s16 crack_pos) m_crack_pos_relative = crack_pos - m_blockpos*MAP_BLOCKSIZE; } -void MeshMakeData::setHighlighted(v3s16 highlighted_pos, bool show_hud) -{ - m_show_hud = show_hud; - m_highlighted_pos_relative = highlighted_pos - m_blockpos*MAP_BLOCKSIZE; -} - void MeshMakeData::setSmoothLighting(bool smooth_lighting) { m_smooth_lighting = smooth_lighting; @@ -1036,12 +1028,10 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): m_animation_force_timer(0), // force initial animation m_last_crack(-1), m_crack_materials(), - m_highlighted_materials(), m_last_daynight_ratio((u32) -1), m_daynight_diffs() { m_enable_shaders = data->m_use_shaders; - m_enable_highlighting = g_settings->getBool("enable_node_highlighting"); if (g_settings->getBool("enable_minimap")) { m_minimap_mapblock = new MinimapMapblock; @@ -1116,8 +1106,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): mapblock_mesh_generate_special(data, collector); - m_highlight_mesh_color = data->m_highlight_mesh_color; - /* Convert MeshCollector to SMesh */ @@ -1162,9 +1150,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): p.tile.texture = animation_frame.texture; } - if(m_enable_highlighting && p.tile.material_flags & MATERIAL_FLAG_HIGHLIGHTED) - m_highlighted_materials.push_back(i); - for(u32 j = 0; j < p.vertices.size(); j++) { video::S3DVertex *vertex = &p.vertices[j]; @@ -1205,19 +1190,15 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): material.setFlag(video::EMF_FOG_ENABLE, true); material.setTexture(0, p.tile.texture); - if (p.tile.material_flags & MATERIAL_FLAG_HIGHLIGHTED) { - material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; - } else { - if (m_enable_shaders) { - material.MaterialType = m_shdrsrc->getShaderInfo(p.tile.shader_id).material; - p.tile.applyMaterialOptionsWithShaders(material); - if (p.tile.normal_texture) { - material.setTexture(1, p.tile.normal_texture); - } - material.setTexture(2, p.tile.flags_texture); - } else { - p.tile.applyMaterialOptions(material); + if (m_enable_shaders) { + material.MaterialType = m_shdrsrc->getShaderInfo(p.tile.shader_id).material; + p.tile.applyMaterialOptionsWithShaders(material); + if (p.tile.normal_texture) { + material.setTexture(1, p.tile.normal_texture); } + material.setTexture(2, p.tile.flags_texture); + } else { + p.tile.applyMaterialOptions(material); } // Create meshbuffer @@ -1273,8 +1254,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): m_has_animation = !m_crack_materials.empty() || !m_daynight_diffs.empty() || - !m_animation_tiles.empty() || - !m_highlighted_materials.empty(); + !m_animation_tiles.empty(); } MapBlockMesh::~MapBlockMesh() @@ -1377,30 +1357,6 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat m_last_daynight_ratio = daynight_ratio; } - // Node highlighting - if (m_enable_highlighting) { - u8 day = m_highlight_mesh_color.getRed(); - u8 night = m_highlight_mesh_color.getGreen(); - video::SColor hc; - finalColorBlend(hc, day, night, daynight_ratio); - float sin_r = 0.07 * sin(1.5 * time); - float sin_g = 0.07 * sin(1.5 * time + irr::core::PI * 0.5); - float sin_b = 0.07 * sin(1.5 * time + irr::core::PI); - hc.setRed(core::clamp(core::round32(hc.getRed() * (0.8 + sin_r)), 0, 255)); - hc.setGreen(core::clamp(core::round32(hc.getGreen() * (0.8 + sin_g)), 0, 255)); - hc.setBlue(core::clamp(core::round32(hc.getBlue() * (0.8 + sin_b)), 0, 255)); - - for(std::list::iterator - i = m_highlighted_materials.begin(); - i != m_highlighted_materials.end(); ++i) - { - scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(*i); - video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); - for (u32 j = 0; j < buf->getVertexCount() ;j++) - vertices[j].Color = hc; - } - } - return true; } diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 9c4fb655a..421e8f2b3 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -41,10 +41,8 @@ struct MeshMakeData VoxelManipulator m_vmanip; v3s16 m_blockpos; v3s16 m_crack_pos_relative; - v3s16 m_highlighted_pos_relative; bool m_smooth_lighting; bool m_show_hud; - video::SColor m_highlight_mesh_color; IGameDef *m_gamedef; bool m_use_shaders; @@ -67,11 +65,6 @@ struct MeshMakeData */ void setCrack(int crack_level, v3s16 crack_pos); - /* - Set the highlighted node position - */ - - void setHighlighted(v3s16 highlighted_pos, bool show_hud); /* Enable or disable smooth lighting */ @@ -137,10 +130,7 @@ private: IShaderSource *m_shdrsrc; bool m_enable_shaders; - bool m_enable_highlighting; - video::SColor m_highlight_mesh_color; - // Must animate() be called before rendering? bool m_has_animation; int m_animation_force_timer; @@ -150,7 +140,6 @@ private: int m_last_crack; // Maps mesh buffer (i.e. material) indices to base texture names std::map m_crack_materials; - std::list m_highlighted_materials; // Animation info: texture animationi // Maps meshbuffers to TileSpecs diff --git a/src/mesh.cpp b/src/mesh.cpp index a800ddf1e..d79f545f3 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -405,9 +405,11 @@ scene::IMesh* cloneMesh(scene::IMesh *src_mesh) return dst_mesh; } -scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f) +scene::IMesh* convertNodeboxesToMesh(const std::vector &boxes, + const f32 *uv_coords) { scene::SMesh* dst_mesh = new scene::SMesh(); + for (u16 j = 0; j < 6; j++) { scene::IMeshBuffer *buf = new scene::SMeshBuffer(); @@ -416,12 +418,10 @@ scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f) dst_mesh->addMeshBuffer(buf); buf->drop(); } - + video::SColor c(255,255,255,255); - std::vector boxes = f->node_box.fixed; - - for(std::vector::iterator + for(std::vector::const_iterator i = boxes.begin(); i != boxes.end(); ++i) { @@ -446,27 +446,33 @@ scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f) box.MinEdge.Z=box.MaxEdge.Z; box.MaxEdge.Z=temp; } - // Compute texture coords - f32 tx1 = (box.MinEdge.X/BS)+0.5; - f32 ty1 = (box.MinEdge.Y/BS)+0.5; - f32 tz1 = (box.MinEdge.Z/BS)+0.5; - f32 tx2 = (box.MaxEdge.X/BS)+0.5; - f32 ty2 = (box.MaxEdge.Y/BS)+0.5; - f32 tz2 = (box.MaxEdge.Z/BS)+0.5; - f32 txc[24] = { + + // Compute texture UV coords + f32 tx1 = (box.MinEdge.X / BS) + 0.5; + f32 ty1 = (box.MinEdge.Y / BS) + 0.5; + f32 tz1 = (box.MinEdge.Z / BS) + 0.5; + f32 tx2 = (box.MaxEdge.X / BS) + 0.5; + f32 ty2 = (box.MaxEdge.Y / BS) + 0.5; + f32 tz2 = (box.MaxEdge.Z / BS) + 0.5; + + f32 txc_default[24] = { // up - tx1, 1-tz2, tx2, 1-tz1, + tx1, 1 - tz2, tx2, 1 - tz1, // down tx1, tz1, tx2, tz2, // right - tz1, 1-ty2, tz2, 1-ty1, + tz1, 1 - ty2, tz2, 1 - ty1, // left - 1-tz2, 1-ty2, 1-tz1, 1-ty1, + 1 - tz2, 1 - ty2, 1 - tz1, 1 - ty1, // back - 1-tx2, 1-ty2, 1-tx1, 1-ty1, + 1 - tx2, 1 - ty2, 1 - tx1, 1 - ty1, // front - tx1, 1-ty2, tx2, 1-ty1, + tx1, 1 - ty2, tx2, 1 - ty1, }; + + // use default texture UV mapping if not provided + const f32 *txc = uv_coords ? uv_coords : txc_default; + v3f min = box.MinEdge; v3f max = box.MaxEdge; diff --git a/src/mesh.h b/src/mesh.h index ec109e9e9..ad3f8db4b 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -83,9 +83,12 @@ void rotateMeshYZby (scene::IMesh *mesh, f64 degrees); scene::IMesh* cloneMesh(scene::IMesh *src_mesh); /* - Convert nodebox drawtype node to mesh. + Convert nodeboxes to mesh. + boxes - set of nodeboxes to be converted into cuboids + uv_coords[24] - table of texture uv coords for each cuboid face */ -scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f); +scene::IMesh* convertNodeboxesToMesh(const std::vector &boxes, + const f32 *uv_coords = NULL); /* Update bounding box for a mesh. diff --git a/src/nodedef.cpp b/src/nodedef.cpp index e30cf6f12..c60958ba5 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -972,7 +972,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, //Convert regular nodebox nodes to meshnodes //Change the drawtype and apply scale f->drawtype = NDT_MESH; - f->mesh_ptr[0] = convertNodeboxNodeToMesh(f); + f->mesh_ptr[0] = convertNodeboxesToMesh(f->node_box.fixed); v3f scale = v3f(1.0, 1.0, 1.0) * f->visual_scale; scaleMesh(f->mesh_ptr[0], scale); recalculateBoundingBox(f->mesh_ptr[0]); diff --git a/textures/base/pack/halo.png b/textures/base/pack/halo.png index e13b54419..eaea782da 100644 Binary files a/textures/base/pack/halo.png and b/textures/base/pack/halo.png differ