From fd9f195fcc2e4e592dbad3290876486eb08318b2 Mon Sep 17 00:00:00 2001 From: Lars Hofhansl Date: Mon, 4 Dec 2017 22:25:09 -0800 Subject: [PATCH] Use Irrlicht's mesh cache for animated meshes. Fixes #6676. Allow animated meshes to be cached in Irrlicht's builtin mesh cache. Use Material.EmmissiveColor instead of manipulating the mesh' vertex colors. --- src/client.cpp | 7 +++---- src/client.h | 2 +- src/content_cao.cpp | 12 ++++++++---- src/mesh.cpp | 8 ++++++++ src/mesh.h | 5 +++++ 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 1a6a87487..2d1572d8e 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1836,7 +1836,7 @@ ParticleManager* Client::getParticleManager() return &m_particle_manager; } -scene::IAnimatedMesh* Client::getMesh(const std::string &filename) +scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache) { StringMap::const_iterator it = m_mesh_data.find(filename); if (it == m_mesh_data.end()) { @@ -1855,10 +1855,9 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename) scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile); rfile->drop(); - // NOTE: By playing with Irrlicht refcounts, maybe we could cache a bunch - // of uniquely named instances and re-use them mesh->grab(); - RenderingEngine::get_mesh_cache()->removeMesh(mesh); + if (!cache) + RenderingEngine::get_mesh_cache()->removeMesh(mesh); return mesh; } diff --git a/src/client.h b/src/client.h index 36f564086..d8b56b0b3 100644 --- a/src/client.h +++ b/src/client.h @@ -376,7 +376,7 @@ public: virtual ParticleManager* getParticleManager(); bool checkLocalPrivilege(const std::string &priv) { return checkPrivilege(priv); } - virtual scene::IAnimatedMesh* getMesh(const std::string &filename); + virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false); const std::string* getModFile(const std::string &filename); virtual std::string getModStoragePath() const; diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 26f5634d4..9d87c733e 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -563,7 +563,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) } else if(m_prop.visual == "mesh") { infostream<<"GenericCAO::addToScene(): mesh"<getMesh(m_prop.mesh); + scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true); if(mesh) { m_animated_meshnode = RenderingEngine::get_scene_manager()-> @@ -575,13 +575,17 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_prop.visual_size.Y, m_prop.visual_size.X)); u8 li = m_last_light; + + // set vertex colors to ensure alpha is set setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); + setAnimatedMeshColor(m_animated_meshnode, video::SColor(255,li,li,li)); + bool backface_culling = m_prop.backface_culling; if (m_is_player) backface_culling = false; - m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); + m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, true); m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); @@ -669,7 +673,7 @@ void GenericCAO::updateLightNoCheck(u8 light_at_pos) if (m_meshnode) { setMeshColor(m_meshnode->getMesh(), color); } else if (m_animated_meshnode) { - setMeshColor(m_animated_meshnode->getMesh(), color); + setAnimatedMeshColor(m_animated_meshnode, color); } else if (m_wield_meshnode) { m_wield_meshnode->setColor(color); } else if (m_spritenode) { @@ -1025,7 +1029,7 @@ void GenericCAO::updateTextures(std::string mod) // Set material flags and texture video::SMaterial& material = m_animated_meshnode->getMaterial(i); material.TextureLayer[0].Texture = texture; - material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_LIGHTING, true); material.setFlag(video::EMF_BILINEAR_FILTER, false); // don't filter low-res textures, makes them look blurry diff --git a/src/mesh.cpp b/src/mesh.cpp index 218e2d0b2..7fc7531f2 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include // In Irrlicht 1.8 the signature of ITexture::lock was changed from // (bool, u32) to (E_TEXTURE_LOCK_MODE, u32). @@ -184,6 +185,13 @@ void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color) ((video::S3DVertex *) (vertices + i * stride))->Color = color; } +void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color) +{ + for (u32 i = 0; i < node->getMaterialCount(); ++i) { + node->getMaterial(i).EmissiveColor = color; + } +} + void setMeshColor(scene::IMesh *mesh, const video::SColor &color) { if (mesh == NULL) diff --git a/src/mesh.h b/src/mesh.h index 35270a999..0c4094de2 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -58,6 +58,11 @@ void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color); */ void setMeshColor(scene::IMesh *mesh, const video::SColor &color); +/* + Set a constant color for an animated mesh +*/ +void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color); + /*! * Overwrites the color of a mesh buffer. * The color is darkened based on the normal vector of the vertices. -- 2.25.1