Convert any inventory item into a mesh, bring back InventoryItem::getImageRay(), some const-correctness fixes

This commit is contained in:
Kahrl 2011-09-19 06:37:24 +02:00
parent 36bcbca9ac
commit 02726f0003
5 changed files with 141 additions and 43 deletions

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" // for g_settings #include "main.h" // for g_settings
#include "map.h" #include "map.h"
#include "player.h" #include "player.h"
#include "tile.h"
#include <cmath> #include <cmath>
const s32 BOBFRAMES = 0x1000000; // must be a power of two const s32 BOBFRAMES = 0x1000000; // must be a power of two
@ -343,17 +344,37 @@ void Camera::updateSettings()
m_wanted_frametime = 1.0 / wanted_fps; m_wanted_frametime = 1.0 / wanted_fps;
} }
void Camera::wield(InventoryItem* item) void Camera::wield(const InventoryItem* item)
{ {
if (item != NULL) if (item != NULL)
{ {
dstream << "wield item: " << item->getName() << std::endl; bool isCube = false;
// Try to make a MaterialItem cube.
if (std::string(item->getName()) == "MaterialItem")
{
// A block-type material
MaterialItem* mat_item = (MaterialItem*) item;
content_t content = mat_item->getMaterial();
if (content_features(content).solidness)
{
m_wieldnode->setCube(content_features(content).tiles);
isCube = true;
}
}
// If that failed, make an extruded sprite.
if (!isCube)
{
m_wieldnode->setSprite(item->getImageRaw()); m_wieldnode->setSprite(item->getImageRaw());
}
m_wieldnode->setVisible(true); m_wieldnode->setVisible(true);
} }
else else
{ {
dstream << "wield item: none" << std::endl; // Bare hands
dstream << "bare hands" << std::endl;
m_wieldnode->setVisible(false); m_wieldnode->setVisible(false);
} }
} }
@ -427,23 +448,37 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
m_is_cube = false; m_is_cube = false;
} }
void ExtrudedSpriteSceneNode::setCube(video::ITexture* texture) void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6])
{ {
if (texture == NULL)
{
m_meshnode->setVisible(false);
return;
}
if (m_cubemesh == NULL) if (m_cubemesh == NULL)
m_cubemesh = SceneManager->getGeometryCreator()->createCubeMesh(v3f(1)); m_cubemesh = createCubeMesh();
m_meshnode->setMesh(m_cubemesh); m_meshnode->setMesh(m_cubemesh);
m_meshnode->setScale(v3f(1)); m_meshnode->setScale(v3f(1));
m_meshnode->getMaterial(0).setTexture(0, texture); for (int i = 0; i < 6; ++i)
m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false); {
m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false); // Get the tile texture and atlas transformation
m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; u32 texture_id = tiles[i].texture.id;
video::ITexture* atlas = NULL;
v2f pos(0,0);
v2f size(1,1);
if (g_texturesource)
{
AtlasPointer ap = g_texturesource->getTexture(texture_id);
atlas = ap.atlas;
pos = ap.pos;
size = ap.size;
}
// Set material flags and texture
video::SMaterial& material = m_meshnode->getMaterial(i);
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
tiles[i].applyMaterialOptions(material);
material.setTexture(0, atlas);
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
}
m_meshnode->setVisible(true); m_meshnode->setVisible(true);
m_is_cube = true; m_is_cube = true;
} }
@ -500,13 +535,13 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
video::S3DVertex vertices[8] = video::S3DVertex vertices[8] =
{ {
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
video::S3DVertex(-0.5,0.5,-0.5, 0,0,-1, c, 0,0), video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
video::S3DVertex(0.5,0.5,-0.5, 0,0,-1, c, 1,0), video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
video::S3DVertex(0.5,-0.5,-0.5, 0,0,-1, c, 1,1), video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
video::S3DVertex(0.5,-0.5,0.5, 0,0,1, c, 1,1), video::S3DVertex(+0.5,-0.5,+0.5, 0,0,+1, c, 1,1),
video::S3DVertex(0.5,0.5,0.5, 0,0,1, c, 1,0), video::S3DVertex(+0.5,+0.5,+0.5, 0,0,+1, c, 1,0),
video::S3DVertex(-0.5,0.5,0.5, 0,0,1, c, 0,0), video::S3DVertex(-0.5,+0.5,+0.5, 0,0,+1, c, 0,0),
video::S3DVertex(-0.5,-0.5,0.5, 0,0,1, c, 0,1), video::S3DVertex(-0.5,-0.5,+0.5, 0,0,+1, c, 0,1),
}; };
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
buf->append(vertices, 8, indices, 12); buf->append(vertices, 8, indices, 12);
@ -557,8 +592,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
{ {
video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty), video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty),
video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty), video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty),
video::S3DVertex(vx2,vy,0.5, 0,-1,0, c, tx2,ty), video::S3DVertex(vx2,vy,+0.5, 0,-1,0, c, tx2,ty),
video::S3DVertex(vx1,vy,0.5, 0,-1,0, c, tx1,ty), video::S3DVertex(vx1,vy,+0.5, 0,-1,0, c, tx1,ty),
}; };
u16 indices[6] = {0,1,2,2,3,0}; u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6); buf->append(vertices, 4, indices, 6);
@ -578,8 +613,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
video::S3DVertex vertices[8] = video::S3DVertex vertices[8] =
{ {
video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty), video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty),
video::S3DVertex(vx1,vy,0.5, 0,1,0, c, tx1,ty), video::S3DVertex(vx1,vy,+0.5, 0,1,0, c, tx1,ty),
video::S3DVertex(vx2,vy,0.5, 0,1,0, c, tx2,ty), video::S3DVertex(vx2,vy,+0.5, 0,1,0, c, tx2,ty),
video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty), video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
}; };
u16 indices[6] = {0,1,2,2,3,0}; u16 indices[6] = {0,1,2,2,3,0};
@ -608,8 +643,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
video::S3DVertex vertices[8] = video::S3DVertex vertices[8] =
{ {
video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1), video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy1,0.5, 1,0,0, c, tx,ty1), video::S3DVertex(vx,vy1,+0.5, 1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy2,0.5, 1,0,0, c, tx,ty2), video::S3DVertex(vx,vy2,+0.5, 1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2), video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2),
}; };
u16 indices[6] = {0,1,2,2,3,0}; u16 indices[6] = {0,1,2,2,3,0};
@ -631,8 +666,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
{ {
video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1), video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2), video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy2,0.5, -1,0,0, c, tx,ty2), video::S3DVertex(vx,vy2,+0.5, -1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy1,0.5, -1,0,0, c, tx,ty1), video::S3DVertex(vx,vy1,+0.5, -1,0,0, c, tx,ty1),
}; };
u16 indices[6] = {0,1,2,2,3,0}; u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6); buf->append(vertices, 4, indices, 6);
@ -643,6 +678,7 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height
// Add to mesh // Add to mesh
scene::SMesh* mesh = new scene::SMesh(); scene::SMesh* mesh = new scene::SMesh();
buf->recalculateBoundingBox();
mesh->addMeshBuffer(buf); mesh->addMeshBuffer(buf);
buf->drop(); buf->drop();
mesh->recalculateBoundingBox(); mesh->recalculateBoundingBox();
@ -690,3 +726,54 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture)
return mesh; return mesh;
} }
scene::IMesh* ExtrudedSpriteSceneNode::createCubeMesh()
{
video::SColor c(255,255,255,255);
video::S3DVertex vertices[24] =
{
// Up
video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
// Down
video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
// Right
video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
// Left
video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
// Back
video::S3DVertex(-0.5,-0.5,+0.5, 0,0,-1, c, 1,1),
video::S3DVertex(+0.5,-0.5,+0.5, 0,0,-1, c, 0,1),
video::S3DVertex(+0.5,+0.5,+0.5, 0,0,-1, c, 0,0),
video::S3DVertex(-0.5,+0.5,+0.5, 0,0,-1, c, 1,0),
// Front
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
};
u16 indices[6] = {0,1,2,2,3,0};
scene::SMesh* mesh = new scene::SMesh();
for (u32 i=0; i<6; ++i)
{
scene::IMeshBuffer* buf = new scene::SMeshBuffer();
buf->append(vertices + 4 * i, 4, indices, 6);
buf->recalculateBoundingBox();
mesh->addMeshBuffer(buf);
buf->drop();
}
mesh->recalculateBoundingBox();
return mesh;
}

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "inventory.h" #include "inventory.h"
#include "tile.h"
#include "utility.h" #include "utility.h"
class LocalPlayer; class LocalPlayer;
@ -117,7 +118,7 @@ public:
void updateSettings(); void updateSettings();
// Replace the wielded item mesh // Replace the wielded item mesh
void wield(InventoryItem* item); void wield(const InventoryItem* item);
// Start or stop digging animation // Start or stop digging animation
void setDigging(bool digging); void setDigging(bool digging);
@ -190,7 +191,7 @@ public:
~ExtrudedSpriteSceneNode(); ~ExtrudedSpriteSceneNode();
void setSprite(video::ITexture* texture); void setSprite(video::ITexture* texture);
void setCube(const TileSpec faces[6]); void setCube(const TileSpec tiles[6]);
f32 getSpriteThickness() const { return m_thickness; } f32 getSpriteThickness() const { return m_thickness; }
void setSpriteThickness(f32 thickness); void setSpriteThickness(f32 thickness);

