Skip to content

Commit 6cd2b3b

Browse files
RealBadAngelest31
authored andcommittedFeb 7, 2016
Use meshes to display inventory items
1 parent bf884e3 commit 6cd2b3b

10 files changed

+281
-155
lines changed
 

‎builtin/settingtypes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,9 @@ directional_colored_fog (Colored fog) bool true
508508
# set to the nearest valid value.
509509
ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0
510510

511+
# Enables animation of inventory items.
512+
inventory_items_animations (Inventory items animations) bool false
513+
511514
[**Menus]
512515

513516
# Use a cloud animation for the main menu background.

‎minetest.conf.example

+3
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,9 @@
588588
# type: float min: 0.25 max: 4
589589
# ambient_occlusion_gamma = 2.2
590590

591+
# Enable animation of inventory items.
592+
# inventory_items_animations = false
593+
591594
### Menus
592595

593596
# Use a cloud animation for the main menu background.

‎src/defaultsettings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ void set_default_settings(Settings *settings)
138138
settings->setDefault("console_alpha", "200");
139139
settings->setDefault("selectionbox_color", "(0,0,0)");
140140
settings->setDefault("enable_node_highlighting", "false");
141+
settings->setDefault("inventory_items_animations", "false");
141142
settings->setDefault("crosshair_color", "(255,255,255)");
142143
settings->setDefault("crosshair_alpha", "255");
143144
settings->setDefault("hud_scaling", "1.0");

‎src/guiFormSpecMenu.cpp

+45-34
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)
572572

573573
if(!data->explicit_size)
574574
warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
575-
m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
575+
m_itemimages.push_back(ImageDrawSpec("", name, pos, geom));
576576
return;
577577
}
578578
errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'" << std::endl;
@@ -1483,7 +1483,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
14831483
IItemDefManager *idef = m_gamedef->idef();
14841484
ItemStack item;
14851485
item.deSerialize(item_name, idef);
1486-
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
14871486

14881487
m_tooltips[name] =
14891488
TooltipSpec(item.getDefinition(idef).description,
@@ -1505,13 +1504,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
15051504
}
15061505

15071506
e->setUseAlphaChannel(true);
1508-
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
1509-
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
1507+
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
1508+
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
15101509
e->setScaleImage(true);
15111510
spec.ftype = f_Button;
15121511
rect+=data->basepos-padding;
15131512
spec.rect=rect;
15141513
m_fields.push_back(spec);
1514+
pos = padding + AbsoluteRect.UpperLeftCorner;
1515+
pos.X += stof(v_pos[0]) * (float) spacing.X;
1516+
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
1517+
m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom));
15151518
return;
15161519
}
15171520
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
@@ -2151,7 +2154,8 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
21512154
return ItemSpec(InventoryLocation(), "", -1);
21522155
}
21532156

2154-
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
2157+
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase,
2158+
bool &item_hovered)
21552159
{
21562160
video::IVideoDriver* driver = Environment->getVideoDriver();
21572161

@@ -2193,12 +2197,13 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
21932197
&& m_selected_item->i == item_i;
21942198
bool hovering = rect.isPointInside(m_pointer);
21952199

2196-
if(phase == 0)
2197-
{
2198-
if(hovering)
2200+
if (phase == 0) {
2201+
if (hovering) {
2202+
item_hovered = true;
21992203
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
2200-
else
2204+
} else {
22012205
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
2206+
}
22022207
}
22032208

22042209
//Draw inv slot borders
@@ -2232,7 +2237,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
22322237
if(!item.empty())
22332238
{
22342239
drawItemStack(driver, m_font, item,
2235-
rect, &AbsoluteClippingRect, m_gamedef);
2240+
rect, &AbsoluteClippingRect, m_gamedef,
2241+
selected, hovering, false);
22362242
}
22372243

22382244
// Draw tooltip
@@ -2273,11 +2279,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
22732279

22742280
void GUIFormSpecMenu::drawSelectedItem()
22752281
{
2276-
if(!m_selected_item)
2277-
return;
2278-
22792282
video::IVideoDriver* driver = Environment->getVideoDriver();
22802283

2284+
if (!m_selected_item) {
2285+
drawItemStack(driver, m_font, ItemStack(),
2286+
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
2287+
NULL, m_gamedef, false, false, true);
2288+
return;
2289+
}
2290+
22812291
Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
22822292
sanity_check(inv);
22832293
InventoryList *list = inv->getList(m_selected_item->listname);
@@ -2287,7 +2297,7 @@ void GUIFormSpecMenu::drawSelectedItem()
22872297

22882298
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
22892299
core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
2290-
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef);
2300+
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, false, false, true);
22912301
}
22922302

