Convert any inventory item into a mesh, bring back InventoryItem::getImageRay(),...
authorKahrl <kahrl@gmx.net>
Mon, 19 Sep 2011 04:37:24 +0000 (06:37 +0200)
committerKahrl <kahrl@gmx.net>
Mon, 19 Sep 2011 04:37:24 +0000 (06:37 +0200)
src/camera.cpp
src/camera.h
src/inventory.cpp
src/inventory.h
src/tile.h

index aae36c51290315773f9037ae30871db608f0c5f0..e7d506177e851bdf09567b5f296d8a11ce99161f 100644 (file)
@@ -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 <cmath>
 
 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;
+}
index 08c03dd19abefccc2a370242bb61dbbeade9b6b0..ccc224e3cd422362cd09545f380246b13dfa1188 100644 (file)
@@ -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);
index f31e19f77fb545bb9e0378347090c63c720a6e93..a3e35c92cd15234efab6b33c7e9bb99c54a7550b 100644 (file)
@@ -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");
index 4aa68d99ecb2f81313b0b814834160f9e59b403b..3e05015efb6d7b9660be0f187427a49812867e3e 100644 (file)
@@ -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()
        {
index 216d76508ec0347f97a769eb83e5941dc03e6852..5cebb0eaad0cd2dbb9ab0c3d84e82d46d535a31f 100644 (file)
@@ -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 "