]> git.lizzy.rs Git - minetest.git/commitdiff
Use meshes to display inventory items
authorRealBadAngel <maciej.kasatkin@o2.pl>
Sun, 24 Jan 2016 13:19:17 +0000 (14:19 +0100)
committerest31 <MTest31@outlook.com>
Sun, 7 Feb 2016 18:51:55 +0000 (19:51 +0100)
builtin/settingtypes.txt
minetest.conf.example
src/defaultsettings.cpp
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h
src/hud.cpp
src/hud.h
src/itemdef.cpp
src/wieldmesh.cpp
src/wieldmesh.h

index dd85299902d9459a383002e12facde7132a3316d..1ca5f16dc048330eb4eaae4325bcf01861d4b2b8 100644 (file)
@@ -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.
index d8f91e7cb670dd9089c52d3f183d2fad6ce08a6f..198b9323848e7313f1d6bf7b76571ba43be92657 100644 (file)
 #    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.
index 42eddb8ceb7c4b998a1c44108acbc981fc095804..669987d0031471611b4f95a7ef934b8baacd1004 100644 (file)
@@ -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");
index 3cef5079ec9c2049a3bed9d6af2d6677ba3299a6..4784d73145a4daba18114d1e41b26c60a0c6b1ac 100644 (file)
@@ -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"<<std::endl;
-               m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
+               m_itemimages.push_back(ImageDrawSpec("", name, pos, geom));
                return;
        }
        errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'"  << std::endl;
@@ -1483,7 +1483,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
                IItemDefManager *idef = m_gamedef->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<s32>(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<s32> imgrect(0,0,imgsize.X,imgsize.Y);
        core::rect<s32> 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<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
-               // Image rectangle on screen
+               // Viewport rectangle on screen
                core::rect<s32> 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<s32>(core::position2d<s32>(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<m_inventorylists.size(); i++)
-       {
-               drawList(m_inventorylists[i], phase);
+       bool item_hovered = false;
+       int start_phase = 0;
+       for (int phase = start_phase; phase <= 1; phase++) {
+               for (u32 i = 0; i < m_inventorylists.size(); i++) {
+                       drawList(m_inventorylists[i], phase, item_hovered);
+               }
+       }
+       if (!item_hovered) {
+               drawItemStack(driver, m_font, ItemStack(),
+                       core::rect<s32>(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
index 2ba47f7ff5bac5c60648465886cfd4daec20f959..9b892f19273d2cd110cb5ac7660aa0fdd00a3a28 100644 (file)
@@ -143,21 +143,32 @@ 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,
-                               v2s32 a_pos):
+                               const v2s32 &a_pos, const v2s32 &a_geom):
+                       name(a_name),
+                       pos(a_pos),
+                       geom(a_geom)
+               {
+                       scale = true;
+               }
+               ImageDrawSpec(const std::string &a_name,
+                               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 @@ class GUIFormSpecMenu : public GUIModalMenu
        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 @@ class GUIFormSpecMenu : public GUIModalMenu
        std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
 
        ItemSpec *m_selected_item;
+       f32 m_timer1;
+       f32 m_timer2;
        u32 m_selected_amount;
        bool m_selected_dragging;
 
@@ -373,6 +386,7 @@ class GUIFormSpecMenu : public GUIModalMenu
        TextDest         *m_text_dst;
        unsigned int      m_formspec_version;
        std::string       m_focused_element;
+       bool              m_selection_active;
 
        typedef struct {
                bool explicit_size;
index d1313089ae8dd95ce74ef5f6852ed6d984857831..2d22f963c02482890b6222e6e5a05e0c8be07fcb 100644 (file)
@@ -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<s32>& rect, bool selected) {
-
+void Hud::drawItem(const ItemStack &item, const core::rect<s32>& 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<s32>& 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<s32> &rect,
                const core::rect<s32> *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);
+
+       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<s32> 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));
+               }
 
-       // 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<s32>(core::position2d<s32>(0,0),
-                       core::dimension2di(texture->getOriginalSize())),
-                       clip, colors, true);
+               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)
index 65453aec1ae7288cbdd127226bf1f0bc57bfd758..88e7181d6f67079152b7573e1d89daf1415dac1a 100644 (file)
--- a/src/hud.h
+++ b/src/hud.h
@@ -137,7 +137,8 @@ class Hud {
        void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
                InventoryList *mainlist, u16 selectitem, u16 direction);
 
-       void drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected);
+       void drawItem(const ItemStack &item, const core::rect<s32>& rect,
+               bool selected);
 
        v2u32 m_screensize;
        v2s32 m_displaycenter;
@@ -151,8 +152,10 @@ void drawItemStack(video::IVideoDriver *driver,
                const ItemStack &item,
                const core::rect<s32> &rect,
                const core::rect<s32> *clip,
-               IGameDef *gamedef);
-
+               IGameDef *gamedef,
+               bool selected,
+               bool hovered,
+               bool dragged);
 
 #endif
 
index 60a7dc64e33316f109eb3c20b81f6fb953792cea..a618ad631b078666a682ec39d944b129b2096884 100644 (file)
@@ -332,7 +332,6 @@ class CItemDefManager: public IWritableItemDefManager
                        return cc;
 
                ITextureSource *tsrc = gamedef->getTextureSource();
-               INodeDefManager *nodedef = gamedef->getNodeDefManager();
                const ItemDefinition &def = get(name);
 
                // Create new ClientCached
@@ -343,103 +342,11 @@ class CItemDefManager: public IWritableItemDefManager
                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);
-
-                       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();
+               ItemStack item = ItemStack();
+               item.name = def.name;
 
-                               // 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);
index a022754a6864da4fce61ad64285043caa00723f7..3e2483b5ee5c7b54b3a0075dfdf00dc7759f8170 100644 (file)
@@ -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<u32> 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;
+}
index 3f4f4fc042a5e5c46a5c41f02cee8de0a7e4ab94..c29c06f956a2f674435e2de6ae8edf2aa1594179 100644 (file)
@@ -77,4 +77,8 @@ class WieldMeshSceneNode: public scene::ISceneNode
        core::aabbox3d<f32> m_bounding_box;
 };
 
+scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item);
+
+scene::IMesh *getExtrudedMesh(ITextureSource *tsrc,
+               const std::string &imagename);
 #endif