Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lhofhansl committed Dec 5, 2017
1 parent f470cb7 commit fd9f195
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 9 deletions.
7 changes: 3 additions & 4 deletions src/client.cpp
Expand Up @@ -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()) {
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/client.h
Expand Up @@ -376,7 +376,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
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;
Expand Down
12 changes: 8 additions & 4 deletions src/content_cao.cpp
Expand Up @@ -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()->
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/mesh.cpp
Expand Up @@ -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).
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions src/mesh.h
Expand Up @@ -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.
Expand Down

1 comment on commit fd9f195

@jmdevy
Copy link
Contributor

@jmdevy jmdevy commented on fd9f195 Dec 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just going to say this here, but these last few commits by you, @lhofhansl, have really made the performance of the game better when it comes to entities. I tried the nssm mod on both the current stable version of Minetest and on the version with this commit; it is like night and day how much better this is. On the stable version, I get drops in FPS every couple of seconds with like 30 mobs spawned, with this though, I don't notice anything, even with more mobs > 30.

0.5.0 is going to really improve this game.

Please sign in to comment.