Use Irrlicht's mesh cache for animated meshes.
authorLars Hofhansl <larsh@apache.org>
Tue, 5 Dec 2017 06:25:09 +0000 (22:25 -0800)
committerLars Hofhansl <larsh@apache.org>
Tue, 5 Dec 2017 06:29:11 +0000 (22:29 -0800)
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
src/client.h
src/content_cao.cpp
src/mesh.cpp
src/mesh.h

index 1a6a87487bec2e52e400d0ed0d6d96ac049d3d30..2d1572d8ee9d346b8652937e70850a4181eaf22f 100644 (file)
@@ -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;
 }
 
index 36f5640867b27172a975d4d78f7c3b71f018ccd5..d8b56b0b35a3ebab888014a7f41251fe0e064335 100644 (file)
@@ -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;
index 26f5634d4904ca035f7c53ab1b5a65c1d6d223c6..9d87c733e92d6552d1b0e7634488e0ea45df1f1b 100644 (file)
@@ -563,7 +563,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
        }
        else if(m_prop.visual == "mesh") {
                infostream<<"GenericCAO::addToScene(): mesh"<<std::endl;
-               scene::IAnimatedMesh *mesh = m_client->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
index 218e2d0b2d1acffad9c2f1f0157c0bcd5b24a2dc..7fc7531f2e8b00dcd2c33710a3340721571efd69 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <iostream>
 #include <IAnimatedMesh.h>
 #include <SAnimatedMesh.h>
+#include <IAnimatedMeshSceneNode.h>
 
 // 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)
index 35270a999bdcbcd22c116743e6f5bf0b119d94a5..0c4094de2a7777e5138ceb47b99b188a0c945c6f 100644 (file)
@@ -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.