summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRealBadAngel <maciej.kasatkin@o2.pl>2016-01-24 14:19:17 +0100
committerest31 <MTest31@outlook.com>2016-02-07 19:51:55 +0100
commit6cd2b3b445bf558fda1e5a7908adef8e3a45449a (patch)
treee8c48b85e55f4e86246ee21e093cee7f80146c04
parentbf884e37a06e0a8dd6c31789a69921f07ec5a9a9 (diff)
downloadminetest-6cd2b3b445bf558fda1e5a7908adef8e3a45449a.tar.gz
minetest-6cd2b3b445bf558fda1e5a7908adef8e3a45449a.tar.bz2
minetest-6cd2b3b445bf558fda1e5a7908adef8e3a45449a.zip
Use meshes to display inventory items
-rw-r--r--builtin/settingtypes.txt3
-rw-r--r--minetest.conf.example3
-rw-r--r--src/defaultsettings.cpp1
-rw-r--r--src/guiFormSpecMenu.cpp79
-rw-r--r--src/guiFormSpecMenu.h20
-rw-r--r--src/hud.cpp99
-rw-r--r--src/hud.h9
-rw-r--r--src/itemdef.cpp101
-rw-r--r--src/wieldmesh.cpp117
-rw-r--r--src/wieldmesh.h4
10 files changed, 281 insertions, 155 deletions
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"<<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
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 2ba47f7ff..9b892f192 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -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 @@ 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<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 @@ 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<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)
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<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
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);
-
- 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);
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<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;
+}
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<f32> m_bounding_box;
};
+scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item);
+
+scene::IMesh *getExtrudedMesh(ITextureSource *tsrc,
+ const std::string &imagename);
#endif