22932303
void GUIFormSpecMenu::drawMenu()
@@ -2369,6 +2379,12 @@ void GUIFormSpecMenu::drawMenu()
23692379

23702380
driver->draw2DRectangle(todraw, rect, 0);
23712381
}
2382+
2383+
/*
2384+
Call base class
2385+
*/
2386+
gui::IGUIElement::draw();
2387+
23722388
/*
23732389
Draw images
23742390
*/
@@ -2413,36 +2429,31 @@ void GUIFormSpecMenu::drawMenu()
24132429
const ImageDrawSpec &spec = m_itemimages[i];
24142430
IItemDefManager *idef = m_gamedef->idef();
24152431
ItemStack item;
2416-
item.deSerialize(spec.name, idef);
2417-
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
2418-
// Image size on screen
2432+
item.deSerialize(spec.item_name, idef);
24192433
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
2420-
// Image rectangle on screen
2434+
// Viewport rectangle on screen
24212435
core::rect<s32> rect = imgrect + spec.pos;
2422-
const video::SColor color(255,255,255,255);
2423-
const video::SColor colors[] = {color,color,color,color};
2424-
draw2DImageFilterScaled(driver, texture, rect,
2425-
core::rect<s32>(core::position2d<s32>(0,0),
2426-
core::dimension2di(texture->getOriginalSize())),
2427-
NULL/*&AbsoluteClippingRect*/, colors, true);
2436+
drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
2437+
m_gamedef, false, false, false);
24282438
}
24292439

24302440
/*
24312441
Draw items
24322442
Phase 0: Item slot rectangles
24332443
Phase 1: Item images; prepare tooltip
24342444
*/
2435-
int start_phase=0;
2436-
for(int phase=start_phase; phase<=1; phase++)
2437-
for(u32 i=0; i<m_inventorylists.size(); i++)
2438-
{
2439-
drawList(m_inventorylists[i], phase);
2445+
bool item_hovered = false;
2446+
int start_phase = 0;
2447+
for (int phase = start_phase; phase <= 1; phase++) {
2448+
for (u32 i = 0; i < m_inventorylists.size(); i++) {
2449+
drawList(m_inventorylists[i], phase, item_hovered);
2450+
}
2451+
}
2452+
if (!item_hovered) {
2453+
drawItemStack(driver, m_font, ItemStack(),
2454+
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
2455+
NULL, m_gamedef, false, true, false);
24402456
}
2441-
2442-
/*
2443-
Call base class
2444-
*/
2445-
gui::IGUIElement::draw();
24462457

24472458
/* TODO find way to show tooltips on touchscreen */
24482459
#ifndef HAVE_TOUCHSCREENGUI

‎src/guiFormSpecMenu.h

+17-3
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,32 @@ class GUIFormSpecMenu : public GUIModalMenu
143143
{
144144
}
145145
ImageDrawSpec(const std::string &a_name,
146-
v2s32 a_pos, v2s32 a_geom):
146+
const std::string &a_item_name,
147+
const v2s32 &a_pos, const v2s32 &a_geom):
147148
name(a_name),
149+
item_name (a_item_name),
148150
pos(a_pos),
149151
geom(a_geom)
150152
{
151153
scale = true;
152154
}
153155
ImageDrawSpec(const std::string &a_name,
154-
v2s32 a_pos):
156+
const v2s32 &a_pos, const v2s32 &a_geom):
157+
name(a_name),
158+
pos(a_pos),
159+
geom(a_geom)
160+
{
161+
scale = true;
162+
}
163+
ImageDrawSpec(const std::string &a_name,
164+
const v2s32 &a_pos):
155165
name(a_name),
156166
pos(a_pos)
157167
{
158168
scale = false;
159169
}
160170
std::string name;
171+
std::string item_name;
161172
v2s32 pos;
162173
v2s32 geom;
163174
bool scale;
@@ -282,7 +293,7 @@ class GUIFormSpecMenu : public GUIModalMenu
282293
void regenerateGui(v2u32 screensize);
283294

