From 02726f00031c8ffadf5298b037b595372be202ef Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Sep 2011 06:37:24 +0200 Subject: [PATCH] Convert any inventory item into a mesh, bring back InventoryItem::getImageRay(), some const-correctness fixes --- src/camera.cpp | 149 ++++++++++++++++++++++++++++++++++++---------- src/camera.h | 5 +- src/inventory.cpp | 4 +- src/inventory.h | 24 +++++--- src/tile.h | 2 +- 5 files changed, 141 insertions(+), 43 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index aae36c51..e7d50617 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // for g_settings #include "map.h" #include "player.h" +#include "tile.h" #include const s32 BOBFRAMES = 0x1000000; // must be a power of two @@ -343,17 +344,37 @@ void Camera::updateSettings() m_wanted_frametime = 1.0 / wanted_fps; } -void Camera::wield(InventoryItem* item) +void Camera::wield(const InventoryItem* item) { if (item != NULL) { - dstream << "wield item: " << item->getName() << std::endl; - m_wieldnode->setSprite(item->getImageRaw()); + 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->setVisible(true); } else { - dstream << "wield item: none" << std::endl; + // Bare hands + dstream << "bare hands" << std::endl; m_wieldnode->setVisible(false); } } @@ -427,23 +448,37 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) 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) - m_cubemesh = SceneManager->getGeometryCreator()->createCubeMesh(v3f(1)); + m_cubemesh = createCubeMesh(); m_meshnode->setMesh(m_cubemesh); m_meshnode->setScale(v3f(1)); - m_meshnode->getMaterial(0).setTexture(0, texture); - m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false); - m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false); - m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + for (int i = 0; i < 6; ++i) + { + // Get the tile texture and atlas transformation + 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_is_cube = true; } @@ -500,13 +535,13 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height 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,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,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,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,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), }; u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; 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(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(vx2,vy,+0.5, 0,-1,0, c, tx2,ty), + video::S3DVertex(vx1,vy,+0.5, 0,-1,0, c, tx1,ty), }; u16 indices[6] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); @@ -578,8 +613,8 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height 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(vx2,vy,0.5, 0,1,0, c, tx2,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), }; 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(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,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), }; 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,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,vy2,+0.5, -1,0,0, c, tx,ty2), + video::S3DVertex(vx,vy1,+0.5, -1,0,0, c, tx,ty1), }; u16 indices[6] = {0,1,2,2,3,0}; buf->append(vertices, 4, indices, 6); @@ -643,6 +678,7 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height // Add to mesh scene::SMesh* mesh = new scene::SMesh(); + buf->recalculateBoundingBox(); mesh->addMeshBuffer(buf); buf->drop(); mesh->recalculateBoundingBox(); @@ -690,3 +726,54 @@ scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture) 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; +} diff --git a/src/camera.h b/src/camera.h index 08c03dd1..ccc224e3 100644 --- a/src/camera.h +++ b/src/camera.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include "inventory.h" +#include "tile.h" #include "utility.h" class LocalPlayer; @@ -117,7 +118,7 @@ public: void updateSettings(); // Replace the wielded item mesh - void wield(InventoryItem* item); + void wield(const InventoryItem* item); // Start or stop digging animation void setDigging(bool digging); @@ -190,7 +191,7 @@ public: ~ExtrudedSpriteSceneNode(); void setSprite(video::ITexture* texture); - void setCube(const TileSpec faces[6]); + void setCube(const TileSpec tiles[6]); f32 getSpriteThickness() const { return m_thickness; } void setSpriteThickness(f32 thickness); diff --git a/src/inventory.cpp b/src/inventory.cpp index f31e19f7..a3e35c92 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -158,7 +158,7 @@ InventoryItem *MaterialItem::createCookResult() const */ #ifndef SERVER -video::ITexture * CraftItem::getImage() +video::ITexture * CraftItem::getImage() const { if(g_texturesource == NULL) return NULL; @@ -224,7 +224,7 @@ bool CraftItem::use(ServerEnvironment *env, Player *player) TODO: Remove */ #ifndef SERVER -video::ITexture * MapBlockObjectItem::getImage() +video::ITexture * MapBlockObjectItem::getImage() const { if(m_inventorystring.substr(0,3) == "Rat") return g_texturesource->getTextureRaw("rat.png"); diff --git a/src/inventory.h b/src/inventory.h index 4aa68d99..3e05015e 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -54,9 +54,11 @@ public: virtual InventoryItem* clone() = 0; #ifndef SERVER // 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) - 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 // Shall return a text to show in the GUI virtual std::string getText() { return ""; } @@ -151,7 +153,7 @@ public: return new MaterialItem(m_content, m_count); } #ifndef SERVER - video::ITexture * getImage() + video::ITexture * getImage() const { return content_features(m_content).inventory_texture; } @@ -226,7 +228,7 @@ public: } #ifndef SERVER - video::ITexture * getImage(); + video::ITexture * getImage() const; #endif std::string getText(); @@ -277,7 +279,7 @@ public: return new CraftItem(m_subname, m_count); } #ifndef SERVER - video::ITexture * getImage(); + video::ITexture * getImage() const; #endif std::string getText() { @@ -354,7 +356,7 @@ public: return new ToolItem(m_toolname, m_wear); } #ifndef SERVER - std::string getBasename() { + std::string getBasename() const { if(m_toolname == "WPick") return "tool_woodpick.png"; else if(m_toolname == "STPick") @@ -385,7 +387,7 @@ public: return "cloud.png"; } - video::ITexture * getImage() + video::ITexture * getImage() const { if(g_texturesource == NULL) return NULL; @@ -405,6 +407,14 @@ public: return g_texturesource->getTextureRaw(os.str()); } + + video::ITexture * getImageRaw() const + { + if(g_texturesource == NULL) + return NULL; + + return g_texturesource->getTextureRaw(getBasename()); + } #endif std::string getText() { diff --git a/src/tile.h b/src/tile.h index 216d7650..5cebb0ea 100644 --- a/src/tile.h +++ b/src/tile.h @@ -304,7 +304,7 @@ struct TileSpec } // 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) dstream<<"WARNING: TileSpec: alpha != 255 " -- 2.30.2