1
0
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:
Ykkrosh 2004-12-12 18:40:00 +00:00
parent 61705f7caf
commit aa1442e8f8
8 changed files with 58 additions and 93 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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();