284295
ItemSpec getItemAtPos(v2s32 p) const;
285-
void drawList(const ListDrawSpec &s, int phase);
296+
void drawList(const ListDrawSpec &s, int phase, bool &item_hovered);
286297
void drawSelectedItem();
287298
void drawMenu();
288299
void updateSelectedItem();
@@ -334,6 +345,8 @@ class GUIFormSpecMenu : public GUIModalMenu
334345
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
335346

336347
ItemSpec *m_selected_item;
348+
f32 m_timer1;
349+
f32 m_timer2;
337350
u32 m_selected_amount;
338351
bool m_selected_dragging;
339352

@@ -373,6 +386,7 @@ class GUIFormSpecMenu : public GUIModalMenu
373386
TextDest *m_text_dst;
374387
unsigned int m_formspec_version;
375388
std::string m_focused_element;
389+
bool m_selection_active;
376390

377391
typedef struct {
378392
bool explicit_size;

‎src/hud.cpp

+84-15
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
8282
use_hotbar_selected_image = false;
8383
}
8484

85-
void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected) {
86-
85+
void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
86+
bool selected)
87+
{
8788
if (selected) {
8889
/* draw hihlighting around selected item */
8990
if (use_hotbar_selected_image) {
@@ -154,7 +155,8 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool sele
154155
video::SColor bgcolor2(128, 0, 0, 0);
155156
if (!use_hotbar_image)
156157
driver->draw2DRectangle(bgcolor2, rect, NULL);
157-
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef);
158+
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
159+
gamedef, selected, false, false);
158160
}
159161

160162
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
@@ -489,23 +491,90 @@ void drawItemStack(video::IVideoDriver *driver,
489491
const ItemStack &item,
490492
const core::rect<s32> &rect,
491493
const core::rect<s32> *clip,
492-
IGameDef *gamedef)
494+
IGameDef *gamedef,
495+
bool selected,
496+
bool hovered,
497+
bool dragged)
493498
{
494-
if(item.empty())
499+
static s32 hovered_time;
500+
static s32 selected_time;
501+
static s32 dragged_time;
502+
static scene::IMesh *hovered_mesh;
503+
static scene::IMesh *selected_mesh;
504+
static scene::IMesh *dragged_mesh;
505+
bool enable_animations =
506+
g_settings->getBool("inventory_items_animations");
507+
508+
if (item.empty()) {
509+
if (selected) {
510+
selected_mesh = NULL;
511+
} else if (hovered) {
512+
hovered_mesh = NULL;
513+
} else if (dragged) {
514+
dragged_mesh = NULL;
515+
}
495516
return;
517+
}
496518

497519
const ItemDefinition &def = item.getDefinition(gamedef->idef());
498-
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
520+
scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);
521+
522+
if (mesh) {
523+
driver->clearZBuffer();
524+
s32 delta = 0;
525+
if (selected) {
526+
if (mesh != selected_mesh) {
527+
selected_mesh = mesh;
528+
selected_time = getTimeMs();
529+
} else {
530+
delta = porting::getDeltaMs(selected_time, getTimeMs()) % 100000;
531+
}
532+
} else if (hovered) {
533+
if (mesh != hovered_mesh) {
534+
hovered_mesh = mesh;
535+
hovered_time = getTimeMs();
536+
} else {
537+
delta = porting::getDeltaMs(hovered_time, getTimeMs()) % 100000;
538+
}
539+
} else if (dragged) {
540+
if (mesh != dragged_mesh) {
541+
dragged_mesh = mesh;
542+
dragged_time = getTimeMs();
543+
} else {
544+
delta = porting::getDeltaMs(dragged_time, getTimeMs()) % 100000;
545+
}
546+
}
547+
core::rect<s32> oldViewPort = driver->getViewPort();
548+
core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
549+
core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
550+
core::matrix4 ProjMatrix;
551+
ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
552+
driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
553+
driver->setTransform(video::ETS_VIEW, ProjMatrix);
554+
core::matrix4 matrix;
555+
matrix.makeIdentity();
556+
557+
if (enable_animations) {
558+
float timer_f = (float)delta / 5000.0;
559+
matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
560+
}
499561

500-
// Draw the inventory texture
501-
if(texture != NULL)
502-
{
503-
const video::SColor color(255,255,255,255);
504-
const video::SColor colors[] = {color,color,color,color};
505-
draw2DImageFilterScaled(driver, texture, rect,
506-
core::rect<s32>(core::position2d<s32>(0,0),
507-
core::dimension2di(texture->getOriginalSize())),
508-
clip, colors, true);
562+
driver->setTransform(video::ETS_WORLD, matrix);
563+
driver->setViewPort(rect);
564+
565+
u32 mc = mesh->getMeshBufferCount();
566+
for (u32 j = 0; j < mc; ++j) {
567+
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
568+
video::SMaterial &material = buf->getMaterial();
569+
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
570+
material.Lighting = false;
571+
driver->setMaterial(material);
572+
driver->drawMeshBuffer(buf);
573+
}
574+
575+
driver->setTransform(video::ETS_VIEW, oldViewMat);
576+
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
577+
driver->setViewPort(oldViewPort);
509578
}
510579

511580
if(def.type == ITEM_TOOL && item.wear != 0)

‎src/hud.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ class Hud {
137137
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
138138
InventoryList *mainlist, u16 selectitem, u16 direction);
139139

140-
void drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected);
140+
void drawItem(const ItemStack &item, const core::rect<s32>& rect,
141+
bool selected);
141142

