From: <axl...@us...> - 2009-08-16 13:58:15
|
Revision: 479 http://hgengine.svn.sourceforge.net/hgengine/?rev=479&view=rev Author: axlecrusher Date: 2009-08-16 13:58:08 +0000 (Sun, 16 Aug 2009) Log Message: ----------- Change how MercuryNodes handle assets. Asset are still instanced, but instead of MercuryNode storing auto pointers to assets, they store a MercuryAssetInstance. Assets are still instanced, but also allows for per-instance data storage. Perviously no per-instance data was allowed as it would affect all instaces of an asset. This change is useful for culling and occlusion tests. Also the Prerender, Render, and PostRender lists have been removed. Currently all assets have all 3 render functions executed. This may change in the future. Modified Paths: -------------- Mercury2/src/HGMDLMesh.h Mercury2/src/HGMDLModel.cpp Mercury2/src/HGMDLModel.h Mercury2/src/MercuryAsset.cpp Mercury2/src/MercuryAsset.h Mercury2/src/MercuryNode.cpp Mercury2/src/MercuryNode.h Mercury2/src/Shader.cpp Mercury2/src/Texture.cpp Mercury2/src/Viewport.cpp Modified: Mercury2/src/HGMDLMesh.h =================================================================== --- Mercury2/src/HGMDLMesh.h 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/HGMDLMesh.h 2009-08-16 13:58:08 UTC (rev 479) @@ -11,6 +11,7 @@ void ReadExtraData(MercuryFile* hgmdl); void LoadOBB(MercuryFile* hgmdl); + OcclusionResult m_occlusionResult; private: MString m_name; bool m_cachable; Modified: Mercury2/src/HGMDLModel.cpp =================================================================== --- Mercury2/src/HGMDLModel.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/HGMDLModel.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -60,14 +60,14 @@ } } -bool HGMDLModel::DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix) +bool HGMDLModel::DoCullingTests(OcclusionResult& occlusion, const MercuryMatrix& matrix) { bool culled = false; if ( GetLoadState() != LOADING ) { culled = true; for(uint16_t i = 0; i < m_meshes.size(); ++i) - culled = culled && m_meshes[i]->DoCullingTests(n, matrix); + culled = culled && m_meshes[i]->DoCullingTests(m_meshes[i]->m_occlusionResult, matrix); } return culled; } @@ -85,7 +85,7 @@ { for(uint16_t i = 0; i < m_meshes.size(); ++i) { - if ( !(node->GetOcclusionResult().IsOccluded() || node->IsCulled()) ) + if ( !(m_meshes[i]->m_occlusionResult.IsOccluded() || node->IsCulled()) ) m_meshes[i]->Render(node); } } Modified: Mercury2/src/HGMDLModel.h =================================================================== --- Mercury2/src/HGMDLModel.h 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/HGMDLModel.h 2009-08-16 13:58:08 UTC (rev 479) @@ -19,7 +19,7 @@ static HGMDLModel* Generate(); - virtual bool DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix); + virtual bool DoCullingTests(OcclusionResult& occlusion, const MercuryMatrix& matrix); virtual void PreRender(const MercuryNode* node); virtual void Render(const MercuryNode* node); Modified: Mercury2/src/MercuryAsset.cpp =================================================================== --- Mercury2/src/MercuryAsset.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/MercuryAsset.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -17,9 +17,8 @@ void MercuryAsset::Init(MercuryNode* node) { -// RenderableNode* rn; - if ( node ) node->AddPreRender(this); - if ( node ) node->AddRender(this); +// if ( node ) node->AddPreRender(this); +// if ( node ) node->AddRender(this); } void MercuryAsset::SetLoadState(LoadState ls) @@ -39,14 +38,13 @@ SetLoadState( LOADED ); } -bool MercuryAsset::DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix) +bool MercuryAsset::DoCullingTests(OcclusionResult& occlusion, const MercuryMatrix& matrix) { bool culled = false; if ( m_boundingVolume ) { culled = m_boundingVolume->DoFrustumTest(matrix); - if ( !culled && DOOCCLUSIONCULL) - m_boundingVolume->DoOcclusionTest( n->GetOcclusionResult() ); + if ( !culled && DOOCCLUSIONCULL) m_boundingVolume->DoOcclusionTest( occlusion ); } return culled; } @@ -89,6 +87,11 @@ glEnd(); } +MercuryAssetInstance::MercuryAssetInstance(MercuryAsset* asset) + :m_asset( asset ), m_isCulled( false ) +{ +} + AssetFactory& AssetFactory::GetInstance() { static AssetFactory* instance = NULL; Modified: Mercury2/src/MercuryAsset.h =================================================================== --- Mercury2/src/MercuryAsset.h 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/MercuryAsset.h 2009-08-16 13:58:08 UTC (rev 479) @@ -52,7 +52,7 @@ inline const MString& Path() const { return m_path; } ///Retuns true if culled, also will initiate occlusion test - virtual bool DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix); + virtual bool DoCullingTests(OcclusionResult& occlusion, const MercuryMatrix& matrix); void DrawAxes(); inline void SetExcludeFromCull(bool t) { m_excludeFromCull = t; } @@ -70,6 +70,26 @@ bool m_excludeFromCull; }; +/** This holds the per-instance data for each asset instance. +Used in MercuryNode. */ +class MercuryAssetInstance +{ + public: + MercuryAssetInstance(MercuryAsset* asset); + inline MercuryAsset& Asset() { return *m_asset; } + inline const MercuryAsset& Asset() const { return *m_asset; } + inline const MercuryAsset* AssetPtr() const { return m_asset; } + + inline bool Culled() const { return m_isCulled; } + inline bool Culled(bool t) { m_isCulled = t; return m_isCulled; } + + inline OcclusionResult& GetOcclusionResult() { return m_occlusionResult; } + private: + MAutoPtr< MercuryAsset > m_asset; //actual asset storage + OcclusionResult m_occlusionResult; + bool m_isCulled; +}; + class LoaderThreadData { public: @@ -97,7 +117,7 @@ std::list< std::pair< MString, Callback0R< MAutoPtr<MercuryAsset> > > > m_factoryCallbacks; - //the actual storage point is in renderable nodes + //the actual storage point is in MercuryAssetInstance static std::map<MString, MercuryAsset*> m_assetInstances; }; Modified: Mercury2/src/MercuryNode.cpp =================================================================== --- Mercury2/src/MercuryNode.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/MercuryNode.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -29,6 +29,11 @@ m_children.clear(); } +void MercuryNode::AddAsset(MercuryAsset* asset) +{ + m_assets.push_back( MercuryAssetInstance(asset) ); +} + void MercuryNode::AddChild(MercuryNode* n) { // list< MercuryNode* >::iterator last = m_children.end(); @@ -181,7 +186,7 @@ void MercuryNode::RecursiveRender() { - if ( IsHidden() || m_occlusionResult.IsOccluded() || IsCulled() ) return; + if ( IsHidden() || IsCulled() ) return; const MercuryMatrix& matrix = FindGlobalMatrix(); const MercuryMatrix& modelView = FindModelViewMatrix(); //get the one computed in the last transform @@ -263,28 +268,31 @@ { SetCulled( false ); bool culled = true; - list< MercuryAsset* >::iterator i; - for (i = m_prerender.begin(); i != m_prerender.end(); ++i ) + + std::list< MercuryAssetInstance >::iterator i; + for (i = m_assets.begin(); i != m_assets.end(); ++i ) { - if ( !(*i)->ExcludeFromCull() ) - culled = culled && (*i)->DoCullingTests( this, matrix ); - (*i)->PreRender(this); - SetCulled( culled ); + MercuryAssetInstance& mai = *i; + MercuryAsset& a = mai.Asset(); + if ( !a.ExcludeFromCull() ) + culled = culled && mai.Culled( a.DoCullingTests( mai.GetOcclusionResult(), matrix ) ); + if ( !mai.Culled() ) a.PreRender(this); } + SetCulled( culled ); } void MercuryNode::Render(const MercuryMatrix& matrix) { - list< MercuryAsset* >::iterator i; - for (i = m_render.begin(); i != m_render.end(); ++i ) - (*i)->Render(this); + std::list< MercuryAssetInstance >::iterator i; + for (i = m_assets.begin(); i != m_assets.end(); ++i ) + if ( !(i->Culled() || i->GetOcclusionResult().IsOccluded()) ) i->Asset().Render(this); } void MercuryNode::PostRender(const MercuryMatrix& matrix) { - list< MercuryAsset* >::iterator i; - for (i = m_postrender.begin(); i != m_postrender.end(); ++i ) - (*i)->PostRender(this); + std::list< MercuryAssetInstance >::iterator i; + for (i = m_assets.begin(); i != m_assets.end(); ++i ) + i->Asset().PostRender(this); } const MercuryMatrix& MercuryNode::FindGlobalMatrix() const @@ -315,43 +323,6 @@ return MercuryMatrix::Identity(); } -void MercuryNode::AddPreRender(MercuryAsset* asset) -{ -#ifdef MCHECKASSETS - if ( !IsInAssetList(asset) ) //yell and scream - assert(!"Asset does not exist in list!"); -#endif - - m_prerender.push_back(asset); -} - -void MercuryNode::AddRender(MercuryAsset* asset) -{ -#ifdef MCHECKASSETS - if ( !IsInAssetList(asset) ) //yell and scream - assert(!"Asset does not exist in list!"); -#endif - - m_render.push_back(asset); -} -void MercuryNode::AddPostRender(MercuryAsset* asset) -{ -#ifdef MCHECKASSETS - if ( !IsInAssetList(asset) ) //yell and scream - assert(!"Asset does not exist in list!"); -#endif - - m_postrender.push_back(asset); -} - -bool MercuryNode::IsInAssetList( MercuryAsset* asset ) const -{ - std::list< MAutoPtr< MercuryAsset > >::const_iterator i; - for (i = m_assets.begin(); i != m_assets.end(); ++i ) - if ( (*i) == asset ) return true; - return false; -} - bool MercuryNode::IsCulled(const MercuryMatrix& matrix) { bool clip = false; Modified: Mercury2/src/MercuryNode.h =================================================================== --- Mercury2/src/MercuryNode.h 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/MercuryNode.h 2009-08-16 13:58:08 UTC (rev 479) @@ -35,7 +35,7 @@ void AddChild(MercuryNode* n); void RemoveChild(MercuryNode* n); - + inline MercuryNode* Parent() const { return m_parent; } inline MercuryNode* NextSibling() const { return m_nextSibling; } inline MercuryNode* PrevSibling() const { return m_prevSibling; } @@ -86,12 +86,8 @@ inline void SetName(const MString& name) { m_name = name; } inline MString GetName() const { return m_name; } - inline void AddAsset(MAutoPtr< MercuryAsset > asset) { m_assets.push_back(asset); } + void AddAsset(MercuryAsset* asset); - void AddPreRender(MercuryAsset* asset); - void AddRender(MercuryAsset* asset); - void AddPostRender(MercuryAsset* asset); - virtual void PreRender(const MercuryMatrix& matrix); virtual void Render(const MercuryMatrix& matrix); virtual void PostRender(const MercuryMatrix& matrix); @@ -107,8 +103,6 @@ inline bool IsCulled() const { return m_culled; } virtual MercuryMatrix ManipulateMatrix(const MercuryMatrix& matrix); - inline OcclusionResult& GetOcclusionResult() { return m_occlusionResult; } - inline const OcclusionResult& GetOcclusionResult() const { return m_occlusionResult; } protected: std::list< MercuryNode* > m_children; //These nodes are unique, not instanced MercuryNode* m_parent; @@ -119,22 +113,22 @@ MString m_name; bool m_hidden; - bool m_useAlphaPath; - bool m_culled; public: //XXX: This will become private sooner or later... It is temporarily public for other work. bool IsInAssetList(MercuryAsset* asset) const; + bool m_useAlphaPath; - OcclusionResult m_occlusionResult; + private: + bool m_culled; //The asset is actually stored here - std::list< MAutoPtr< MercuryAsset > > m_assets; + std::list< MercuryAssetInstance > m_assets; //we will just use normal pointers here because we don't want to waste too much time //dereferencing the autopointer. As a precaution when assets are added to these lists, //they must exist in m_assets. - std::list< MercuryAsset* > m_prerender; - std::list< MercuryAsset* > m_render; - std::list< MercuryAsset* > m_postrender; +// std::list< MercuryAsset* > m_prerender; +// std::list< MercuryAsset* > m_render; +// std::list< MercuryAsset* > m_postrender; }; class NodeFactory Modified: Mercury2/src/Shader.cpp =================================================================== --- Mercury2/src/Shader.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/Shader.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -61,8 +61,6 @@ void Shader::Init(MercuryNode* node) { MercuryAsset::Init( node ); -// RenderableNode* rn = RenderableNode::Cast( node ); - if ( node ) node->AddPostRender( this ); } void Shader::Render(const MercuryNode* node) Modified: Mercury2/src/Texture.cpp =================================================================== --- Mercury2/src/Texture.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/Texture.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -40,9 +40,6 @@ void Texture::Init(MercuryNode* node) { MercuryAsset::Init( node ); - -// RenderableNode* rn = RenderableNode::Cast( node ); - if ( node ) node->AddPostRender( this ); } void Texture::LoadFromRaw() Modified: Mercury2/src/Viewport.cpp =================================================================== --- Mercury2/src/Viewport.cpp 2009-08-16 13:40:19 UTC (rev 478) +++ Mercury2/src/Viewport.cpp 2009-08-16 13:58:08 UTC (rev 479) @@ -66,7 +66,7 @@ n->PreRender( matrix ); if( n->Parent() ) - n->Parent()->m_culled = n->Parent()->m_culled && n->IsCulled(); + n->Parent()->SetCulled( n->Parent()->IsCulled() && n->IsCulled() ); //Traverse next /* @@ -103,7 +103,7 @@ n = this; while( n ) { - if( n->IsHidden() || m_occlusionResult.IsOccluded() || IsCulled() ) + if( n->IsHidden() || IsCulled() ) { //Make sure we have a next sibling... while( n && n != this && !n->NextSibling() ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |