Merge, part 1/2
This commit is contained in:
parent
925a9d8373
commit
4be9d9a393
|
@ -588,6 +588,9 @@
|
||||||
# type: float min: 0.25 max: 4
|
# type: float min: 0.25 max: 4
|
||||||
# ambient_occlusion_gamma = 2.2
|
# ambient_occlusion_gamma = 2.2
|
||||||
|
|
||||||
|
# Enable animation of inventory items.
|
||||||
|
# inventory_items_animations = false
|
||||||
|
|
||||||
### Menus
|
### Menus
|
||||||
|
|
||||||
# Use a cloud animation for the main menu background.
|
# Use a cloud animation for the main menu background.
|
||||||
|
|
|
@ -137,6 +137,7 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("console_alpha", "200");
|
settings->setDefault("console_alpha", "200");
|
||||||
settings->setDefault("selectionbox_color", "(0,0,0)");
|
settings->setDefault("selectionbox_color", "(0,0,0)");
|
||||||
settings->setDefault("enable_node_highlighting", "true");
|
settings->setDefault("enable_node_highlighting", "true");
|
||||||
|
settings->setDefault("inventory_items_animations", "false");
|
||||||
settings->setDefault("crosshair_color", "(255,255,255)");
|
settings->setDefault("crosshair_color", "(255,255,255)");
|
||||||
settings->setDefault("crosshair_alpha", "255");
|
settings->setDefault("crosshair_alpha", "255");
|
||||||
settings->setDefault("hud_scaling", "1.0");
|
settings->setDefault("hud_scaling", "1.0");
|
||||||
|
|
|
@ -572,7 +572,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)
|
||||||
|
|
||||||
if(!data->explicit_size)
|
if(!data->explicit_size)
|
||||||
warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'" << std::endl;
|
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();
|
IItemDefManager *idef = m_gamedef->idef();
|
||||||
ItemStack item;
|
ItemStack item;
|
||||||
item.deSerialize(item_name, idef);
|
item.deSerialize(item_name, idef);
|
||||||
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
|
|
||||||
|
|
||||||
m_tooltips[name] =
|
m_tooltips[name] =
|
||||||
TooltipSpec(item.getDefinition(idef).description,
|
TooltipSpec(item.getDefinition(idef).description,
|
||||||
|
@ -1505,13 +1504,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
|
||||||
}
|
}
|
||||||
|
|
||||||
e->setUseAlphaChannel(true);
|
e->setUseAlphaChannel(true);
|
||||||
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
|
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
|
||||||
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
|
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
|
||||||
e->setScaleImage(true);
|
e->setScaleImage(true);
|
||||||
spec.ftype = f_Button;
|
spec.ftype = f_Button;
|
||||||
rect+=data->basepos-padding;
|
rect+=data->basepos-padding;
|
||||||
spec.rect=rect;
|
spec.rect=rect;
|
||||||
m_fields.push_back(spec);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
|
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||||
|
@ -2151,7 +2154,8 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
|
||||||
return ItemSpec(InventoryLocation(), "", -1);
|
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();
|
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||||
|
|
||||||
|
@ -2192,13 +2196,17 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
|
||||||
&& m_selected_item->listname == s.listname
|
&& m_selected_item->listname == s.listname
|
||||||
&& m_selected_item->i == item_i;
|
&& m_selected_item->i == item_i;
|
||||||
bool hovering = rect.isPointInside(m_pointer);
|
bool hovering = rect.isPointInside(m_pointer);
|
||||||
|
ItemRotationKind rotation_kind = selected ? IT_ROT_SELECTED :
|
||||||
|
(hovering ? IT_ROT_HOVERED : IT_ROT_NONE);
|
||||||
|
|
||||||
if(phase == 0)
|
if (phase == 0) {
|
||||||
{
|
if (hovering)
|
||||||
if(hovering)
|
|
||||||
|
item_hovered = true;
|
||||||
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
|
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
|
||||||
else
|
} else {
|
||||||
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
|
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw inv slot borders
|
//Draw inv slot borders
|
||||||
|
@ -2232,6 +2240,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
|
||||||
if(!item.empty())
|
if(!item.empty())
|
||||||
{
|
{
|
||||||
drawItemStack(driver, m_font, item,
|
drawItemStack(driver, m_font, item,
|
||||||
|
rect, &AbsoluteClippingRect, m_gamedef,
|
||||||
|
rotation_kind);
|
||||||
rect, &AbsoluteClippingRect, m_gamedef);
|
rect, &AbsoluteClippingRect, m_gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2273,11 +2283,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
|
||||||
|
|
||||||
void GUIFormSpecMenu::drawSelectedItem()
|
void GUIFormSpecMenu::drawSelectedItem()
|
||||||
{
|
{
|
||||||
if(!m_selected_item)
|
|
||||||
return;
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
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, IT_ROT_DRAGGED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
|
Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
|
||||||
sanity_check(inv);
|
sanity_check(inv);
|
||||||
InventoryList *list = inv->getList(m_selected_item->listname);
|
InventoryList *list = inv->getList(m_selected_item->listname);
|
||||||
|
@ -2287,7 +2301,7 @@ void GUIFormSpecMenu::drawSelectedItem()
|
||||||
|
|
||||||
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
|
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
|
||||||
core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
|
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, IT_ROT_DRAGGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::drawMenu()
|
void GUIFormSpecMenu::drawMenu()
|
||||||
|
@ -2369,6 +2383,12 @@ void GUIFormSpecMenu::drawMenu()
|
||||||
|
|
||||||
driver->draw2DRectangle(todraw, rect, 0);
|
driver->draw2DRectangle(todraw, rect, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Call base class
|
||||||
|
*/
|
||||||
|
gui::IGUIElement::draw();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Draw images
|
Draw images
|
||||||
*/
|
*/
|
||||||
|
@ -2413,18 +2433,12 @@ void GUIFormSpecMenu::drawMenu()
|
||||||
const ImageDrawSpec &spec = m_itemimages[i];
|
const ImageDrawSpec &spec = m_itemimages[i];
|
||||||
IItemDefManager *idef = m_gamedef->idef();
|
IItemDefManager *idef = m_gamedef->idef();
|
||||||
ItemStack item;
|
ItemStack item;
|
||||||
item.deSerialize(spec.name, idef);
|
item.deSerialize(spec.item_name, idef);
|
||||||
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
|
|
||||||
// Image size on screen
|
|
||||||
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
|
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;
|
core::rect<s32> rect = imgrect + spec.pos;
|
||||||
const video::SColor color(255,255,255,255);
|
drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
|
||||||
const video::SColor colors[] = {color,color,color,color};
|
m_gamedef, IT_ROT_NONE);
|
||||||
draw2DImageFilterScaled(driver, texture, rect,
|
|
||||||
core::rect<s32>(core::position2d<s32>(0,0),
|
|
||||||
core::dimension2di(texture->getOriginalSize())),
|
|
||||||
NULL/*&AbsoluteClippingRect*/, colors, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2432,17 +2446,18 @@ void GUIFormSpecMenu::drawMenu()
|
||||||
Phase 0: Item slot rectangles
|
Phase 0: Item slot rectangles
|
||||||
Phase 1: Item images; prepare tooltip
|
Phase 1: Item images; prepare tooltip
|
||||||
*/
|
*/
|
||||||
int start_phase=0;
|
bool item_hovered = false;
|
||||||
for(int phase=start_phase; phase<=1; phase++)
|
int start_phase = 0;
|
||||||
for(u32 i=0; i<m_inventorylists.size(); i++)
|
for (int phase = start_phase; phase <= 1; phase++) {
|
||||||
{
|
for (u32 i = 0; i < m_inventorylists.size(); i++) {
|
||||||
drawList(m_inventorylists[i], phase);
|
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 */
|
/* TODO find way to show tooltips on touchscreen */
|
||||||
#ifndef HAVE_TOUCHSCREENGUI
|
#ifndef HAVE_TOUCHSCREENGUI
|
||||||
|
|
|
@ -144,6 +144,17 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||||
}
|
}
|
||||||
ImageDrawSpec(const std::string &a_name,
|
ImageDrawSpec(const std::string &a_name,
|
||||||
v2s32 a_pos, v2s32 a_geom):
|
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),
|
name(a_name),
|
||||||
pos(a_pos),
|
pos(a_pos),
|
||||||
geom(a_geom)
|
geom(a_geom)
|
||||||
|
@ -151,13 +162,14 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||||
scale = true;
|
scale = true;
|
||||||
}
|
}
|
||||||
ImageDrawSpec(const std::string &a_name,
|
ImageDrawSpec(const std::string &a_name,
|
||||||
v2s32 a_pos):
|
const v2s32 &a_pos):
|
||||||
name(a_name),
|
name(a_name),
|
||||||
pos(a_pos)
|
pos(a_pos)
|
||||||
{
|
{
|
||||||
scale = false;
|
scale = false;
|
||||||
}
|
}
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string item_name;
|
||||||
v2s32 pos;
|
v2s32 pos;
|
||||||
v2s32 geom;
|
v2s32 geom;
|
||||||
bool scale;
|
bool scale;
|
||||||
|
@ -282,7 +294,7 @@ public:
|
||||||
void regenerateGui(v2u32 screensize);
|
void regenerateGui(v2u32 screensize);
|
||||||
|
|
||||||
ItemSpec getItemAtPos(v2s32 p) const;
|
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 drawSelectedItem();
|
||||||
void drawMenu();
|
void drawMenu();
|
||||||
void updateSelectedItem();
|
void updateSelectedItem();
|
||||||
|
@ -334,6 +346,8 @@ protected:
|
||||||
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
|
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
|
||||||
|
|
||||||
ItemSpec *m_selected_item;
|
ItemSpec *m_selected_item;
|
||||||
|
f32 m_timer1;
|
||||||
|
f32 m_timer2;
|
||||||
u32 m_selected_amount;
|
u32 m_selected_amount;
|
||||||
bool m_selected_dragging;
|
bool m_selected_dragging;
|
||||||
|
|
||||||
|
@ -373,6 +387,7 @@ private:
|
||||||
TextDest *m_text_dst;
|
TextDest *m_text_dst;
|
||||||
unsigned int m_formspec_version;
|
unsigned int m_formspec_version;
|
||||||
std::string m_focused_element;
|
std::string m_focused_element;
|
||||||
|
bool m_selection_active;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool explicit_size;
|
bool explicit_size;
|
||||||
|
|
80
src/hud.cpp
80
src/hud.cpp
|
@ -82,8 +82,9 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
||||||
use_hotbar_selected_image = false;
|
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) {
|
if (selected) {
|
||||||
/* draw hihlighting around selected item */
|
/* draw hihlighting around selected item */
|
||||||
if (use_hotbar_selected_image) {
|
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);
|
video::SColor bgcolor2(128, 0, 0, 0);
|
||||||
if (!use_hotbar_image)
|
if (!use_hotbar_image)
|
||||||
driver->draw2DRectangle(bgcolor2, rect, NULL);
|
driver->draw2DRectangle(bgcolor2, rect, NULL);
|
||||||
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef);
|
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
|
||||||
|
gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
|
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
|
||||||
|
@ -484,28 +486,76 @@ void Hud::resizeHotbar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MeshTimeInfo {
|
||||||
|
s32 time;
|
||||||
|
scene::IMesh *mesh;
|
||||||
|
};
|
||||||
|
|
||||||
void drawItemStack(video::IVideoDriver *driver,
|
void drawItemStack(video::IVideoDriver *driver,
|
||||||
gui::IGUIFont *font,
|
gui::IGUIFont *font,
|
||||||
const ItemStack &item,
|
const ItemStack &item,
|
||||||
const core::rect<s32> &rect,
|
const core::rect<s32> &rect,
|
||||||
const core::rect<s32> *clip,
|
const core::rect<s32> *clip,
|
||||||
IGameDef *gamedef)
|
IGameDef *gamedef,
|
||||||
|
ItemRotationKind rotation_kind)
|
||||||
{
|
{
|
||||||
if(item.empty())
|
static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
|
||||||
|
static bool enable_animations =
|
||||||
|
g_settings->getBool("inventory_items_animations");
|
||||||
|
|
||||||
|
if (item.empty()) {
|
||||||
|
if (rotation_kind < IT_ROT_NONE) {
|
||||||
|
rotation_time_infos[rotation_kind].mesh = NULL;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const ItemDefinition &def = item.getDefinition(gamedef->idef());
|
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 (mesh) {
|
||||||
if(texture != NULL)
|
driver->clearZBuffer();
|
||||||
{
|
s32 delta = 0;
|
||||||
const video::SColor color(255,255,255,255);
|
if (rotation_kind < IT_ROT_NONE) {
|
||||||
const video::SColor colors[] = {color,color,color,color};
|
MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
|
||||||
draw2DImageFilterScaled(driver, texture, rect,
|
if (mesh != ti.mesh) {
|
||||||
core::rect<s32>(core::position2d<s32>(0,0),
|
ti.mesh = mesh;
|
||||||
core::dimension2di(texture->getOriginalSize())),
|
ti.time = getTimeMs();
|
||||||
clip, colors, true);
|
} else {
|
||||||
|
delta = porting::getDeltaMs(ti.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if(def.type == ITEM_TOOL && item.wear != 0)
|
||||||
|
|
14
src/hud.h
14
src/hud.h
|
@ -137,7 +137,8 @@ private:
|
||||||
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
||||||
InventoryList *mainlist, u16 selectitem, u16 direction);
|
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;
|
v2u32 m_screensize;
|
||||||
v2s32 m_displaycenter;
|
v2s32 m_displaycenter;
|
||||||
|
@ -146,13 +147,20 @@ private:
|
||||||
video::SColor hbar_colors[4];
|
video::SColor hbar_colors[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ItemRotationKind {
|
||||||
|
IT_ROT_SELECTED,
|
||||||
|
IT_ROT_HOVERED,
|
||||||
|
IT_ROT_DRAGGED,
|
||||||
|
IT_ROT_NONE, // Must be last, also serves as number
|
||||||
|
};
|
||||||
|
|
||||||
void drawItemStack(video::IVideoDriver *driver,
|
void drawItemStack(video::IVideoDriver *driver,
|
||||||
gui::IGUIFont *font,
|
gui::IGUIFont *font,
|
||||||
const ItemStack &item,
|
const ItemStack &item,
|
||||||
const core::rect<s32> &rect,
|
const core::rect<s32> &rect,
|
||||||
const core::rect<s32> *clip,
|
const core::rect<s32> *clip,
|
||||||
IGameDef *gamedef);
|
IGameDef *gamedef,
|
||||||
|
ItemRotationKind rotation_kind);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
101
src/itemdef.cpp
101
src/itemdef.cpp
|
@ -332,7 +332,6 @@ public:
|
||||||
return cc;
|
return cc;
|
||||||
|
|
||||||
ITextureSource *tsrc = gamedef->getTextureSource();
|
ITextureSource *tsrc = gamedef->getTextureSource();
|
||||||
INodeDefManager *nodedef = gamedef->getNodeDefManager();
|
|
||||||
const ItemDefinition &def = get(name);
|
const ItemDefinition &def = get(name);
|
||||||
|
|
||||||
// Create new ClientCached
|
// Create new ClientCached
|
||||||
|
@ -343,103 +342,11 @@ public:
|
||||||
if(def.inventory_image != "")
|
if(def.inventory_image != "")
|
||||||
cc->inventory_texture = tsrc->getTexture(def.inventory_image);
|
cc->inventory_texture = tsrc->getTexture(def.inventory_image);
|
||||||
|
|
||||||
// Additional processing for nodes:
|
ItemStack item = ItemStack();
|
||||||
// - Create a wield mesh if WieldMeshSceneNode can't render
|
item.name = def.name;
|
||||||
// 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;
|
scene::IMesh *mesh = getItemMesh(gamedef, item);
|
||||||
|
cc->wield_mesh = mesh;
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put in cache
|
// Put in cache
|
||||||
m_clientcached.set(name, cc);
|
m_clientcached.set(name, cc);
|
||||||
|
|
|
@ -1167,7 +1167,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
||||||
|
|
||||||
for(u32 j = 0; j < p.vertices.size(); j++)
|
for(u32 j = 0; j < p.vertices.size(); j++)
|
||||||
{
|
{
|
||||||
video::S3DVertexTangents *vertex = &p.vertices[j];
|
video::S3DVertex *vertex = &p.vertices[j];
|
||||||
// Note applyFacesShading second parameter is precalculated sqrt
|
// Note applyFacesShading second parameter is precalculated sqrt
|
||||||
// value for speed improvement
|
// value for speed improvement
|
||||||
// Skip it for lightsources and top faces.
|
// Skip it for lightsources and top faces.
|
||||||
|
@ -1221,11 +1221,12 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create meshbuffer
|
// Create meshbuffer
|
||||||
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
|
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
// Set material
|
// Set material
|
||||||
buf->Material = material;
|
buf->Material = material;
|
||||||
// Add to mesh
|
// Add to mesh
|
||||||
m_mesh->addMeshBuffer(buf);
|
scene::SMesh *mesh = (scene::SMesh *)m_mesh;
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
// Mesh grabbed it
|
// Mesh grabbed it
|
||||||
buf->drop();
|
buf->drop();
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
buf->append(&p.vertices[0], p.vertices.size(),
|
||||||
|
@ -1241,7 +1242,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
||||||
|
|
||||||
if (m_enable_shaders) {
|
if (m_enable_shaders) {
|
||||||
scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator();
|
scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator();
|
||||||
meshmanip->recalculateTangents(m_mesh, true, false, false);
|
scene::IMesh* tangentMesh = meshmanip->createMeshWithTangents(m_mesh);
|
||||||
|
m_mesh->drop();
|
||||||
|
m_mesh = tangentMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_mesh)
|
if(m_mesh)
|
||||||
|
@ -1361,7 +1364,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
||||||
i != m_daynight_diffs.end(); ++i)
|
i != m_daynight_diffs.end(); ++i)
|
||||||
{
|
{
|
||||||
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
|
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
|
||||||
video::S3DVertexTangents *vertices = (video::S3DVertexTangents *)buf->getVertices();
|
video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices();
|
||||||
for(std::map<u32, std::pair<u8, u8 > >::iterator
|
for(std::map<u32, std::pair<u8, u8 > >::iterator
|
||||||
j = i->second.begin();
|
j = i->second.begin();
|
||||||
j != i->second.end(); ++j)
|
j != i->second.end(); ++j)
|
||||||
|
@ -1392,7 +1395,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
||||||
i != m_highlighted_materials.end(); ++i)
|
i != m_highlighted_materials.end(); ++i)
|
||||||
{
|
{
|
||||||
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(*i);
|
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(*i);
|
||||||
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
|
video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices();
|
||||||
for (u32 j = 0; j < buf->getVertexCount() ;j++)
|
for (u32 j = 0; j < buf->getVertexCount() ;j++)
|
||||||
vertices[j].Color = hc;
|
vertices[j].Color = hc;
|
||||||
}
|
}
|
||||||
|
@ -1448,7 +1451,7 @@ void MeshCollector::append(const TileSpec &tile,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < numVertices; i++) {
|
for (u32 i = 0; i < numVertices; i++) {
|
||||||
video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal,
|
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal,
|
||||||
vertices[i].Color, vertices[i].TCoords);
|
vertices[i].Color, vertices[i].TCoords);
|
||||||
p->vertices.push_back(vert);
|
p->vertices.push_back(vert);
|
||||||
}
|
}
|
||||||
|
@ -1494,7 +1497,7 @@ void MeshCollector::append(const TileSpec &tile,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < numVertices; i++) {
|
for (u32 i = 0; i < numVertices; i++) {
|
||||||
video::S3DVertexTangents vert(vertices[i].Pos + pos, vertices[i].Normal,
|
video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal,
|
||||||
c, vertices[i].TCoords);
|
c, vertices[i].TCoords);
|
||||||
p->vertices.push_back(vert);
|
p->vertices.push_back(vert);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
// Returns true if anything has been changed.
|
// Returns true if anything has been changed.
|
||||||
bool animate(bool faraway, float time, int crack, u32 daynight_ratio);
|
bool animate(bool faraway, float time, int crack, u32 daynight_ratio);
|
||||||
|
|
||||||
scene::SMesh *getMesh()
|
scene::IMesh *getMesh()
|
||||||
{
|
{
|
||||||
return m_mesh;
|
return m_mesh;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ public:
|
||||||
void updateCameraOffset(v3s16 camera_offset);
|
void updateCameraOffset(v3s16 camera_offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
scene::SMesh *m_mesh;
|
scene::IMesh *m_mesh;
|
||||||
MinimapMapblock *m_minimap_mapblock;
|
MinimapMapblock *m_minimap_mapblock;
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
ITextureSource *m_tsrc;
|
ITextureSource *m_tsrc;
|
||||||
|
@ -177,7 +177,7 @@ struct PreMeshBuffer
|
||||||
{
|
{
|
||||||
TileSpec tile;
|
TileSpec tile;
|
||||||
std::vector<u16> indices;
|
std::vector<u16> indices;
|
||||||
std::vector<video::S3DVertexTangents> vertices;
|
std::vector<video::S3DVertex> vertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshCollector
|
struct MeshCollector
|
||||||
|
@ -218,4 +218,3 @@ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data);
|
||||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data);
|
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,7 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
|
||||||
mesh->addMeshBuffer(buf);
|
mesh->addMeshBuffer(buf);
|
||||||
buf->drop();
|
buf->drop();
|
||||||
scaleMesh(mesh, scale); // also recalculates bounding box
|
scaleMesh(mesh, scale); // also recalculates bounding box
|
||||||
scene::IMesh *newmesh = createForsythOptimizedMesh(mesh);
|
return mesh;
|
||||||
mesh->drop();
|
|
||||||
return newmesh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -436,3 +434,116 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
|
||||||
m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting);
|
m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting);
|
||||||
m_meshnode->setVisible(true);
|
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;
|
||||||
|
}
|
|
@ -77,4 +77,8 @@ private:
|
||||||
core::aabbox3d<f32> m_bounding_box;
|
core::aabbox3d<f32> m_bounding_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item);
|
||||||
|
|
||||||
|
scene::IMesh *getExtrudedMesh(ITextureSource *tsrc,
|
||||||
|
const std::string &imagename);
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue