forked from 0ad/0ad
Fix for mesh manager crashes (plus some parts of Boost, which may be a little excessive)
This was SVN commit r1488.
This commit is contained in:
parent
61705f7caf
commit
aa1442e8f8
@ -106,7 +106,8 @@ if (OS == "windows") then
|
||||
"openal",
|
||||
"spidermonkey",
|
||||
"xerces",
|
||||
"vorbis"
|
||||
"vorbis",
|
||||
"boost"
|
||||
}
|
||||
|
||||
-- Add '<libraries root>/<libraryname>/lib' and '/include' to the includepaths and libpaths
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
#include "graphics/MeshManager.h"
|
||||
#include "CLogger.h"
|
||||
#include "FileUnpacker.h" // to get access to its CError
|
||||
|
||||
CMeshManager::CMeshManager()
|
||||
{
|
||||
@ -10,71 +11,38 @@ CMeshManager::~CMeshManager()
|
||||
{
|
||||
}
|
||||
|
||||
CModelDef *CMeshManager::GetMesh(const char *filename)
|
||||
CModelDefPtr CMeshManager::GetMesh(const char *filename)
|
||||
{
|
||||
mesh_map::iterator iter;
|
||||
CStr fn(filename);
|
||||
if((iter = m_MeshMap.find(fn)) == m_MeshMap.end())
|
||||
mesh_map::iterator iter = m_MeshMap.find(fn);
|
||||
if (iter != m_MeshMap.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
CModelDef *model = CModelDef::Load(filename);
|
||||
if(!model)
|
||||
return NULL;
|
||||
|
||||
LOG(MESSAGE, "mesh", "Loading mesh '%s'...\n", filename);
|
||||
model->m_Filename = fn;
|
||||
model->m_RefCount = 1;
|
||||
m_MeshMap[fn] = model;
|
||||
return model;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG(ERROR, "mesh", "Could not load mesh '%s'\n!", filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...\n", filename);
|
||||
CModelDef *model = (CModelDef *)(*iter).second;
|
||||
model->m_RefCount++;
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
int CMeshManager::ReleaseMesh(CModelDef* mesh)
|
||||
{
|
||||
if(!mesh)
|
||||
return 0;
|
||||
|
||||
// FIXME: Someone sort this out. I'm tired.
|
||||
// Looks like it might be a multiple delete; not sure best way
|
||||
// to resolve it. MT.
|
||||
|
||||
mesh_map::iterator iter;
|
||||
try
|
||||
{
|
||||
CModelDefPtr model (iter->second);
|
||||
LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...\n", filename);
|
||||
return model;
|
||||
}
|
||||
// If the mesh has already been deleted, the weak_ptr -> shared_ptr
|
||||
// conversion will throw bad_weak_ptr (and we need to reload the mesh)
|
||||
catch (boost::bad_weak_ptr)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
iter = m_MeshMap.find(mesh->m_Filename);
|
||||
CModelDefPtr model (CModelDef::Load(filename));
|
||||
if (!model)
|
||||
return CModelDefPtr();
|
||||
|
||||
LOG(MESSAGE, "mesh", "Loading mesh '%s'...\n", filename);
|
||||
m_MeshMap[fn] = model;
|
||||
return model;
|
||||
}
|
||||
catch( ... )
|
||||
catch (CFileUnpacker::CError)
|
||||
{
|
||||
debug_out( "FIXME: Do something with %s(%d)", __FILE__, __LINE__ );
|
||||
return( 0 );
|
||||
LOG(ERROR, "mesh", "Could not load mesh '%s'\n!", filename);
|
||||
return CModelDefPtr();
|
||||
}
|
||||
|
||||
if(iter == m_MeshMap.end())
|
||||
return 0;
|
||||
|
||||
mesh->m_RefCount--;
|
||||
if(mesh->m_RefCount <= 0)
|
||||
{
|
||||
m_MeshMap.erase(iter);
|
||||
delete mesh;
|
||||
mesh = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mesh->m_RefCount;
|
||||
}
|
||||
|
@ -4,9 +4,14 @@
|
||||
#include "Singleton.h"
|
||||
#include "graphics/ModelDef.h"
|
||||
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include "boost/weak_ptr.hpp"
|
||||
|
||||
#define g_MeshManager CMeshManager::GetSingleton()
|
||||
|
||||
typedef STL_HASH_MAP<CStr, CModelDef *, CStr_hash_compare> mesh_map;
|
||||
typedef STL_HASH_MAP<CStr, boost::weak_ptr<CModelDef>, CStr_hash_compare> mesh_map;
|
||||
|
||||
typedef boost::shared_ptr<CModelDef> CModelDefPtr;
|
||||
|
||||
class CMeshManager : public Singleton<CMeshManager>
|
||||
{
|
||||
@ -14,8 +19,7 @@ public:
|
||||
CMeshManager();
|
||||
~CMeshManager();
|
||||
|
||||
CModelDef *GetMesh(const char *filename);
|
||||
int ReleaseMesh(CModelDef* mesh);
|
||||
CModelDefPtr GetMesh(const char *filename);
|
||||
private:
|
||||
mesh_map m_MeshMap;
|
||||
};
|
||||
|
@ -19,7 +19,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel()
|
||||
: m_pModelDef(0), m_Flags(0), m_Anim(0), m_AnimTime(0),
|
||||
: m_Flags(0), m_Anim(0), m_AnimTime(0),
|
||||
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
|
||||
{
|
||||
}
|
||||
@ -41,13 +41,12 @@ void CModel::ReleaseData()
|
||||
delete m_Props[i].m_Model;
|
||||
}
|
||||
m_Props.clear();
|
||||
if(m_pModelDef)
|
||||
g_MeshManager.ReleaseMesh(m_pModelDef);
|
||||
m_pModelDef = CModelDefPtr();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InitModel: setup model from given geometry
|
||||
bool CModel::InitModel(CModelDef* modeldef)
|
||||
bool CModel::InitModel(CModelDefPtr modeldef)
|
||||
{
|
||||
// clean up any existing data first
|
||||
ReleaseData();
|
||||
@ -289,6 +288,7 @@ void CModel::AddProp(SPropPoint* point,CModel* model)
|
||||
uint i;
|
||||
for (i=0;i<m_Props.size();i++) {
|
||||
if (m_Props[i].m_Point==point) {
|
||||
delete m_Props[i].m_Model;
|
||||
m_Props[i].m_Model=model;
|
||||
return;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "Texture.h"
|
||||
#include "ModelDef.h"
|
||||
#include "MeshManager.h"
|
||||
#include "RenderableObject.h"
|
||||
#include "SkeletonAnim.h"
|
||||
#include "Material.h"
|
||||
@ -40,14 +41,14 @@ public:
|
||||
~CModel();
|
||||
|
||||
// setup model from given geometry
|
||||
bool InitModel(CModelDef *modeldef);
|
||||
bool InitModel(CModelDefPtr modeldef);
|
||||
// calculate the world space bounds of this model
|
||||
void CalcBounds();
|
||||
// update this model's state; 'time' is the time since the last update, in MS
|
||||
void Update(float time);
|
||||
|
||||
// get the model's geometry data
|
||||
CModelDef *GetModelDef() { return m_pModelDef; }
|
||||
CModelDefPtr GetModelDef() { return m_pModelDef; }
|
||||
|
||||
// set the model's texture
|
||||
void SetTexture(const CTexture& tex) { m_Texture=tex; }
|
||||
@ -125,7 +126,7 @@ private:
|
||||
// model's material
|
||||
CMaterial m_Material;
|
||||
// pointer to the model's raw 3d data
|
||||
CModelDef* m_pModelDef;
|
||||
CModelDefPtr m_pModelDef;
|
||||
// object space bounds of model - accounts for bounds of all possible animations
|
||||
// that can play on a model
|
||||
CBound m_ObjectBounds;
|
||||
|
@ -127,8 +127,7 @@ public:
|
||||
SPropPoint* m_PropPoints;
|
||||
protected:
|
||||
static CModelDef* Load(const char* filename);
|
||||
int m_RefCount;
|
||||
CStr m_Filename;
|
||||
//CStr m_Filename;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -46,19 +46,14 @@ bool CObjectEntry::BuildModel()
|
||||
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
|
||||
|
||||
// remember the old model so we can replace any models using it later on
|
||||
CModelDef* oldmodeldef=m_Model ? m_Model->GetModelDef() : 0;
|
||||
|
||||
// try and create a model
|
||||
CModelDef* modeldef;
|
||||
CModelDefPtr oldmodeldef=m_Model ? m_Model->GetModelDef() : CModelDefPtr();
|
||||
|
||||
const char* modelfilename = m_ModelName.c_str();
|
||||
|
||||
try {
|
||||
//modeldef=CModelDef::Load(modelfilename);
|
||||
modeldef = g_MeshManager.GetMesh(modelfilename);
|
||||
if(!modeldef)
|
||||
throw false;
|
||||
} catch (...) {
|
||||
// try and create a model
|
||||
CModelDefPtr modeldef (g_MeshManager.GetMesh(modelfilename));
|
||||
if (!modeldef)
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", modelfilename);
|
||||
return false;
|
||||
}
|
||||
@ -81,15 +76,15 @@ bool CObjectEntry::BuildModel()
|
||||
const char* animfilename = m_Animations[t].m_FileName.c_str();
|
||||
m_Animations[t].m_AnimData = m_Model->BuildAnimation(animfilename,m_Animations[t].m_Speed);
|
||||
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) )
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == "idle" )
|
||||
m_IdleAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) )
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == "walk" )
|
||||
m_WalkAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "attack" ) )
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == "attack" )
|
||||
m_MeleeAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "death" ) )
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == "death" )
|
||||
m_DeathAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "decay" ) )
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == "decay" )
|
||||
m_CorpseAnim = m_Animations[t].m_AnimData;
|
||||
}
|
||||
else
|
||||
@ -158,9 +153,6 @@ bool CObjectEntry::BuildModel()
|
||||
}
|
||||
}
|
||||
|
||||
// and were done with the old model ..
|
||||
delete oldmodeldef;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ void CModelRData::Build()
|
||||
|
||||
void CModelRData::BuildIndices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
CModelDefPtr mdef=m_Model->GetModelDef();
|
||||
assert(mdef);
|
||||
|
||||
// must have a valid vertex buffer by this point so we know where indices are supposed to start
|
||||
@ -138,7 +138,7 @@ static void SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices,C
|
||||
|
||||
void CModelRData::BuildVertices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
CModelDefPtr mdef=m_Model->GetModelDef();
|
||||
|
||||
// allocate vertices if we haven't got any already
|
||||
if (!m_Vertices) {
|
||||
@ -184,7 +184,7 @@ void CModelRData::BuildVertices()
|
||||
|
||||
void CModelRData::RenderStreams(u32 streamflags)
|
||||
{
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
CModelDefPtr mdldef=m_Model->GetModelDef();
|
||||
|
||||
if (streamflags & STREAM_UV0)
|
||||
{
|
||||
@ -243,7 +243,7 @@ float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
|
||||
float mindist=1.0e30f;
|
||||
CVector3D osvtx,csvtx;
|
||||
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
CModelDefPtr mdldef=m_Model->GetModelDef();
|
||||
|
||||
SModelVertex* vtxs=mdldef->GetVertices();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user