inventorycube: use all three specified textures; also moved mesh creation / modificat...
authorKahrl <kahrl@gmx.net>
Sat, 3 Dec 2011 07:40:32 +0000 (08:40 +0100)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 3 Dec 2011 09:47:37 +0000 (11:47 +0200)
12 files changed:
data/builtin.lua
data/mods/default/init.lua
data/mods/experimental/init.lua
src/CMakeLists.txt
src/camera.cpp
src/camera.h
src/content_cao.cpp
src/mesh.cpp [new file with mode: 0644]
src/mesh.h [new file with mode: 0644]
src/tile.cpp
src/utility.cpp
src/utility.h

index a9412a97d0a78a432ada4406f9319abf68df8129..5d6936d618f0ea5d6d676509c97ee1b12ff7d50f 100644 (file)
@@ -303,6 +303,19 @@ function test_stackstring()
 end
 test_stackstring()
 
+--
+-- nodeitem helpers
+--
+
+minetest.inventorycube = function(img1, img2, img3)
+       img2 = img2 or img1
+       img3 = img3 or img1
+       return "[inventorycube"
+                       .. "{" .. img1:gsub("%^", "&")
+                       .. "{" .. img2:gsub("%^", "&")
+                       .. "{" .. img3:gsub("%^", "&")
+end
+
 --
 -- craftitem helpers
 --
index 3baafff63a55097e3478f6737a15371c92ca0331..2e07b54121ceea5b147cbd8859d9a332a00c7627 100644 (file)
@@ -824,20 +824,11 @@ function digprop_glasslike(toughness)
        }
 end
 