@ -158,7 +158,7 @@ InventoryItem *MaterialItem::createCookResult() const
*/ */
#ifndef SERVER #ifndef SERVER
video::ITexture * CraftItem::getImage() video::ITexture * CraftItem::getImage() const
{ {
if(g_texturesource == NULL) if(g_texturesource == NULL)
return NULL; return NULL;
@ -224,7 +224,7 @@ bool CraftItem::use(ServerEnvironment *env, Player *player)
TODO: Remove TODO: Remove
*/ */
#ifndef SERVER #ifndef SERVER
video::ITexture * MapBlockObjectItem::getImage() video::ITexture * MapBlockObjectItem::getImage() const
{ {
if(m_inventorystring.substr(0,3) == "Rat") if(m_inventorystring.substr(0,3) == "Rat")
return g_texturesource->getTextureRaw("rat.png"); return g_texturesource->getTextureRaw("rat.png");

@ -54,9 +54,11 @@ public:
virtual InventoryItem* clone() = 0; virtual InventoryItem* clone() = 0;
#ifndef SERVER #ifndef SERVER
// Return the name of the image for this item // Return the name of the image for this item
virtual std::string getBasename() { return ""; } virtual std::string getBasename() const { return ""; }
// Shall return an image of the item (or NULL) // Shall return an image of the item (or NULL)
virtual video::ITexture * getImage() { return NULL; } virtual video::ITexture * getImage() const { return NULL; }
// Shall return an image of the item without embellishments (or NULL)
virtual video::ITexture * getImageRaw() const { return getImage(); }
#endif #endif
// Shall return a text to show in the GUI // Shall return a text to show in the GUI
virtual std::string getText() { return ""; } virtual std::string getText() { return ""; }
@ -151,7 +153,7 @@ public:
return new MaterialItem(m_content, m_count); return new MaterialItem(m_content, m_count);
} }
#ifndef SERVER #ifndef SERVER
video::ITexture * getImage() video::ITexture * getImage() const
{ {
return content_features(m_content).inventory_texture; return content_features(m_content).inventory_texture;
} }
@ -226,7 +228,7 @@ public:
} }
#ifndef SERVER #ifndef SERVER
video::ITexture * getImage(); video::ITexture * getImage() const;
#endif #endif
std::string getText(); std::string getText();
@ -277,7 +279,7 @@ public:
return new CraftItem(m_subname, m_count); return new CraftItem(m_subname, m_count);
} }
#ifndef SERVER #ifndef SERVER
video::ITexture * getImage(); video::ITexture * getImage() const;
#endif #endif
std::string getText() std::string getText()
{ {
@ -354,7 +356,7 @@ public:
return new ToolItem(m_toolname, m_wear); return new ToolItem(m_toolname, m_wear);
} }
#ifndef SERVER #ifndef SERVER
std::string getBasename() { std::string getBasename() const {
if(m_toolname == "WPick") if(m_toolname == "WPick")
return "tool_woodpick.png"; return "tool_woodpick.png";
else if(m_toolname == "STPick") else if(m_toolname == "STPick")
@ -385,7 +387,7 @@ public:
return "cloud.png"; return "cloud.png";
} }
video::ITexture * getImage() video::ITexture * getImage() const
{ {
if(g_texturesource == NULL) if(g_texturesource == NULL)
return NULL; return NULL;
@ -405,6 +407,14 @@ public:
return g_texturesource->getTextureRaw(os.str()); return g_texturesource->getTextureRaw(os.str());
} }
video::ITexture * getImageRaw() const
{
if(g_texturesource == NULL)
return NULL;
return g_texturesource->getTextureRaw(getBasename());
}
#endif #endif
std::string getText() std::string getText()
{ {

@ -304,7 +304,7 @@ struct TileSpec
} }
// Sets everything else except the texture in the material // Sets everything else except the texture in the material
void applyMaterialOptions(video::SMaterial &material) void applyMaterialOptions(video::SMaterial &material) const
{ {
if(alpha != 255 && material_type != MATERIAL_ALPHA_VERTEX) if(alpha != 255 && material_type != MATERIAL_ALPHA_VERTEX)
dstream<<"WARNING: TileSpec: alpha != 255 " dstream<<"WARNING: TileSpec: alpha != 255 "