142143
v2u32 m_screensize;
143144
v2s32 m_displaycenter;
@@ -151,8 +152,10 @@ void drawItemStack(video::IVideoDriver *driver,
151152
const ItemStack &item,
152153
const core::rect<s32> &rect,
153154
const core::rect<s32> *clip,
154-
IGameDef *gamedef);
155-
155+
IGameDef *gamedef,
156+
bool selected,
157+
bool hovered,
158+
bool dragged);
156159

157160
#endif
158161

‎src/itemdef.cpp

+4-97
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ class CItemDefManager: public IWritableItemDefManager
332332
return cc;
333333

334334
ITextureSource *tsrc = gamedef->getTextureSource();
335-
INodeDefManager *nodedef = gamedef->getNodeDefManager();
336335
const ItemDefinition &def = get(name);
337336

338337
// Create new ClientCached
@@ -343,103 +342,11 @@ class CItemDefManager: public IWritableItemDefManager
343342
if(def.inventory_image != "")
344343
cc->inventory_texture = tsrc->getTexture(def.inventory_image);
345344

346-
// Additional processing for nodes:
347-
// - Create a wield mesh if WieldMeshSceneNode can't render
348-
// the node on its own.
349-
// - If inventory_texture isn't set yet, create one using
350-
// render-to-texture.
351-
if (def.type == ITEM_NODE) {
352-
// Get node properties
353-
content_t id = nodedef->getId(name);
354-
const ContentFeatures &f = nodedef->get(id);
355-
356-
bool need_rtt_mesh = cc->inventory_texture == NULL;
357-
358-
// Keep this in sync with WieldMeshSceneNode::setItem()
359-
bool need_wield_mesh =
360-
!(f.mesh_ptr[0] ||
361-
f.drawtype == NDT_NORMAL ||
362-
f.drawtype == NDT_ALLFACES ||
363-
f.drawtype == NDT_AIRLIKE);
364-
365-
scene::IMesh *node_mesh = NULL;
366-
367-
if (need_rtt_mesh || need_wield_mesh) {
368-
u8 param1 = 0;
369-
if (f.param_type == CPT_LIGHT)
370-
param1 = 0xee;
371-
372-
/*
373-
Make a mesh from the node
374-
*/
375-
MeshMakeData mesh_make_data(gamedef, false);
376-
u8 param2 = 0;
377-
if (f.param_type_2 == CPT2_WALLMOUNTED)
378-
param2 = 1;
379-
MapNode mesh_make_node(id, param1, param2);
380-
mesh_make_data.fillSingleNode(&mesh_make_node);
381-
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
382-
node_mesh = mapblock_mesh.getMesh();
383-
node_mesh->grab();
384-
video::SColor c(255, 255, 255, 255);
385-
setMeshColor(node_mesh, c);
386-
387-
// scale and translate the mesh so it's a
388-
// unit cube centered on the origin
389-
scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
390-
translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));
391-
}
392-
393-
/*
394-
Draw node mesh into a render target texture
395-
*/
396-
if (need_rtt_mesh) {
397-
TextureFromMeshParams params;
398-
params.mesh = node_mesh;
399-
params.dim.set(64, 64);
400-
params.rtt_texture_name = "INVENTORY_"
401-
+ def.name + "_RTT";
402-
params.delete_texture_on_shutdown = true;
403-
params.camera_position.set(0, 1.0, -1.5);
404-
params.camera_position.rotateXZBy(45);
405-
params.camera_lookat.set(0, 0, 0);
406-
// Set orthogonal projection
407-
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
408-
1.65, 1.65, 0, 100);
409-
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
410-
params.light_position.set(10, 100, -50);
411-
params.light_color.set(1.0, 0.5, 0.5, 0.5);
412-
params.light_radius = 1000;
413-
414-
#ifdef __ANDROID__
415-
params.camera_position.set(0, -1.0, -1.5);
416-
params.camera_position.rotateXZBy(45);
417-
params.light_position.set(10, -100, -50);
418-
#endif
419-
cc->inventory_texture =
420-
tsrc->generateTextureFromMesh(params);
421-
422-
// render-to-target didn't work
423-
if (cc->inventory_texture == NULL) {
424-
cc->inventory_texture =
425-
tsrc->getTexture(f.tiledef[0].name);
426-
}
427-
}
428-
429-
/*
430-
Use the node mesh as the wield mesh
431-
*/
432-
if (need_wield_mesh) {
433-
cc->wield_mesh = node_mesh;
434-
cc->wield_mesh->grab();
345+
ItemStack item = ItemStack();
346+
item.name = def.name;
435347

436-
// no way reference count can be smaller than 2 in this place!
437-
assert(cc->wield_mesh->getReferenceCount() >= 2);
438-
}
439-
440-
if (node_mesh)
441-
node_mesh->drop();
442-
}
348+
scene::IMesh *mesh = getItemMesh(gamedef, item);
349+
cc->wield_mesh = mesh;
443350

444351
// Put in cache
445352
m_clientcached.set(name, cc);

‎src/wieldmesh.cpp

+114-3
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,7 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
114114
mesh->addMeshBuffer(buf);
115115
buf->drop();
116116
scaleMesh(mesh, scale); // also recalculates bounding box
117-
scene::IMesh *newmesh = createForsythOptimizedMesh(mesh);
118-
mesh->drop();
119-
return newmesh;
117+
return mesh;
120118
}
121119

122120
/*
@@ -436,3 +434,116 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
436434
m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting);
437435
m_meshnode->setVisible(true);
438436
}
437+
438+
scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item)
439+
{
440+
ITextureSource *tsrc = gamedef->getTextureSource();
441+
IItemDefManager *idef = gamedef->getItemDefManager();
442+
INodeDefManager *ndef = gamedef->getNodeDefManager();
443+
const ItemDefinition &def = item.getDefinition(idef);
444+
const ContentFeatures &f = ndef->get(def.name);
445+
content_t id = ndef->getId(def.name);
446+
447+
if (!g_extrusion_mesh_cache) {
448+
g_extrusion_mesh_cache = new ExtrusionMeshCache();
449+
} else {
450+
g_extrusion_mesh_cache->grab();
451+
}
452+
453+
scene::IMesh *mesh;
454+
455+
// If wield_image is defined, it overrides everything else
456+
if (def.wield_image != "") {
457+
mesh = getExtrudedMesh(tsrc, def.wield_image);
458+
return mesh;
459+
} else if (def.inventory_image != "") {
460+
mesh = getExtrudedMesh(tsrc, def.inventory_image);
461+
return mesh;
462+
} else if (def.type == ITEM_NODE) {
463+
if (f.mesh_ptr[0]) {
464+
mesh = cloneMesh(f.mesh_ptr[0]);
465+
scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
466+
setMeshColor(mesh, video::SColor (255, 255, 255, 255));
467+
} else if (f.drawtype == NDT_PLANTLIKE) {
468+
mesh = getExtrudedMesh(tsrc,
469+
tsrc->getTextureName(f.tiles[0].texture_id));
470+
return mesh;
471+
} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES
472+
|| f.drawtype == NDT_LIQUID || f.drawtype == NDT_FLOWINGLIQUID) {
473+
mesh = cloneMesh(g_extrusion_mesh_cache->createCube());
474+
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
475+
} else {
476+
MeshMakeData mesh_make_data(gamedef, false);
477+
MapNode mesh_make_node(id, 255, 0);
478+
mesh_make_data.fillSingleNode(&mesh_make_node);
479+
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
480+
mesh = cloneMesh(mapblock_mesh.getMesh());
481+
translateMesh(mesh, v3f(-BS, -BS, -BS));
482+
scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
483+
rotateMeshXZby(mesh, -45);
484+
rotateMeshYZby(mesh, -30);
485+
486+
u32 mc = mesh->getMeshBufferCount();
487+
for (u32 i = 0; i < mc; ++i) {
488+
video::SMaterial &material1 =
489+
mesh->getMeshBuffer(i)->getMaterial();
490+
video::SMaterial &material2 =
491+
mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial();
492+
material1.setTexture(0, material2.getTexture(0));
493+
material1.setTexture(1, material2.getTexture(1));
494+
material1.setTexture(2, material2.getTexture(2));
495+
material1.setTexture(3, material2.getTexture(3));
496+
material1.MaterialType = material2.MaterialType;
497+
}
498+
return mesh;
499+
}
500+
501+
shadeMeshFaces(mesh);
502+
rotateMeshXZby(mesh, -45);
503+
rotateMeshYZby(mesh, -30);
504+
505+
u32 mc = mesh->getMeshBufferCount();
506+
for (u32 i = 0; i < mc; ++i) {
507+
video::SMaterial &material = mesh->getMeshBuffer(i)->getMaterial();
508+
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
509+
material.setFlag(video::EMF_BILINEAR_FILTER, false);
510+
material.setFlag(video::EMF_TRILINEAR_FILTER, false);
511+
material.setFlag(video::EMF_BACK_FACE_CULLING, true);
512+
material.setFlag(video::EMF_LIGHTING, false);
513+
if (f.tiles[i].animation_frame_count > 1) {
514+
FrameSpec animation_frame = f.tiles[i].frames[0];
515+
material.setTexture(0, animation_frame.texture);
516+
} else {
517+
material.setTexture(0, f.tiles[i].texture);
518+
}
519+
}
520+
return mesh;
521+
}
522+
return NULL;
523+
}
524+
525+
scene::IMesh * getExtrudedMesh(ITextureSource *tsrc,
526+
const std::string &imagename)
527+
{
528+
video::ITexture *texture = tsrc->getTextureForMesh(imagename);
529+
if (!texture) {
530+
return NULL;
531+
}
532+
533+
core::dimension2d<u32> dim = texture->getSize();
534+
scene::IMesh *mesh = cloneMesh(g_extrusion_mesh_cache->create(dim));
535+
536+
// Customize material
537+
video::SMaterial &material = mesh->getMeshBuffer(0)->getMaterial();
538+
material.setTexture(0, tsrc->getTexture(imagename));
539+
material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
540+
material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
541+
material.setFlag(video::EMF_BILINEAR_FILTER, false);
542+
material.setFlag(video::EMF_TRILINEAR_FILTER, false);
543+
material.setFlag(video::EMF_BACK_FACE_CULLING, true);
544+
material.setFlag(video::EMF_LIGHTING, false);
545+
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
546+
scaleMesh(mesh, v3f(2.0, 2.0, 2.0));
547+
548+
return mesh;
549+
}

‎src/wieldmesh.h

+4
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@ class WieldMeshSceneNode: public scene::ISceneNode
7777
core::aabbox3d<f32> m_bounding_box;
7878
};
7979

80+
scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item);
81+
82+
scene::IMesh *getExtrudedMesh(ITextureSource *tsrc,
83+
const std::string &imagename);
8084
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.