-function inventorycube(img1, img2, img3)
-       img2 = img2 or img1
-       img3 = img3 or img1
-       return "[inventorycube"
-                       .. "{" .. img1:gsub("%^", "&")
-                       .. "{" .. img2:gsub("%^", "&")
-                       .. "{" .. img3:gsub("%^", "&")
-end
-
 -- Legacy nodes
 
 minetest.register_node(":stone", {
        tile_images = {"stone.png"},
-       inventory_image = inventorycube("stone.png"),
+       inventory_image = minetest.inventorycube("stone.png"),
        paramtype = "mineral",
        is_ground_content = true,
        often_contains_mineral = true, -- Texture atlas hint
@@ -847,7 +838,7 @@ minetest.register_node(":stone", {
 
 minetest.register_node(":dirt_with_grass", {
        tile_images = {"grass.png", "mud.png", "mud.png^grass_side.png"},
-       inventory_image = inventorycube("mud.png^grass_side.png"),
+       inventory_image = minetest.inventorycube("mud.png^grass_side.png"),
        is_ground_content = true,
        material = digprop_dirtlike(1.0),
        dug_item = 'node "dirt" 1',
@@ -863,14 +854,14 @@ minetest.register_node(":dirt_with_grass_footsteps", {
 
 minetest.register_node(":dirt", {
        tile_images = {"mud.png"},
-       inventory_image = inventorycube("mud.png"),
+       inventory_image = minetest.inventorycube("mud.png"),
        is_ground_content = true,
        material = digprop_dirtlike(1.0),
 })
 
 minetest.register_node(":sand", {
        tile_images = {"sand.png"},
-       inventory_image = inventorycube("sand.png"),
+       inventory_image = minetest.inventorycube("sand.png"),
        is_ground_content = true,
        material = digprop_dirtlike(1.0),
        cookresult_item = 'node "glass" 1',
@@ -878,14 +869,14 @@ minetest.register_node(":sand", {
 
 minetest.register_node(":gravel", {
        tile_images = {"gravel.png"},
-       inventory_image = inventorycube("gravel.png"),
+       inventory_image = minetest.inventorycube("gravel.png"),
        is_ground_content = true,
        material = digprop_gravellike(1.0),
 })
 
 minetest.register_node(":sandstone", {
        tile_images = {"sandstone.png"},
-       inventory_image = inventorycube("sandstone.png"),
+       inventory_image = minetest.inventorycube("sandstone.png"),
        is_ground_content = true,
        material = digprop_dirtlike(1.0),  -- FIXME should this be stonelike?
        dug_item = 'node "sand" 1',  -- FIXME is this intentional?
@@ -893,7 +884,7 @@ minetest.register_node(":sandstone", {
 
 minetest.register_node(":clay", {
        tile_images = {"clay.png"},
-       inventory_image = inventorycube("clay.png"),
+       inventory_image = minetest.inventorycube("clay.png"),
        is_ground_content = true,
        material = digprop_dirtlike(1.0),
        dug_item = 'craft "lump_of_clay" 4',
@@ -901,7 +892,7 @@ minetest.register_node(":clay", {
 
 minetest.register_node(":brick", {
        tile_images = {"brick.png"},
-       inventory_image = inventorycube("brick.png"),
+       inventory_image = minetest.inventorycube("brick.png"),
        is_ground_content = true,
        material = digprop_stonelike(1.0),
        dug_item = 'craft "clay_brick" 4',
@@ -909,7 +900,7 @@ minetest.register_node(":brick", {
 
 minetest.register_node(":tree", {
        tile_images = {"tree_top.png", "tree_top.png", "tree.png"},
-       inventory_image = inventorycube("tree_top.png", "tree.png", "tree.png"),
+       inventory_image = minetest.inventorycube("tree_top.png", "tree.png", "tree.png"),
        is_ground_content = true,
        material = digprop_woodlike(1.0),
        cookresult_item = 'craft "lump_of_coal" 1',
@@ -918,7 +909,7 @@ minetest.register_node(":tree", {
 
 minetest.register_node(":jungletree", {
        tile_images = {"jungletree_top.png", "jungletree_top.png", "jungletree.png"},
-       inventory_image = inventorycube("jungletree_top.png", "jungletree.png", "jungletree.png"),
+       inventory_image = minetest.inventorycube("jungletree_top.png", "jungletree.png", "jungletree.png"),
        is_ground_content = true,
        material = digprop_woodlike(1.0),
        cookresult_item = 'craft "lump_of_coal" 1',
@@ -941,7 +932,7 @@ minetest.register_node(":leaves", {
        drawtype = "allfaces_optional",
        visual_scale = 1.3,
        tile_images = {"leaves.png"},
-       inventory_image = "leaves.png",
+       inventory_image = minetest.inventorycube("leaves.png"),
        light_propagates = true,
        paramtype = "light",
        material = digprop_leaveslike(1.0),
@@ -952,7 +943,7 @@ minetest.register_node(":leaves", {
 
 minetest.register_node(":cactus", {
        tile_images = {"cactus_top.png", "cactus_top.png", "cactus_side.png"},
-       inventory_image = inventorycube("cactus_top.png", "cactus_side.png", "cactus_side.png"),
+       inventory_image = minetest.inventorycube("cactus_top.png", "cactus_side.png", "cactus_side.png"),
        is_ground_content = true,
        material = digprop_woodlike(0.75),
        furnace_burntime = 15,
@@ -972,9 +963,7 @@ minetest.register_node(":papyrus", {
 
 minetest.register_node(":bookshelf", {
        tile_images = {"wood.png", "wood.png", "bookshelf.png"},
-       -- FIXME: inventorycube only cares for the first texture
-       --inventory_image = inventorycube("wood.png", "bookshelf.png", "bookshelf.png")
-       inventory_image = inventorycube("bookshelf.png"),
+       inventory_image = minetest.inventorycube("wood.png", "bookshelf.png", "bookshelf.png"),
        is_ground_content = true,
        material = digprop_woodlike(0.75),
        furnace_burntime = 30,
@@ -983,7 +972,7 @@ minetest.register_node(":bookshelf", {
 minetest.register_node(":glass", {
        drawtype = "glasslike",
        tile_images = {"glass.png"},
-       inventory_image = inventorycube("glass.png"),
+       inventory_image = minetest.inventorycube("glass.png"),
        light_propagates = true,
        paramtype = "light",
        sunlight_propagates = true,
@@ -1050,7 +1039,7 @@ minetest.register_node(":coalstone", {
 
 minetest.register_node(":wood", {
        tile_images = {"wood.png"},
-       inventory_image = inventorycube("wood.png"),
+       inventory_image = minetest.inventorycube("wood.png"),
        is_ground_content = true,
        furnace_burntime = 7,
        material = digprop_woodlike(0.75),
@@ -1058,7 +1047,7 @@ minetest.register_node(":wood", {
 
 minetest.register_node(":mese", {
        tile_images = {"mese.png"},
-       inventory_image = inventorycube("mese.png"),
+       inventory_image = minetest.inventorycube("mese.png"),
        is_ground_content = true,
        furnace_burntime = 30,
        material = digprop_stonelike(0.5),
@@ -1066,7 +1055,7 @@ minetest.register_node(":mese", {
 
 minetest.register_node(":cloud", {
        tile_images = {"cloud.png"},
-       inventory_image = inventorycube("cloud.png"),
+       inventory_image = minetest.inventorycube("cloud.png"),
        is_ground_content = true,
 })
 
@@ -1074,7 +1063,7 @@ minetest.register_node(":water_flowing", {
        drawtype = "flowingliquid",
        tile_images = {"water.png"},
        alpha = WATER_ALPHA,
-       inventory_image = inventorycube("water.png"),
+       inventory_image = minetest.inventorycube("water.png"),
        paramtype = "light",
        light_propagates = true,
        walkable = false,
@@ -1096,7 +1085,7 @@ minetest.register_node(":water_source", {
        drawtype = "liquid",
        tile_images = {"water.png"},
        alpha = WATER_ALPHA,
-       inventory_image = inventorycube("water.png"),
+       inventory_image = minetest.inventorycube("water.png"),
        paramtype = "light",
        light_propagates = true,
        walkable = false,
@@ -1117,7 +1106,7 @@ minetest.register_node(":water_source", {
 minetest.register_node(":lava_flowing", {
        drawtype = "flowingliquid",
        tile_images = {"lava.png"},
-       inventory_image = inventorycube("lava.png"),
+       inventory_image = minetest.inventorycube("lava.png"),
        paramtype = "light",
        light_propagates = false,
        light_source = LIGHT_MAX - 1,
@@ -1140,7 +1129,7 @@ minetest.register_node(":lava_flowing", {
 minetest.register_node(":lava_source", {
        drawtype = "liquid",
        tile_images = {"lava.png"},
-       inventory_image = inventorycube("lava.png"),
+       inventory_image = minetest.inventorycube("lava.png"),
        paramtype = "light",
        light_propagates = false,
        light_source = LIGHT_MAX - 1,
@@ -1204,8 +1193,7 @@ minetest.register_node(":sign_wall", {
 minetest.register_node(":chest", {
        tile_images = {"chest_top.png", "chest_top.png", "chest_side.png",
                "chest_side.png", "chest_side.png", "chest_front.png"},
-       inventory_image = "chest_top.png",
-       --inventory_image = inventorycube("chest_top.png", "chest_side.png", "chest_front.png"),
+       inventory_image = minetest.inventorycube("chest_top.png", "chest_front.png", "chest_side.png"),
        paramtype = "facedir_simple",
        metadata_name = "chest",
        material = digprop_woodlike(1.0),
@@ -1215,7 +1203,7 @@ minetest.register_node(":chest", {
 minetest.register_node(":locked_chest", {
        tile_images = {"chest_top.png", "chest_top.png", "chest_side.png",
                "chest_side.png", "chest_side.png", "chest_lock.png"},
-       inventory_image = "chest_lock.png",
+       inventory_image = minetest.inventorycube("chest_top.png", "chest_lock.png", "chest_side.png"),
        paramtype = "facedir_simple",
        metadata_name = "locked_chest",
        material = digprop_woodlike(1.0),
@@ -1225,7 +1213,7 @@ minetest.register_node(":locked_chest", {
 minetest.register_node(":furnace", {
        tile_images = {"furnace_side.png", "furnace_side.png", "furnace_side.png",
                "furnace_side.png", "furnace_side.png", "furnace_front.png"},
-       inventory_image = "furnace_front.png",
+       inventory_image = minetest.inventorycube("furnace_side.png", "furnace_front.png", "furnace_side.png"),
        paramtype = "facedir_simple",
        metadata_name = "furnace",
        material = digprop_stonelike(3.0),
@@ -1233,7 +1221,7 @@ minetest.register_node(":furnace", {
 
 minetest.register_node(":cobble", {
        tile_images = {"cobble.png"},
-       inventory_image = inventorycube("cobble.png"),
+       inventory_image = minetest.inventorycube("cobble.png"),
        is_ground_content = true,
        cookresult_item = 'node "stone" 1',
        material = digprop_stonelike(0.9),
@@ -1241,14 +1229,14 @@ minetest.register_node(":cobble", {
 
 minetest.register_node(":mossycobble", {
        tile_images = {"mossycobble.png"},
-       inventory_image = inventorycube("mossycobble.png"),
+       inventory_image = minetest.inventorycube("mossycobble.png"),
        is_ground_content = true,
        material = digprop_stonelike(0.8),
 })
 
 minetest.register_node(":steelblock", {
        tile_images = {"steel_block.png"},
-       inventory_image = inventorycube("steel_block.png"),
+       inventory_image = minetest.inventorycube("steel_block.png"),
        is_ground_content = true,
        material = digprop_stonelike(5.0),
 })
index 326fe1b754094ad23974e17b9429890bb0b4984a..b63bf76fc128742127058a71366de2279b6d8b1c 100644 (file)
@@ -8,7 +8,7 @@ minetest.register_node("experimental:luafurnace", {
        tile_images = {"lava.png", "furnace_side.png", "furnace_side.png",
                "furnace_side.png", "furnace_side.png", "furnace_front.png"},
        --inventory_image = "furnace_front.png",
-       inventory_image = inventorycube("furnace_front.png"),
+       inventory_image = minetest.inventorycube("furnace_front.png"),
        paramtype = "facedir_simple",
        metadata_name = "generic",
        material = digprop_stonelike(3.0),
@@ -134,7 +134,8 @@ minetest.register_craft({
 
 minetest.register_node("experimental:somenode", {
        tile_images = {"lava.png", "mese.png", "stone.png", "grass.png", "cobble.png", "tree_top.png"},
-       inventory_image = "treeprop.png",
+       inventory_image = minetest.inventorycube("lava.png", "mese.png", "stone.png"),
+       --inventory_image = "treeprop.png",
        material = {
                diggability = "normal",
                weight = 0,
index a0e063465769a638abc283fafee0f077fcd1bada..61a0b1be8a9b3ca956c7cd2bcd7fa44969d63a01 100644 (file)
@@ -161,6 +161,7 @@ set(minetest_SRCS
        MyBillboardSceneNode.cpp
        content_mapblock.cpp
        content_cao.cpp
+       mesh.cpp
        mapblock_mesh.cpp
        farmesh.cpp
        keycode.cpp
index 8f421e6916852ade67b21f6a69a60d86939cb8dd..c0e1714681122dd01ff31bc48dd6f03734298f23 100644 (file)
@@ -22,21 +22,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client.h"
 #include "main.h" // for g_settings
 #include "map.h"
+#include "mesh.h"
 #include "player.h"
 #include "tile.h"
 #include <cmath>
-#include <SAnimatedMesh.h>
 #include "settings.h"
 #include "nodedef.h" // For wield visualization
 
-// In Irrlicht 1.8 the signature of ITexture::lock was changed from
-// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
-#define MY_ETLM_READ_ONLY true
-#else
-#define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
-#endif
-
 Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
        m_smgr(smgr),
        m_playernode(NULL),
@@ -480,7 +472,6 @@ void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
                        case NDT_ALLFACES:
                        case NDT_ALLFACES_OPTIONAL:
                                m_wieldnode->setCube(ndef->get(content).tiles);
-                               m_wieldnode->setScale(v3f(30));
                                isCube = true;
                                break;
                        default:
@@ -492,7 +483,6 @@ void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
                if (!isCube)
                {
                        m_wieldnode->setSprite(item->getImageRaw());
-                       m_wieldnode->setScale(v3f(40));
                }
 
                m_wieldnode->setVisible(true);
@@ -501,7 +491,6 @@ void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
        {
                // Bare hands
                m_wieldnode->setSprite(gamedef->tsrc()->getTextureRaw("wieldhand.png"));
-               m_wieldnode->setScale(v3f(40));
                m_wieldnode->setVisible(true);
        }
 }
@@ -536,7 +525,6 @@ ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode(
        ISceneNode(parent, mgr, id, position, rotation, scale)
 {
        m_meshnode = mgr->addMeshSceneNode(NULL, this, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true);
-       m_thickness = 0.1;
        m_cubemesh = NULL;
        m_is_cube = false;
        m_light = LIGHT_MAX;
@@ -551,6 +539,8 @@ ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode()
 
 void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
 {
+       const v3f sprite_scale(40.0, 40.0, 4.0); // width, height, thickness
+
        if (texture == NULL)
        {
                m_meshnode->setVisible(false);
@@ -568,7 +558,9 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
        else
        {
                // Texture was not yet extruded, do it now and save in cache
-               mesh = extrude(texture);
+               mesh = createExtrudedMesh(texture,
+                               SceneManager->getVideoDriver(),
+                               sprite_scale);
                if (mesh == NULL)
                {
                        dstream << "Warning: failed to extrude sprite" << std::endl;
@@ -580,7 +572,6 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
                mesh->drop();
        }
 
-       m_meshnode->setScale(v3f(1, 1, m_thickness));
        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);
@@ -592,11 +583,14 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
 
 void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6])
 {
+       const v3f cube_scale(30.0, 30.0, 30.0);
+
        if (m_cubemesh == NULL)
-               m_cubemesh = createCubeMesh();
+       {
+               m_cubemesh = createCubeMesh(cube_scale);
+       }
 
        m_meshnode->setMesh(m_cubemesh);
-       m_meshnode->setScale(v3f(1));
        for (int i = 0; i < 6; ++i)
        {
                // Get the tile texture and atlas transformation
@@ -626,7 +620,7 @@ void ExtrudedSpriteSceneNode::updateLight(u8 light)
        // Set brightness one lower than incoming light
        diminish_light(li);
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_meshnode->getMesh(), color);
+       setMeshColor(m_meshnode->getMesh(), color);
 }
 
 void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture)
@@ -637,13 +631,6 @@ void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture)
                cache->removeMesh(mesh);
 }
 
-void ExtrudedSpriteSceneNode::setSpriteThickness(f32 thickness)
-{
-       m_thickness = thickness;
-       if (!m_is_cube)
-               m_meshnode->setScale(v3f(1, 1, thickness));
-}
-
 const core::aabbox3d<f32>& ExtrudedSpriteSceneNode::getBoundingBox() const
 {
        return m_meshnode->getBoundingBox();
@@ -667,259 +654,3 @@ io::path ExtrudedSpriteSceneNode::getExtrudedName(video::ITexture* texture)
        path.append("/[extruded]");
        return path;
 }
-
-scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height, u8* data)
-{
-       const s32 argb_wstep = 4 * width;
-       const s32 alpha_threshold = 1;
-
-       scene::IMeshBuffer* buf = new scene::SMeshBuffer();
-       video::SColor c(255,255,255,255);
-
-       // Front and back
-       {
-               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),
-               };
-               u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
-               buf->append(vertices, 8, indices, 12);
-       }
-
-       // "Interior"
-       // (add faces where a solid pixel is next to a transparent one)
-       u8* solidity = new u8[(width+2) * (height+2)];
-       u32 wstep = width + 2;
-       for (u32 y = 0; y < height + 2; ++y)
-       {
-               u8* scanline = solidity + y * wstep;
-               if (y == 0 || y == height + 1)
-               {
-                       for (u32 x = 0; x < width + 2; ++x)
-                               scanline[x] = 0;
-               }
-               else
-               {
-                       scanline[0] = 0;
-                       u8* argb_scanline = data + (y - 1) * argb_wstep;
-                       for (u32 x = 0; x < width; ++x)
-                               scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold);
-                       scanline[width + 1] = 0;
-               }
-       }
-
-       // without this, there would be occasional "holes" in the mesh
-       f32 eps = 0.01;
-
-       for (u32 y = 0; y <= height; ++y)
-       {
-               u8* scanline = solidity + y * wstep + 1;
-               for (u32 x = 0; x <= width; ++x)
-               {
-                       if (scanline[x] && !scanline[x + wstep])
-                       {
-                               u32 xx = x + 1;
-                               while (scanline[xx] && !scanline[xx + wstep])
-                                       ++xx;
-                               f32 vx1 = (x - eps) / (f32) width - 0.5;
-                               f32 vx2 = (xx + eps) / (f32) width - 0.5;
-                               f32 vy = 0.5 - (y - eps) / (f32) height;
-                               f32 tx1 = x / (f32) width;
-                               f32 tx2 = xx / (f32) width;
-                               f32 ty = (y - 0.5) / (f32) height;
-                               video::S3DVertex vertices[8] =
-                               {
-                                       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),
-                               };
-                               u16 indices[6] = {0,1,2,2,3,0};
-                               buf->append(vertices, 4, indices, 6);
-                               x = xx - 1;
-                       }
-                       if (!scanline[x] && scanline[x + wstep])
-                       {
-                               u32 xx = x + 1;
-                               while (!scanline[xx] && scanline[xx + wstep])
-                                       ++xx;
-                               f32 vx1 = (x - eps) / (f32) width - 0.5;
-                               f32 vx2 = (xx + eps) / (f32) width - 0.5;
-                               f32 vy = 0.5 - (y + eps) / (f32) height;
-                               f32 tx1 = x / (f32) width;
-                               f32 tx2 = xx / (f32) width;
-                               f32 ty = (y + 0.5) / (f32) 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(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
-                               };
-                               u16 indices[6] = {0,1,2,2,3,0};
-                               buf->append(vertices, 4, indices, 6);
-                               x = xx - 1;
-                       }
-               }
-       }
-
-       for (u32 x = 0; x <= width; ++x)
-       {
-               u8* scancol = solidity + x + wstep;
-               for (u32 y = 0; y <= height; ++y)
-               {
-                       if (scancol[y * wstep] && !scancol[y * wstep + 1])
-                       {
-                               u32 yy = y + 1;
-                               while (scancol[yy * wstep] && !scancol[yy * wstep + 1])
-                                       ++yy;
-                               f32 vx = (x - eps) / (f32) width - 0.5;
-                               f32 vy1 = 0.5 - (y - eps) / (f32) height;
-                               f32 vy2 = 0.5 - (yy + eps) / (f32) height;
-                               f32 tx = (x - 0.5) / (f32) width;
-                               f32 ty1 = y / (f32) height;
-                               f32 ty2 = yy / (f32) 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,vy2,-0.5, 1,0,0, c, tx,ty2),
-                               };
-                               u16 indices[6] = {0,1,2,2,3,0};
-                               buf->append(vertices, 4, indices, 6);
-                               y = yy - 1;
-                       }
-                       if (!scancol[y * wstep] && scancol[y * wstep + 1])
-                       {
-                               u32 yy = y + 1;
-                               while (!scancol[yy * wstep] && scancol[yy * wstep + 1])
-                                       ++yy;
-                               f32 vx = (x + eps) / (f32) width - 0.5;
-                               f32 vy1 = 0.5 - (y - eps) / (f32) height;
-                               f32 vy2 = 0.5 - (yy + eps) / (f32) height;
-                               f32 tx = (x + 0.5) / (f32) width;
-                               f32 ty1 = y / (f32) height;
-                               f32 ty2 = yy / (f32) height;
-                               video::S3DVertex vertices[8] =
-                               {
-                                       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),
-                               };
-                               u16 indices[6] = {0,1,2,2,3,0};
-                               buf->append(vertices, 4, indices, 6);
-                               y = yy - 1;
-                       }
-               }
-       }
-
-       // Add to mesh
-       scene::SMesh* mesh = new scene::SMesh();
-       buf->recalculateBoundingBox();
-       mesh->addMeshBuffer(buf);
-       buf->drop();
-       mesh->recalculateBoundingBox();
-       scene::SAnimatedMesh* anim_mesh = new scene::SAnimatedMesh(mesh);
-       mesh->drop();
-       return anim_mesh;
-}
-
-scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture)
-{
-       scene::IAnimatedMesh* mesh = NULL;
-       core::dimension2d<u32> size = texture->getSize();
-       video::ECOLOR_FORMAT format = texture->getColorFormat();
-       if (format == video::ECF_A8R8G8B8)
-       {
-               // Texture is in the correct color format, we can pass it
-               // to extrudeARGB right away.
-               void* data = texture->lock(MY_ETLM_READ_ONLY);
-               if (data == NULL)
-                       return NULL;
-               mesh = extrudeARGB(size.Width, size.Height, (u8*) data);
-               texture->unlock();
-       }
-       else
-       {
-               video::IVideoDriver* driver = SceneManager->getVideoDriver();
-
-               video::IImage* img1 = driver->createImageFromData(format, size, texture->lock(MY_ETLM_READ_ONLY));
-               if (img1 == NULL)
-                       return NULL;
-
-               // img1 is in the texture's color format, convert to 8-bit ARGB
-               video::IImage* img2 = driver->createImage(video::ECF_A8R8G8B8, size);
-               if (img2 != NULL)
-               {
-                       img1->copyTo(img2);
-                       img1->drop();
-
-                       mesh = extrudeARGB(size.Width, size.Height, (u8*) img2->lock());
-                       img2->unlock();
-                       img2->drop();
-               }
-               img1->drop();
-       }
-       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 973ae3f31006f76704d3f535ad2b107fc0afef13..d5789d807191527f533b69f9f3e4d6b72492751d 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 "mesh.h"
 #include "tile.h"
 #include "utility.h"
 #include <ICameraSceneNode.h>
@@ -206,9 +207,6 @@ public:
        void setSprite(video::ITexture* texture);
        void setCube(const TileSpec tiles[6]);
 
-       f32 getSpriteThickness() const { return m_thickness; }
-       void setSpriteThickness(f32 thickness);
-
        void updateLight(u8 light);
 
        void removeSpriteFromCache(video::ITexture* texture);
@@ -219,16 +217,11 @@ public:
 
 private:
        scene::IMeshSceneNode* m_meshnode;
-       f32 m_thickness;
        scene::IMesh* m_cubemesh;
        bool m_is_cube;
        u8 m_light;
 
-       // internal extrusion helper methods
        io::path getExtrudedName(video::ITexture* texture);
-       scene::IAnimatedMesh* extrudeARGB(u32 width, u32 height, u8* data);
-       scene::IAnimatedMesh* extrude(video::ITexture* texture);
-       scene::IMesh* createCubeMesh();
 };
 
 #endif
index b9dc91e63c6a4e2e652d92764872ba6933e9681a..da68004ce20159f4735bce442ed49df948ca1e77 100644 (file)
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gamedef.h"
 #include "clientobject.h"
 #include "content_object.h"
+#include "mesh.h"
 #include "utility.h" // For IntervalLimiter
 class Settings;
 #include "MyBillboardSceneNode.h"
@@ -630,7 +631,7 @@ void ItemCAO::updateLight(u8 light_at_pos)
 
        u8 li = decode_light(light_at_pos);
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_node->getMesh(), color);
+       setMeshColor(m_node->getMesh(), color);
 }
 
 v3s16 ItemCAO::getLightPosition()
@@ -778,7 +779,7 @@ void RatCAO::updateLight(u8 light_at_pos)
 
        u8 li = decode_light(light_at_pos);
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_node->getMesh(), color);
+       setMeshColor(m_node->getMesh(), color);
 }
 
 v3s16 RatCAO::getLightPosition()
@@ -934,7 +935,7 @@ void Oerkki1CAO::updateLight(u8 light_at_pos)
 
        u8 li = decode_light(light_at_pos);
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_node->getMesh(), color);
+       setMeshColor(m_node->getMesh(), color);
 }
 
 v3s16 Oerkki1CAO::getLightPosition()
@@ -1165,7 +1166,7 @@ void FireflyCAO::updateLight(u8 light_at_pos)
 
        u8 li = 255;
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_node->getMesh(), color);
+       setMeshColor(m_node->getMesh(), color);
 }
 
 v3s16 FireflyCAO::getLightPosition()
@@ -1866,7 +1867,7 @@ public:
                u8 li = decode_light(light_at_pos);
                video::SColor color(255,li,li,li);
                if(m_meshnode){
-                       setMeshVerticesColor(m_meshnode->getMesh(), color);
+                       setMeshColor(m_meshnode->getMesh(), color);
                        m_meshnode->setVisible(true);
                }
                if(m_spritenode){
@@ -2250,7 +2251,7 @@ public:
 
                u8 li = decode_light(light_at_pos);
                video::SColor color(255,li,li,li);
-               setMeshVerticesColor(m_node->getMesh(), color);
+               setMeshColor(m_node->getMesh(), color);
        }
 
        v3s16 getLightPosition()
diff --git a/src/mesh.cpp b/src/mesh.cpp
new file mode 100644 (file)
index 0000000..1d347a0
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "mesh.h"
+#include <IAnimatedMesh.h>
+#include <SAnimatedMesh.h>
+
+// In Irrlicht 1.8 the signature of ITexture::lock was changed from
+// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 7
+#define MY_ETLM_READ_ONLY true
+#else
+#define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
+#endif
+
+scene::IAnimatedMesh* createCubeMesh(v3f scale)
+{
+       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);
+               mesh->addMeshBuffer(buf);
+               buf->drop();
+       }
+       scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh);
+       mesh->drop();
+       scaleMesh(anim_mesh, scale);  // also recalculates bounding box
+       return anim_mesh;
+}
+
+static scene::IAnimatedMesh* extrudeARGB(u32 twidth, u32 theight, u8 *data)
+{
+       const s32 argb_wstep = 4 * twidth;
+       const s32 alpha_threshold = 1;
+
+       scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+       video::SColor c(255,255,255,255);
+
+       // Front and back
+       {
+               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),
+               };
+               u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
+               buf->append(vertices, 8, indices, 12);
+       }
+
+       // "Interior"
+       // (add faces where a solid pixel is next to a transparent one)
+       u8 *solidity = new u8[(twidth+2) * (theight+2)];
+       u32 wstep = twidth + 2;
+       for (u32 y = 0; y < theight + 2; ++y)
+       {
+               u8 *scanline = solidity + y * wstep;
+               if (y == 0 || y == theight + 1)
+               {
+                       for (u32 x = 0; x < twidth + 2; ++x)
+                               scanline[x] = 0;
+               }
+               else
+               {
+                       scanline[0] = 0;
+                       u8 *argb_scanline = data + (y - 1) * argb_wstep;
+                       for (u32 x = 0; x < twidth; ++x)
+                               scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold);
+                       scanline[twidth + 1] = 0;
+               }
+       }
+
+       // without this, there would be occasional "holes" in the mesh
+       f32 eps = 0.01;
+
+       for (u32 y = 0; y <= theight; ++y)
+       {
+               u8 *scanline = solidity + y * wstep + 1;
+               for (u32 x = 0; x <= twidth; ++x)
+               {
+                       if (scanline[x] && !scanline[x + wstep])
+                       {
+                               u32 xx = x + 1;
+                               while (scanline[xx] && !scanline[xx + wstep])
+                                       ++xx;
+                               f32 vx1 = (x - eps) / (f32) twidth - 0.5;
+                               f32 vx2 = (xx + eps) / (f32) twidth - 0.5;
+                               f32 vy = 0.5 - (y - eps) / (f32) theight;
+                               f32 tx1 = x / (f32) twidth;
+                               f32 tx2 = xx / (f32) twidth;
+                               f32 ty = (y - 0.5) / (f32) theight;
+                               video::S3DVertex vertices[8] =
+                               {
+                                       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),
+                               };
+                               u16 indices[6] = {0,1,2,2,3,0};
+                               buf->append(vertices, 4, indices, 6);
+                               x = xx - 1;
+                       }
+                       if (!scanline[x] && scanline[x + wstep])
+                       {
+                               u32 xx = x + 1;
+                               while (!scanline[xx] && scanline[xx + wstep])
+                                       ++xx;
+                               f32 vx1 = (x - eps) / (f32) twidth - 0.5;
+                               f32 vx2 = (xx + eps) / (f32) twidth - 0.5;
+                               f32 vy = 0.5 - (y + eps) / (f32) theight;
+                               f32 tx1 = x / (f32) twidth;
+                               f32 tx2 = xx / (f32) twidth;
+                               f32 ty = (y + 0.5) / (f32) theight;
+                               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(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
+                               };
+                               u16 indices[6] = {0,1,2,2,3,0};
+                               buf->append(vertices, 4, indices, 6);
+                               x = xx - 1;
+                       }
+               }
+       }
+
+       for (u32 x = 0; x <= twidth; ++x)
+       {
+               u8 *scancol = solidity + x + wstep;
+               for (u32 y = 0; y <= theight; ++y)
+               {
+                       if (scancol[y * wstep] && !scancol[y * wstep + 1])
+                       {
+                               u32 yy = y + 1;
+                               while (scancol[yy * wstep] && !scancol[yy * wstep + 1])
+                                       ++yy;
+                               f32 vx = (x - eps) / (f32) twidth - 0.5;
+                               f32 vy1 = 0.5 - (y - eps) / (f32) theight;
+                               f32 vy2 = 0.5 - (yy + eps) / (f32) theight;
+                               f32 tx = (x - 0.5) / (f32) twidth;
+                               f32 ty1 = y / (f32) theight;
+                               f32 ty2 = yy / (f32) theight;
+                               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,vy2,-0.5, 1,0,0, c, tx,ty2),
+                               };
+                               u16 indices[6] = {0,1,2,2,3,0};
+                               buf->append(vertices, 4, indices, 6);
+                               y = yy - 1;
+                       }
+                       if (!scancol[y * wstep] && scancol[y * wstep + 1])
+                       {
+                               u32 yy = y + 1;
+                               while (!scancol[yy * wstep] && scancol[yy * wstep + 1])
+                                       ++yy;
+                               f32 vx = (x + eps) / (f32) twidth - 0.5;
+                               f32 vy1 = 0.5 - (y - eps) / (f32) theight;
+                               f32 vy2 = 0.5 - (yy + eps) / (f32) theight;
+                               f32 tx = (x + 0.5) / (f32) twidth;
+                               f32 ty1 = y / (f32) theight;
+                               f32 ty2 = yy / (f32) theight;
+                               video::S3DVertex vertices[8] =
+                               {
+                                       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),
+                               };
+                               u16 indices[6] = {0,1,2,2,3,0};
+                               buf->append(vertices, 4, indices, 6);
+                               y = yy - 1;
+                       }
+               }
+       }
+
+       // Add to mesh
+       scene::SMesh *mesh = new scene::SMesh();
+       mesh->addMeshBuffer(buf);
+       buf->drop();
+       scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh);
+       mesh->drop();
+       return anim_mesh;
+}
+
+scene::IAnimatedMesh* createExtrudedMesh(video::ITexture *texture,
+               video::IVideoDriver *driver, v3f scale)
+{
+       scene::IAnimatedMesh *mesh = NULL;
+       core::dimension2d<u32> size = texture->getSize();
+       video::ECOLOR_FORMAT format = texture->getColorFormat();
+       if (format == video::ECF_A8R8G8B8)
+       {
+               // Texture is in the correct color format, we can pass it
+               // to extrudeARGB right away.
+               void *data = texture->lock(MY_ETLM_READ_ONLY);
+               if (data == NULL)
+                       return NULL;
+               mesh = extrudeARGB(size.Width, size.Height, (u8*) data);
+               texture->unlock();
+       }
+       else
+       {
+               video::IImage *img1 = driver->createImageFromData(format, size, texture->lock(MY_ETLM_READ_ONLY));
+               if (img1 == NULL)
+                       return NULL;
+
+               // img1 is in the texture's color format, convert to 8-bit ARGB
+               video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, size);
+               if (img2 != NULL)
+               {
+                       img1->copyTo(img2);
+                       img1->drop();
+
+                       mesh = extrudeARGB(size.Width, size.Height, (u8*) img2->lock());
+                       img2->unlock();
+                       img2->drop();
+               }
+               img1->drop();
+       }
+       scaleMesh(mesh, scale);  // also recalculates bounding box
+       return mesh;
+}
+
+void scaleMesh(scene::IMesh *mesh, v3f scale)
+{
+       if(mesh == NULL)
+               return;
+
+       core::aabbox3d<f32> bbox;
+       bbox.reset(0,0,0);
+
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       vertices[i].Pos *= scale;
+               }
+               buf->recalculateBoundingBox();
+
+               // calculate total bounding box
+               if(j == 0)
+                       bbox = buf->getBoundingBox();
+               else
+                       bbox.addInternalBox(buf->getBoundingBox());
+       }
+       mesh->setBoundingBox(bbox);
+}
+
+void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
+{
+       if(mesh == NULL)
+               return;
+       
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       vertices[i].Color = color;
+               }
+       }
+}
+
+void setMeshColorByNormalXYZ(scene::IMesh *mesh,
+               const video::SColor &colorX,
+               const video::SColor &colorY,
+               const video::SColor &colorZ)
+{
+       if(mesh == NULL)
+               return;
+       
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       f32 x = fabs(vertices[i].Normal.X);
+                       f32 y = fabs(vertices[i].Normal.Y);
+                       f32 z = fabs(vertices[i].Normal.Z);
+                       if(x >= y && x >= z)
+                               vertices[i].Color = colorX;
+                       else if(y >= z)
+                               vertices[i].Color = colorY;
+                       else
+                               vertices[i].Color = colorZ;
+
+               }
+       }
+}
diff --git a/src/mesh.h b/src/mesh.h
new file mode 100644 (file)
index 0000000..33e0729
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef MESH_HEADER
+#define MESH_HEADER
+
+#include "common_irrlicht.h"
+
+/*
+       Create a new cube mesh.
+       Vertices are at (+-scale.X/2, +-scale.Y/2, +-scale.Z/2).
+
+       The resulting mesh has 6 materials (up, down, right, left, back, front)
+       which must be defined by the caller.
+*/
+scene::IAnimatedMesh* createCubeMesh(v3f scale);
+
+/*
+       Create a new extruded mesh from a texture.
+       Maximum bounding box is (+-scale.X/2, +-scale.Y/2, +-scale.Z).
+       Thickness is in Z direction.
+
+       The resulting mesh has 1 material which must be defined by the caller.
+*/
+scene::IAnimatedMesh* createExtrudedMesh(video::ITexture *texture,
+               video::IVideoDriver *driver, v3f scale);
+
+/*
+       Multiplies each vertex coordinate by the specified scaling factors
+       (componentwise vector multiplication).
+*/
+void scaleMesh(scene::IMesh *mesh, v3f scale);
+
+/*
+       Set a constant color for all vertices in the mesh
+*/
+void setMeshColor(scene::IMesh *mesh, const video::SColor &color);
+
+/*
+       Set the color of all vertices in the mesh.
+       For each vertex, determine the largest absolute entry in
+       the normal vector, and choose one of colorX, colorY or
+       colorZ accordingly.
+*/
+void setMeshColorByNormalXYZ(scene::IMesh *mesh,
+               const video::SColor &colorX,
+               const video::SColor &colorY,
+               const video::SColor &colorZ);
+
+#endif
index 27454c3213e52291fa9914668fa4ab323dcbc93c..89f3451973e078dc8b47fa10916110df8e891e3e 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "filesys.h"
 #include "utility.h"
 #include "settings.h"
+#include "mesh.h"
 #include <ICameraSceneNode.h>
 #include "log.h"
 #include "mapnode.h" // For texture atlas making
@@ -1468,11 +1469,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        assert(img_top && img_left && img_right);
 
                        // Create textures from images
-                       // TODO: Use them all
                        video::ITexture *texture_top = driver->addTexture(
                                        (imagename_top + "__temp__").c_str(), img_top);
-                       assert(texture_top);
-                       
+                       video::ITexture *texture_left = driver->addTexture(
+                                       (imagename_left + "__temp__").c_str(), img_left);
+                       video::ITexture *texture_right = driver->addTexture(
+                                       (imagename_right + "__temp__").c_str(), img_right);
+                       assert(texture_top && texture_left && texture_right);
+
                        // Drop images
                        img_top->drop();
                        img_left->drop();
@@ -1499,17 +1503,24 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                Create scene:
                                - An unit cube is centered at 0,0,0
                                - Camera looks at cube from Y+, Z- towards Y-, Z+
-                               NOTE: Cube has to be changed to something else because
-                               the textures cannot be set individually (or can they?)
                        */
 
-                       scene::ISceneNode* cube = smgr->addCubeSceneNode(1.0, NULL, -1,
-                                       v3f(0,0,0), v3f(0, 45, 0));
+                       scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1));
+                       setMeshColor(cube, video::SColor(255, 255, 255, 255));
+
+                       scene::IMeshSceneNode* cubenode = smgr->addMeshSceneNode(cube, NULL, -1, v3f(0,0,0), v3f(0,45,0), v3f(1,1,1), true);
+                       cube->drop();
+
                        // Set texture of cube
-                       cube->setMaterialTexture(0, texture_top);
-                       //cube->setMaterialFlag(video::EMF_LIGHTING, false);
-                       cube->setMaterialFlag(video::EMF_ANTI_ALIASING, false);
-                       cube->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
+                       cubenode->getMaterial(0).setTexture(0, texture_top);
+                       cubenode->getMaterial(1).setTexture(0, texture_top);
+                       cubenode->getMaterial(2).setTexture(0, texture_right);
+                       cubenode->getMaterial(3).setTexture(0, texture_right);
+                       cubenode->getMaterial(4).setTexture(0, texture_left);
+                       cubenode->getMaterial(5).setTexture(0, texture_left);
+                       cubenode->setMaterialFlag(video::EMF_LIGHTING, true);
+                       cubenode->setMaterialFlag(video::EMF_ANTI_ALIASING, true);
+                       cubenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, true);
 
                        scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0,
                                        v3f(0, 1.0, -1.5), v3f(0, 0, 0));
@@ -1519,7 +1530,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        camera->setProjectionMatrix(pm, true);
 
                        /*scene::ILightSceneNode *light =*/ smgr->addLightSceneNode(0,
-                                       v3f(-50, 100, 0), video::SColorf(0.5,0.5,0.5), 1000);
+                                       v3f(-50, 100, -75), video::SColorf(0.5,0.5,0.5), 1000);
 
                        smgr->setAmbientLight(video::SColorf(0.2,0.2,0.2));
 
@@ -1540,8 +1551,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        driver->setRenderTarget(0, true, true, 0);
 
                        // Free textures of images
-                       // TODO: When all are used, free them all
                        driver->removeTexture(texture_top);
+                       driver->removeTexture(texture_left);
+                       driver->removeTexture(texture_right);
                        
                        // Create image of render target
                        video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim);
index 87c81cb2abdba5cd2526b281ab20f39efb2f2952..4e9f307d8396c7d90be5ba699977cb99f2ba307d 100644 (file)
@@ -172,27 +172,6 @@ int myrand_range(int min, int max)
        return (myrand()%(max-min+1))+min;
 }
 
-#ifndef SERVER
-// Sets the color of all vertices in the mesh
-void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color)
-{
-       if(mesh == NULL)
-               return;
-       
-       u16 mc = mesh->getMeshBufferCount();
-       for(u16 j=0; j<mc; j++)
-       {
-               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
-               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
-               u16 vc = buf->getVertexCount();
-               for(u16 i=0; i<vc; i++)
-               {
-                       vertices[i].Color = color;
-               }
-       }
-}
-#endif
-
 /*
        blockpos: position of block in block coordinates
        camera_pos: position of camera in nodes
index 47696cbf8b80bca964e9939174505d1efb8406ff..14b49772bdbdbf4f6e9b83e4ce44831638f866e9 100644 (file)
@@ -694,11 +694,6 @@ private:
        u32 *m_result;
 };
 
-#ifndef SERVER
-// Sets the color of all vertices in the mesh
-void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
-#endif
-
 // Calculates the borders of a "d-radius" cube
 inline void getFacePositions(core::list<v3s16> &list, u16 d)
 {