Create new instance of mesh every time it's required (Solves #703)
parent
86c616a545
commit
d76957ee22
|
@ -893,30 +893,12 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
|
|||
name = removeStringEnd(filename, model_ext);
|
||||
if(name != "")
|
||||
{
|
||||
verbosestream<<"Client: Storing model into Irrlicht: "
|
||||
verbosestream<<"Client: Storing model into memory: "
|
||||
<<"\""<<filename<<"\""<<std::endl;
|
||||
scene::ISceneManager *smgr = m_device->getSceneManager();
|
||||
|
||||
//check if mesh was already cached
|
||||
scene::IAnimatedMesh *mesh =
|
||||
smgr->getMeshCache()->getMeshByName(filename.c_str());
|
||||
|
||||
if (mesh != NULL) {
|
||||
errorstream << "Multiple models with name: " << filename.c_str() <<
|
||||
" found replacing previous model!" << std::endl;
|
||||
|
||||
smgr->getMeshCache()->removeMesh(mesh);
|
||||
mesh = 0;
|
||||
}
|
||||
|
||||
io::IFileSystem *irrfs = m_device->getFileSystem();
|
||||
io::IReadFile *rfile = irrfs->createMemoryReadFile(
|
||||
*data_rw, data_rw.getSize(), filename.c_str());
|
||||
assert(rfile);
|
||||
|
||||
mesh = smgr->getMesh(rfile);
|
||||
smgr->getMeshCache()->addMesh(filename.c_str(), mesh);
|
||||
rfile->drop();
|
||||
if(m_mesh_data.count(filename))
|
||||
errorstream<<"Multiple models with name \""<<filename.c_str()
|
||||
<<"\" found; replacing previous model"<<std::endl;
|
||||
m_mesh_data[filename] = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2836,3 +2818,31 @@ MtEventManager* Client::getEventManager()
|
|||
return m_event;
|
||||
}
|
||||
|
||||
scene::IAnimatedMesh* Client::getMesh(const std::string &filename)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator i =
|
||||
m_mesh_data.find(filename);
|
||||
if(i == m_mesh_data.end()){
|
||||
errorstream<<"Client::getMesh(): Mesh not found: \""<<filename<<"\""
|
||||
<<std::endl;
|
||||
return NULL;
|
||||
}
|
||||
const std::string &data = i->second;
|
||||
scene::ISceneManager *smgr = m_device->getSceneManager();
|
||||
|
||||
// Create the mesh, remove it from cache and return it
|
||||
// This allows unique vertex colors and other properties for each instance
|
||||
Buffer<char> data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht
|
||||
io::IFileSystem *irrfs = m_device->getFileSystem();
|
||||
io::IReadFile *rfile = irrfs->createMemoryReadFile(
|
||||
*data_rw, data_rw.getSize(), filename.c_str());
|
||||
assert(rfile);
|
||||
scene::IAnimatedMesh *mesh = smgr->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();
|
||||
smgr->getMeshCache()->removeMesh(mesh);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -420,6 +420,7 @@ public:
|
|||
virtual MtEventManager* getEventManager();
|
||||
virtual bool checkLocalPrivilege(const std::string &priv)
|
||||
{ return checkPrivilege(priv); }
|
||||
virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
|
||||
|
||||
// The following set of functions is used by ClientMediaDownloader
|
||||
// Insert a media file appropriately into the appropriate manager
|
||||
|
@ -509,6 +510,9 @@ private:
|
|||
// Detached inventories
|
||||
// key = name
|
||||
std::map<std::string, Inventory*> m_detached_inventories;
|
||||
|
||||
// Storage for mesh data for creating multiple instances of the same mesh
|
||||
std::map<std::string, std::string> m_mesh_data;
|
||||
};
|
||||
|
||||
#endif // !CLIENT_HEADER
|
||||
|
|
|
@ -957,10 +957,11 @@ public:
|
|||
}
|
||||
else if(m_prop.visual == "mesh"){
|
||||
infostream<<"GenericCAO::addToScene(): mesh"<<std::endl;
|
||||
scene::IAnimatedMesh *mesh = smgr->getMesh(m_prop.mesh.c_str());
|
||||
scene::IAnimatedMesh *mesh = m_gamedef->getMesh(m_prop.mesh);
|
||||
if(mesh)
|
||||
{
|
||||
m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL);
|
||||
mesh->drop(); // The scene node took hold of it
|
||||
m_animated_meshnode->animateJoints(); // Needed for some animations
|
||||
m_animated_meshnode->setScale(v3f(m_prop.visual_size.X,
|
||||
m_prop.visual_size.Y,
|
||||
|
|
|
@ -31,6 +31,9 @@ class ISoundManager;
|
|||
class IShaderSource;
|
||||
class MtEventManager;
|
||||
class IRollbackReportSink;
|
||||
namespace irr { namespace scene {
|
||||
class IAnimatedMesh;
|
||||
}}
|
||||
|
||||
/*
|
||||
An interface for fetching game-global definitions like tool and
|
||||
|
@ -58,6 +61,8 @@ public:
|
|||
// Only usable on the client
|
||||
virtual ISoundManager* getSoundManager()=0;
|
||||
virtual MtEventManager* getEventManager()=0;
|
||||
virtual scene::IAnimatedMesh* getMesh(const std::string &filename)
|
||||
{ return NULL; }
|
||||
|
||||
// Only usable on the server, and NOT thread-safe. It is usable from the
|
||||
// environment thread.
|
||||
|
|
Loading…
Reference in New Issue