diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35cdad3..1666930 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -146,7 +146,6 @@ endif() # Client sources set(minetest_SRCS ${common_SRCS} - MyBillboardSceneNode.cpp content_mapblock.cpp content_cao.cpp mapblock_mesh.cpp diff --git a/src/camera.cpp b/src/camera.cpp index 4bf2f87..31edb1b 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -22,6 +22,7 @@ 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 @@ -529,8 +530,9 @@ ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode() void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) { - if (texture == NULL) - { + const v3f sprite_scale(1.0,1.0, 1.0); // width, height, thickness + + if (texture == NULL) { m_meshnode->setVisible(false); return; } @@ -546,7 +548,7 @@ 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; @@ -570,8 +572,9 @@ void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture) void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6]) { + const v3f cube_scale(1.0, 1.0, 1.0); if (m_cubemesh == NULL) - m_cubemesh = createCubeMesh(); + m_cubemesh = createCubeMesh(cube_scale); m_meshnode->setMesh(m_cubemesh); m_meshnode->setScale(v3f(1)); @@ -645,259 +648,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 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(true); - 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(true)); - 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; -} diff --git a/src/camera.h b/src/camera.h index b6349d2..0959bda 100644 --- a/src/camera.h +++ b/src/camera.h @@ -225,9 +225,6 @@ private: // 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 diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 0935860..8e5b941 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -23,6 +23,15 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include +static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, + float txs, float tys, int col, int row) +{ + video::SMaterial& material = bill->getMaterial(0); + core::matrix4& matrix = material.getTextureMatrix(0); + matrix.setTextureTranslate(txs*col, tys*row); + matrix.setTextureScale(txs, tys); +} + core::map ClientActiveObject::m_types; /* @@ -903,8 +912,8 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr) std::string texture_string = "[makealpha2:128,0,0;128,128,0:"; texture_string += m_texture_name; - scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode( - smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1)); + scene::IBillboardSceneNode *bill = smgr->addBillboardSceneNode( + NULL, v2f(1, 1), v3f(0,0,0), -1); bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string)); bill->setMaterialFlag(video::EMF_LIGHTING, false); bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); @@ -918,17 +927,11 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr) const float txs = txp*32; const float typ = 1./240; const float tys = typ*48; - bill->setTCoords(0, v2f(txs*1, tys*1)); - bill->setTCoords(1, v2f(txs*1, tys*0)); - bill->setTCoords(2, v2f(txs*0, tys*0)); - bill->setTCoords(3, v2f(txs*0, tys*1)); + setBillboardTextureMatrix(bill, txs, tys, 0, 0); } else if(m_sprite_type == "simple"){ const float txs = 1.0; const float tys = 1.0 / m_simple_anim_frames; - bill->setTCoords(0, v2f(txs*1, tys*1)); - bill->setTCoords(1, v2f(txs*1, tys*0)); - bill->setTCoords(2, v2f(txs*0, tys*0)); - bill->setTCoords(3, v2f(txs*0, tys*1)); + setBillboardTextureMatrix(bill, txs, tys, 0, 0); } else { infostream<<"MobV2CAO: Unknown sprite type \""<setTCoords(0, v2f(txs*(1+col), tys*(1+row))); - bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row))); - bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row))); - bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row))); + setBillboardTextureMatrix(bill, txs, tys, col, row); } else if(m_sprite_type == "simple"){ m_walk_timer += dtime; if(m_walk_timer >= m_simple_anim_frametime){ @@ -1059,10 +1059,7 @@ void MobV2CAO::step(float dtime, ClientEnvironment *env) int row = m_walk_frame; const float txs = 1.0; const float tys = 1.0 / m_simple_anim_frames; - bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row))); - bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row))); - bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row))); - bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row))); + setBillboardTextureMatrix(bill, txs, tys, col, row); } else { infostream<<"MobV2CAO::step(): Unknown sprite type \"" < /* SmoothTranslator @@ -348,7 +348,7 @@ private: IntervalLimiter m_attack_interval; core::aabbox3d m_selection_box; - scene::MyBillboardSceneNode *m_node; + scene::IBillboardSceneNode *m_node; v3f m_position; std::string m_texture_name; float m_yaw; diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index b550fa3..e15cec9 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -160,7 +160,7 @@ void LockingChestNodeMetadata::serializeBody(std::ostream &os) } std::string LockingChestNodeMetadata::infoText() { - return "Locking Chest"; + return std::string("Locking Chest owned by '")+m_text+"'"; } bool LockingChestNodeMetadata::nodeRemovalDisabled() {