From 925835439e99a8c1417bfced74c47ff426261017 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 6 Feb 2016 05:49:12 +0100 Subject: [PATCH 1/6] Use tangent space meshes only when shaders are enabled --- src/mapblock_mesh.cpp | 19 +++++++++++-------- src/mapblock_mesh.h | 6 +++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 6ae9dec1..9bcc4fa6 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -1167,7 +1167,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): for(u32 j = 0; j < p.vertices.size(); j++) { - video::S3DVertexTangents *vertex = &p.vertices[j]; + video::S3DVertex *vertex = &p.vertices[j]; // Note applyFacesShading second parameter is precalculated sqrt // value for speed improvement // Skip it for lightsources and top faces. @@ -1221,11 +1221,12 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): } // Create meshbuffer - scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents(); + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); // Set material buf->Material = material; // Add to mesh - m_mesh->addMeshBuffer(buf); + scene::SMesh *mesh = (scene::SMesh *)m_mesh; + mesh->addMeshBuffer(buf); // Mesh grabbed it buf->drop(); buf->append(&p.vertices[0], p.vertices.size(), @@ -1241,7 +1242,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): if (m_enable_shaders) { scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator(); - meshmanip->recalculateTangents(m_mesh, true, false, false); + scene::IMesh* tangentMesh = meshmanip->createMeshWithTangents(m_mesh); + m_mesh->drop(); + m_mesh = tangentMesh; } if(m_mesh) @@ -1361,7 +1364,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat i != m_daynight_diffs.end(); ++i) { scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first); - video::S3DVertexTangents *vertices = (video::S3DVertexTangents *)buf->getVertices(); + video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); for(std::map >::iterator j = i->second.begin(); j != i->second.end(); ++j) @@ -1392,7 +1395,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat i != m_highlighted_materials.end(); ++i) { scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(*i); - video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices(); + video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); for (u32 j = 0; j < buf->getVertexCount() ;j++) vertices[j].Color = hc; } @@ -1448,7 +1451,7 @@ void MeshCollector::append(const TileSpec &tile, } for (u32 i = 0; i < numVertices; i++) { - video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal, + video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal, vertices[i].Color, vertices[i].TCoords); p->vertices.push_back(vert); } @@ -1494,7 +1497,7 @@ void MeshCollector::append(const TileSpec &tile, } for (u32 i = 0; i < numVertices; i++) { - video::S3DVertexTangents vert(vertices[i].Pos + pos, vertices[i].Normal, + video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal, c, vertices[i].TCoords); p->vertices.push_back(vert); } diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 8e994ec6..9c4fb655 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -104,7 +104,7 @@ public: // Returns true if anything has been changed. bool animate(bool faraway, float time, int crack, u32 daynight_ratio); - scene::SMesh *getMesh() + scene::IMesh *getMesh() { return m_mesh; } @@ -130,7 +130,7 @@ public: void updateCameraOffset(v3s16 camera_offset); private: - scene::SMesh *m_mesh; + scene::IMesh *m_mesh; MinimapMapblock *m_minimap_mapblock; IGameDef *m_gamedef; ITextureSource *m_tsrc; @@ -177,7 +177,7 @@ struct PreMeshBuffer { TileSpec tile; std::vector indices; - std::vector vertices; + std::vector vertices; }; struct MeshCollector From 013ef76173ff7dcb0d2f86d2b212bd5a175017cc Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sun, 24 Jan 2016 14:19:17 +0100 Subject: [PATCH 2/6] Use meshes to display inventory items --- builtin/settingtypes.txt | 3 + minetest.conf.example | 3 + src/defaultsettings.cpp | 1 + src/guiFormSpecMenu.cpp | 79 ++++++++++++++------------ src/guiFormSpecMenu.h | 20 ++++++- src/hud.cpp | 99 ++++++++++++++++++++++++++++----- src/hud.h | 9 ++- src/itemdef.cpp | 101 ++------------------------------- src/wieldmesh.cpp | 117 ++++++++++++++++++++++++++++++++++++++- src/wieldmesh.h | 4 ++ 10 files changed, 281 insertions(+), 155 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index dd852999..1ca5f16d 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -508,6 +508,9 @@ directional_colored_fog (Colored fog) bool true # set to the nearest valid value. ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0 +# Enables animation of inventory items. +inventory_items_animations (Inventory items animations) bool false + [**Menus] # Use a cloud animation for the main menu background. diff --git a/minetest.conf.example b/minetest.conf.example index d8f91e7c..198b9323 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -588,6 +588,9 @@ # type: float min: 0.25 max: 4 # ambient_occlusion_gamma = 2.2 +# Enable animation of inventory items. +# inventory_items_animations = false + ### Menus # Use a cloud animation for the main menu background. diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 42eddb8c..669987d0 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -138,6 +138,7 @@ void set_default_settings(Settings *settings) settings->setDefault("console_alpha", "200"); settings->setDefault("selectionbox_color", "(0,0,0)"); settings->setDefault("enable_node_highlighting", "false"); + settings->setDefault("inventory_items_animations", "false"); settings->setDefault("crosshair_color", "(255,255,255)"); settings->setDefault("crosshair_alpha", "255"); settings->setDefault("hud_scaling", "1.0"); diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 3cef5079..4784d731 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -572,7 +572,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) if(!data->explicit_size) warningstream<<"invalid use of item_image without a size[] element"<idef(); ItemStack item; item.deSerialize(item_name, idef); - video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); m_tooltips[name] = TooltipSpec(item.getDefinition(idef).description, @@ -1505,13 +1504,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) } e->setUseAlphaChannel(true); - e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y)); - e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y)); + e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y)); + e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y)); e->setScaleImage(true); spec.ftype = f_Button; rect+=data->basepos-padding; spec.rect=rect; m_fields.push_back(spec); + pos = padding + AbsoluteRect.UpperLeftCorner; + pos.X += stof(v_pos[0]) * (float) spacing.X; + pos.Y += stof(v_pos[1]) * (float) spacing.Y; + m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom)); return; } errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl; @@ -2151,7 +2154,8 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const return ItemSpec(InventoryLocation(), "", -1); } -void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) +void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase, + bool &item_hovered) { video::IVideoDriver* driver = Environment->getVideoDriver(); @@ -2193,12 +2197,13 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) && m_selected_item->i == item_i; bool hovering = rect.isPointInside(m_pointer); - if(phase == 0) - { - if(hovering) + if (phase == 0) { + if (hovering) { + item_hovered = true; driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect); - else + } else { driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect); + } } //Draw inv slot borders @@ -2232,7 +2237,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) if(!item.empty()) { drawItemStack(driver, m_font, item, - rect, &AbsoluteClippingRect, m_gamedef); + rect, &AbsoluteClippingRect, m_gamedef, + selected, hovering, false); } // Draw tooltip @@ -2273,11 +2279,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) void GUIFormSpecMenu::drawSelectedItem() { - if(!m_selected_item) - return; - video::IVideoDriver* driver = Environment->getVideoDriver(); + if (!m_selected_item) { + drawItemStack(driver, m_font, ItemStack(), + core::rect(v2s32(0, 0), v2s32(0, 0)), + NULL, m_gamedef, false, false, true); + return; + } + Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); sanity_check(inv); InventoryList *list = inv->getList(m_selected_item->listname); @@ -2287,7 +2297,7 @@ void GUIFormSpecMenu::drawSelectedItem() core::rect imgrect(0,0,imgsize.X,imgsize.Y); core::rect rect = imgrect + (m_pointer - imgrect.getCenter()); - drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef); + drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, false, false, true); } void GUIFormSpecMenu::drawMenu() @@ -2369,6 +2379,12 @@ void GUIFormSpecMenu::drawMenu() driver->draw2DRectangle(todraw, rect, 0); } + + /* + Call base class + */ + gui::IGUIElement::draw(); + /* Draw images */ @@ -2413,18 +2429,12 @@ void GUIFormSpecMenu::drawMenu() const ImageDrawSpec &spec = m_itemimages[i]; IItemDefManager *idef = m_gamedef->idef(); ItemStack item; - item.deSerialize(spec.name, idef); - video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); - // Image size on screen + item.deSerialize(spec.item_name, idef); core::rect imgrect(0, 0, spec.geom.X, spec.geom.Y); - // Image rectangle on screen + // Viewport rectangle on screen core::rect rect = imgrect + spec.pos; - const video::SColor color(255,255,255,255); - const video::SColor colors[] = {color,color,color,color}; - draw2DImageFilterScaled(driver, texture, rect, - core::rect(core::position2d(0,0), - core::dimension2di(texture->getOriginalSize())), - NULL/*&AbsoluteClippingRect*/, colors, true); + drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, + m_gamedef, false, false, false); } /* @@ -2432,17 +2442,18 @@ void GUIFormSpecMenu::drawMenu() Phase 0: Item slot rectangles Phase 1: Item images; prepare tooltip */ - int start_phase=0; - for(int phase=start_phase; phase<=1; phase++) - for(u32 i=0; i(v2s32(0, 0), v2s32(0, 0)), + NULL, m_gamedef, false, true, false); } - - /* - Call base class - */ - gui::IGUIElement::draw(); /* TODO find way to show tooltips on touchscreen */ #ifndef HAVE_TOUCHSCREENGUI diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 2ba47f7f..9b892f19 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -143,7 +143,17 @@ class GUIFormSpecMenu : public GUIModalMenu { } ImageDrawSpec(const std::string &a_name, - v2s32 a_pos, v2s32 a_geom): + const std::string &a_item_name, + const v2s32 &a_pos, const v2s32 &a_geom): + name(a_name), + item_name (a_item_name), + pos(a_pos), + geom(a_geom) + { + scale = true; + } + ImageDrawSpec(const std::string &a_name, + const v2s32 &a_pos, const v2s32 &a_geom): name(a_name), pos(a_pos), geom(a_geom) @@ -151,13 +161,14 @@ class GUIFormSpecMenu : public GUIModalMenu scale = true; } ImageDrawSpec(const std::string &a_name, - v2s32 a_pos): + const v2s32 &a_pos): name(a_name), pos(a_pos) { scale = false; } std::string name; + std::string item_name; v2s32 pos; v2s32 geom; bool scale; @@ -282,7 +293,7 @@ public: void regenerateGui(v2u32 screensize); ItemSpec getItemAtPos(v2s32 p) const; - void drawList(const ListDrawSpec &s, int phase); + void drawList(const ListDrawSpec &s, int phase, bool &item_hovered); void drawSelectedItem(); void drawMenu(); void updateSelectedItem(); @@ -334,6 +345,8 @@ protected: std::vector > m_scrollbars; ItemSpec *m_selected_item; + f32 m_timer1; + f32 m_timer2; u32 m_selected_amount; bool m_selected_dragging; @@ -373,6 +386,7 @@ private: TextDest *m_text_dst; unsigned int m_formspec_version; std::string m_focused_element; + bool m_selection_active; typedef struct { bool explicit_size; diff --git a/src/hud.cpp b/src/hud.cpp index d1313089..2d22f963 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -82,8 +82,9 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, use_hotbar_selected_image = false; } -void Hud::drawItem(const ItemStack &item, const core::rect& rect, bool selected) { - +void Hud::drawItem(const ItemStack &item, const core::rect& rect, + bool selected) +{ if (selected) { /* draw hihlighting around selected item */ if (use_hotbar_selected_image) { @@ -154,7 +155,8 @@ void Hud::drawItem(const ItemStack &item, const core::rect& rect, bool sele video::SColor bgcolor2(128, 0, 0, 0); if (!use_hotbar_image) driver->draw2DRectangle(bgcolor2, rect, NULL); - drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef); + drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, + gamedef, selected, false, false); } //NOTE: selectitem = 0 -> no selected; selectitem 1-based @@ -489,23 +491,90 @@ void drawItemStack(video::IVideoDriver *driver, const ItemStack &item, const core::rect &rect, const core::rect *clip, - IGameDef *gamedef) + IGameDef *gamedef, + bool selected, + bool hovered, + bool dragged) { - if(item.empty()) + static s32 hovered_time; + static s32 selected_time; + static s32 dragged_time; + static scene::IMesh *hovered_mesh; + static scene::IMesh *selected_mesh; + static scene::IMesh *dragged_mesh; + bool enable_animations = + g_settings->getBool("inventory_items_animations"); + + if (item.empty()) { + if (selected) { + selected_mesh = NULL; + } else if (hovered) { + hovered_mesh = NULL; + } else if (dragged) { + dragged_mesh = NULL; + } return; + } const ItemDefinition &def = item.getDefinition(gamedef->idef()); - video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef); + scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef); - // Draw the inventory texture - if(texture != NULL) - { - const video::SColor color(255,255,255,255); - const video::SColor colors[] = {color,color,color,color}; - draw2DImageFilterScaled(driver, texture, rect, - core::rect(core::position2d(0,0), - core::dimension2di(texture->getOriginalSize())), - clip, colors, true); + if (mesh) { + driver->clearZBuffer(); + s32 delta = 0; + if (selected) { + if (mesh != selected_mesh) { + selected_mesh = mesh; + selected_time = getTimeMs(); + } else { + delta = porting::getDeltaMs(selected_time, getTimeMs()) % 100000; + } + } else if (hovered) { + if (mesh != hovered_mesh) { + hovered_mesh = mesh; + hovered_time = getTimeMs(); + } else { + delta = porting::getDeltaMs(hovered_time, getTimeMs()) % 100000; + } + } else if (dragged) { + if (mesh != dragged_mesh) { + dragged_mesh = mesh; + dragged_time = getTimeMs(); + } else { + delta = porting::getDeltaMs(dragged_time, getTimeMs()) % 100000; + } + } + core::rect oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + core::matrix4 ProjMatrix; + ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100); + driver->setTransform(video::ETS_PROJECTION, ProjMatrix); + driver->setTransform(video::ETS_VIEW, ProjMatrix); + core::matrix4 matrix; + matrix.makeIdentity(); + + if (enable_animations) { + float timer_f = (float)delta / 5000.0; + matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0)); + } + + driver->setTransform(video::ETS_WORLD, matrix); + driver->setViewPort(rect); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; ++j) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + video::SMaterial &material = buf->getMaterial(); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material.Lighting = false; + driver->setMaterial(material); + driver->drawMeshBuffer(buf); + } + + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + driver->setViewPort(oldViewPort); } if(def.type == ITEM_TOOL && item.wear != 0) diff --git a/src/hud.h b/src/hud.h index 65453aec..88e7181d 100644 --- a/src/hud.h +++ b/src/hud.h @@ -137,7 +137,8 @@ private: void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset, InventoryList *mainlist, u16 selectitem, u16 direction); - void drawItem(const ItemStack &item, const core::rect& rect, bool selected); + void drawItem(const ItemStack &item, const core::rect& rect, + bool selected); v2u32 m_screensize; v2s32 m_displaycenter; @@ -151,8 +152,10 @@ void drawItemStack(video::IVideoDriver *driver, const ItemStack &item, const core::rect &rect, const core::rect *clip, - IGameDef *gamedef); - + IGameDef *gamedef, + bool selected, + bool hovered, + bool dragged); #endif diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 60a7dc64..a618ad63 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -332,7 +332,6 @@ public: return cc; ITextureSource *tsrc = gamedef->getTextureSource(); - INodeDefManager *nodedef = gamedef->getNodeDefManager(); const ItemDefinition &def = get(name); // Create new ClientCached @@ -343,103 +342,11 @@ public: if(def.inventory_image != "") cc->inventory_texture = tsrc->getTexture(def.inventory_image); - // Additional processing for nodes: - // - Create a wield mesh if WieldMeshSceneNode can't render - // the node on its own. - // - If inventory_texture isn't set yet, create one using - // render-to-texture. - if (def.type == ITEM_NODE) { - // Get node properties - content_t id = nodedef->getId(name); - const ContentFeatures &f = nodedef->get(id); + ItemStack item = ItemStack(); + item.name = def.name; - bool need_rtt_mesh = cc->inventory_texture == NULL; - - // Keep this in sync with WieldMeshSceneNode::setItem() - bool need_wield_mesh = - !(f.mesh_ptr[0] || - f.drawtype == NDT_NORMAL || - f.drawtype == NDT_ALLFACES || - f.drawtype == NDT_AIRLIKE); - - scene::IMesh *node_mesh = NULL; - - if (need_rtt_mesh || need_wield_mesh) { - u8 param1 = 0; - if (f.param_type == CPT_LIGHT) - param1 = 0xee; - - /* - Make a mesh from the node - */ - MeshMakeData mesh_make_data(gamedef, false); - u8 param2 = 0; - if (f.param_type_2 == CPT2_WALLMOUNTED) - param2 = 1; - MapNode mesh_make_node(id, param1, param2); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - node_mesh = mapblock_mesh.getMesh(); - node_mesh->grab(); - video::SColor c(255, 255, 255, 255); - setMeshColor(node_mesh, c); - - // scale and translate the mesh so it's a - // unit cube centered on the origin - scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); - translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); - } - - /* - Draw node mesh into a render target texture - */ - if (need_rtt_mesh) { - TextureFromMeshParams params; - params.mesh = node_mesh; - params.dim.set(64, 64); - params.rtt_texture_name = "INVENTORY_" - + def.name + "_RTT"; - params.delete_texture_on_shutdown = true; - params.camera_position.set(0, 1.0, -1.5); - params.camera_position.rotateXZBy(45); - params.camera_lookat.set(0, 0, 0); - // Set orthogonal projection - params.camera_projection_matrix.buildProjectionMatrixOrthoLH( - 1.65, 1.65, 0, 100); - params.ambient_light.set(1.0, 0.2, 0.2, 0.2); - params.light_position.set(10, 100, -50); - params.light_color.set(1.0, 0.5, 0.5, 0.5); - params.light_radius = 1000; - -#ifdef __ANDROID__ - params.camera_position.set(0, -1.0, -1.5); - params.camera_position.rotateXZBy(45); - params.light_position.set(10, -100, -50); -#endif - cc->inventory_texture = - tsrc->generateTextureFromMesh(params); - - // render-to-target didn't work - if (cc->inventory_texture == NULL) { - cc->inventory_texture = - tsrc->getTexture(f.tiledef[0].name); - } - } - - /* - Use the node mesh as the wield mesh - */ - if (need_wield_mesh) { - cc->wield_mesh = node_mesh; - cc->wield_mesh->grab(); - - // no way reference count can be smaller than 2 in this place! - assert(cc->wield_mesh->getReferenceCount() >= 2); - } - - if (node_mesh) - node_mesh->drop(); - } + scene::IMesh *mesh = getItemMesh(gamedef, item); + cc->wield_mesh = mesh; // Put in cache m_clientcached.set(name, cc); diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index a022754a..3e2483b5 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -114,9 +114,7 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y) mesh->addMeshBuffer(buf); buf->drop(); scaleMesh(mesh, scale); // also recalculates bounding box - scene::IMesh *newmesh = createForsythOptimizedMesh(mesh); - mesh->drop(); - return newmesh; + return mesh; } /* @@ -436,3 +434,116 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh) m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting); m_meshnode->setVisible(true); } + +scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item) +{ + ITextureSource *tsrc = gamedef->getTextureSource(); + IItemDefManager *idef = gamedef->getItemDefManager(); + INodeDefManager *ndef = gamedef->getNodeDefManager(); + const ItemDefinition &def = item.getDefinition(idef); + const ContentFeatures &f = ndef->get(def.name); + content_t id = ndef->getId(def.name); + + if (!g_extrusion_mesh_cache) { + g_extrusion_mesh_cache = new ExtrusionMeshCache(); + } else { + g_extrusion_mesh_cache->grab(); + } + + scene::IMesh *mesh; + + // If wield_image is defined, it overrides everything else + if (def.wield_image != "") { + mesh = getExtrudedMesh(tsrc, def.wield_image); + return mesh; + } else if (def.inventory_image != "") { + mesh = getExtrudedMesh(tsrc, def.inventory_image); + return mesh; + } else if (def.type == ITEM_NODE) { + if (f.mesh_ptr[0]) { + mesh = cloneMesh(f.mesh_ptr[0]); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + setMeshColor(mesh, video::SColor (255, 255, 255, 255)); + } else if (f.drawtype == NDT_PLANTLIKE) { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.tiles[0].texture_id)); + return mesh; + } else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES + || f.drawtype == NDT_LIQUID || f.drawtype == NDT_FLOWINGLIQUID) { + mesh = cloneMesh(g_extrusion_mesh_cache->createCube()); + scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); + } else { + MeshMakeData mesh_make_data(gamedef, false); + MapNode mesh_make_node(id, 255, 0); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + mesh = cloneMesh(mapblock_mesh.getMesh()); + translateMesh(mesh, v3f(-BS, -BS, -BS)); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + rotateMeshXZby(mesh, -45); + rotateMeshYZby(mesh, -30); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; ++i) { + video::SMaterial &material1 = + mesh->getMeshBuffer(i)->getMaterial(); + video::SMaterial &material2 = + mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial(); + material1.setTexture(0, material2.getTexture(0)); + material1.setTexture(1, material2.getTexture(1)); + material1.setTexture(2, material2.getTexture(2)); + material1.setTexture(3, material2.getTexture(3)); + material1.MaterialType = material2.MaterialType; + } + return mesh; + } + + shadeMeshFaces(mesh); + rotateMeshXZby(mesh, -45); + rotateMeshYZby(mesh, -30); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; ++i) { + video::SMaterial &material = mesh->getMeshBuffer(i)->getMaterial(); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_TRILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_LIGHTING, false); + if (f.tiles[i].animation_frame_count > 1) { + FrameSpec animation_frame = f.tiles[i].frames[0]; + material.setTexture(0, animation_frame.texture); + } else { + material.setTexture(0, f.tiles[i].texture); + } + } + return mesh; + } + return NULL; +} + +scene::IMesh * getExtrudedMesh(ITextureSource *tsrc, + const std::string &imagename) +{ + video::ITexture *texture = tsrc->getTextureForMesh(imagename); + if (!texture) { + return NULL; + } + + core::dimension2d dim = texture->getSize(); + scene::IMesh *mesh = cloneMesh(g_extrusion_mesh_cache->create(dim)); + + // Customize material + video::SMaterial &material = mesh->getMeshBuffer(0)->getMaterial(); + material.setTexture(0, tsrc->getTexture(imagename)); + material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_TRILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_LIGHTING, false); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + scaleMesh(mesh, v3f(2.0, 2.0, 2.0)); + + return mesh; +} diff --git a/src/wieldmesh.h b/src/wieldmesh.h index 3f4f4fc0..c29c06f9 100644 --- a/src/wieldmesh.h +++ b/src/wieldmesh.h @@ -77,4 +77,8 @@ private: core::aabbox3d m_bounding_box; }; +scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item); + +scene::IMesh *getExtrudedMesh(ITextureSource *tsrc, + const std::string &imagename); #endif From 3bb1d941adff4795c91fe5cdd0ed74250e91ef19 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 7 Feb 2016 20:27:50 +0100 Subject: [PATCH 3/6] small drawItemStack cleanup -> Replace the three bool params with an enum -> Add struct for the static content, leads to less repetition -> cache enable_animations setting --- src/guiFormSpecMenu.cpp | 12 ++++++---- src/hud.cpp | 53 +++++++++++++---------------------------- src/hud.h | 11 ++++++--- 3 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 4784d731..116688e9 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -2196,6 +2196,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase, && m_selected_item->listname == s.listname && m_selected_item->i == item_i; bool hovering = rect.isPointInside(m_pointer); + ItemRotationKind rotation_kind = selected ? IT_ROT_SELECTED : + (hovering ? IT_ROT_HOVERED : IT_ROT_NONE); if (phase == 0) { if (hovering) { @@ -2238,7 +2240,7 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase, { drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, m_gamedef, - selected, hovering, false); + rotation_kind); } // Draw tooltip @@ -2284,7 +2286,7 @@ void GUIFormSpecMenu::drawSelectedItem() if (!m_selected_item) { drawItemStack(driver, m_font, ItemStack(), core::rect(v2s32(0, 0), v2s32(0, 0)), - NULL, m_gamedef, false, false, true); + NULL, m_gamedef, IT_ROT_DRAGGED); return; } @@ -2297,7 +2299,7 @@ void GUIFormSpecMenu::drawSelectedItem() core::rect imgrect(0,0,imgsize.X,imgsize.Y); core::rect rect = imgrect + (m_pointer - imgrect.getCenter()); - drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, false, false, true); + drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, IT_ROT_DRAGGED); } void GUIFormSpecMenu::drawMenu() @@ -2434,7 +2436,7 @@ void GUIFormSpecMenu::drawMenu() // Viewport rectangle on screen core::rect rect = imgrect + spec.pos; drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, - m_gamedef, false, false, false); + m_gamedef, IT_ROT_NONE); } /* @@ -2452,7 +2454,7 @@ void GUIFormSpecMenu::drawMenu() if (!item_hovered) { drawItemStack(driver, m_font, ItemStack(), core::rect(v2s32(0, 0), v2s32(0, 0)), - NULL, m_gamedef, false, true, false); + NULL, m_gamedef, IT_ROT_HOVERED); } /* TODO find way to show tooltips on touchscreen */ diff --git a/src/hud.cpp b/src/hud.cpp index 2d22f963..1c144b02 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -156,7 +156,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect& rect, if (!use_hotbar_image) driver->draw2DRectangle(bgcolor2, rect, NULL); drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, - gamedef, selected, false, false); + gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE); } //NOTE: selectitem = 0 -> no selected; selectitem 1-based @@ -486,32 +486,26 @@ void Hud::resizeHotbar() { } } +struct MeshTimeInfo { + s32 time; + scene::IMesh *mesh; +}; + void drawItemStack(video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, const core::rect &rect, const core::rect *clip, IGameDef *gamedef, - bool selected, - bool hovered, - bool dragged) + ItemRotationKind rotation_kind) { - static s32 hovered_time; - static s32 selected_time; - static s32 dragged_time; - static scene::IMesh *hovered_mesh; - static scene::IMesh *selected_mesh; - static scene::IMesh *dragged_mesh; - bool enable_animations = + static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; + static bool enable_animations = g_settings->getBool("inventory_items_animations"); if (item.empty()) { - if (selected) { - selected_mesh = NULL; - } else if (hovered) { - hovered_mesh = NULL; - } else if (dragged) { - dragged_mesh = NULL; + if (rotation_kind < IT_ROT_NONE) { + rotation_time_infos[rotation_kind].mesh = NULL; } return; } @@ -522,26 +516,13 @@ void drawItemStack(video::IVideoDriver *driver, if (mesh) { driver->clearZBuffer(); s32 delta = 0; - if (selected) { - if (mesh != selected_mesh) { - selected_mesh = mesh; - selected_time = getTimeMs(); + if (rotation_kind < IT_ROT_NONE) { + MeshTimeInfo &ti = rotation_time_infos[rotation_kind]; + if (mesh != ti.mesh) { + ti.mesh = mesh; + ti.time = getTimeMs(); } else { - delta = porting::getDeltaMs(selected_time, getTimeMs()) % 100000; - } - } else if (hovered) { - if (mesh != hovered_mesh) { - hovered_mesh = mesh; - hovered_time = getTimeMs(); - } else { - delta = porting::getDeltaMs(hovered_time, getTimeMs()) % 100000; - } - } else if (dragged) { - if (mesh != dragged_mesh) { - dragged_mesh = mesh; - dragged_time = getTimeMs(); - } else { - delta = porting::getDeltaMs(dragged_time, getTimeMs()) % 100000; + delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000; } } core::rect oldViewPort = driver->getViewPort(); diff --git a/src/hud.h b/src/hud.h index 88e7181d..f373d4fe 100644 --- a/src/hud.h +++ b/src/hud.h @@ -147,15 +147,20 @@ private: video::SColor hbar_colors[4]; }; +enum ItemRotationKind { + IT_ROT_SELECTED, + IT_ROT_HOVERED, + IT_ROT_DRAGGED, + IT_ROT_NONE, // Must be last, also serves as number +}; + void drawItemStack(video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, const core::rect &rect, const core::rect *clip, IGameDef *gamedef, - bool selected, - bool hovered, - bool dragged); + ItemRotationKind rotation_kind); #endif From e877590dec82b774a0551b4829ddc7807ec5c326 Mon Sep 17 00:00:00 2001 From: Diego Martinez Date: Thu, 4 Feb 2016 09:58:44 -0300 Subject: [PATCH 4/6] builtin: Fix `print` crashing on nil "holes". The engine implementation of `print` packs the varargs into a table and passes the table directly to `table.concat`. If you pass any value not supported by `table.concat` (particularly `nil`), the server crashes. This is unexpected behavior, as `print` is supposed to be able to work with anything. This patch changes the implementation so it first converts all arguments using `tostring`, which fixes the issue and makes the custom `print` function compatible with the stock Lua behavior. --- builtin/init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/builtin/init.lua b/builtin/init.lua index b3004468..6b27cf76 100644 --- a/builtin/init.lua +++ b/builtin/init.lua @@ -12,7 +12,11 @@ if core.print then -- Override native print and use -- terminal if that's turned on function print(...) - core_print(table.concat({...}, "\t")) + local n, t = select("#", ...), { ... } + for i = 1, n do + t[i] = tostring(t[i]) + end + core_print(table.concat(t, "\t")) end core.print = nil -- don't pollute our namespace end From 8b602bba0f846e27d12db4614b3521a6aa2189db Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sun, 7 Feb 2016 04:08:43 +0100 Subject: [PATCH 5/6] Cleanup selection mesh code, add shaders for halo and selection boxes --- builtin/settingtypes.txt | 6 +- .../default_shader/opengl_fragment.glsl | 4 + .../shaders/default_shader/opengl_vertex.glsl | 9 ++ .../selection_shader/opengl_fragment.glsl | 9 ++ .../selection_shader/opengl_vertex.glsl | 9 ++ minetest.conf.example | 6 +- src/client.cpp | 12 -- src/client.h | 5 - src/content_mapblock.cpp | 51 -------- src/defaultsettings.cpp | 6 +- src/drawscene.cpp | 120 +++++++---------- src/drawscene.h | 8 +- src/game.cpp | 123 ++++++++++-------- src/hud.cpp | 118 ++++++++++++++++- src/hud.h | 30 ++++- src/mapblock_mesh.cpp | 62 ++------- src/mapblock_mesh.h | 11 -- src/mesh.cpp | 42 +++--- src/mesh.h | 7 +- src/nodedef.cpp | 2 +- textures/base/pack/halo.png | Bin 83 -> 144 bytes 21 files changed, 336 insertions(+), 304 deletions(-) create mode 100644 client/shaders/default_shader/opengl_fragment.glsl create mode 100644 client/shaders/default_shader/opengl_vertex.glsl create mode 100644 client/shaders/selection_shader/opengl_fragment.glsl create mode 100644 client/shaders/selection_shader/opengl_vertex.glsl diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 1ca5f16d..79a64c2d 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 00000000..925ab6e1 --- /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 00000000..0f460917 --- /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 00000000..c679d0e1 --- /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 00000000..0f460917 --- /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 198b9323..1bf56720 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 8e49ee3b..a845277b 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 07fb79dc..98a8bc12 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 01a06b6c..ab8091de 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 669987d0..ddd7b5fe 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 c716ca0d..32eafeb2 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 0630f297..364fcd49 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 3902c50b..cae468d4 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 1c144b02..0a77a1a2 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 f373d4fe..d0158b2f 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 9bcc4fa6..9486220e 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 9c4fb655..421e8f2b 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 a800ddf1..d79f545f 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 ec109e9e..ad3f8db4 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 e30cf6f1..c60958ba 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 e13b544199c8cd299d7b061162b8bc22849b297d..eaea782da6480cd7996367a1a10785db6f5933cb 100644 GIT binary patch delta 126 zcmWHZz&Jsof`g5LfkFQB|3o0gmgMd3!tfsi7wla=87RV8;1OBOz`!jG!i)^F=12eq z*-JcqUD+Qnu`^kTmX({Z1BGNgT^vI!PA7kf`;g1W%-Yb|=wy&}U Date: Mon, 8 Feb 2016 01:40:05 +0100 Subject: [PATCH 6/6] Use inventory_image in the first place for inventory item mesh --- src/wieldmesh.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index 3e2483b5..9c4d5b64 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -452,11 +452,8 @@ scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item) scene::IMesh *mesh; - // If wield_image is defined, it overrides everything else - if (def.wield_image != "") { - mesh = getExtrudedMesh(tsrc, def.wield_image); - return mesh; - } else if (def.inventory_image != "") { + // If inventory_image is defined, it overrides everything else + if (def.inventory_image != "") { mesh = getExtrudedMesh(tsrc, def.inventory_image); return mesh; } else if (def.type == ITEM_NODE) {