diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index dd8529990..1ca5f16dc 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 d8f91e7cb..198b93238 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 42eddb8ce..669987d00 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 3cef5079e..4784d7314 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 2ba47f7ff..9b892f192 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 d1313089a..2d22f963c 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 65453aec1..88e7181d6 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 60a7dc64e..a618ad631 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 a022754a6..3e2483b5e 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 3f4f4fc04..c29c06f95 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