Temporary cache implementation for lightmapping during export

develop
kaetemi 4 years ago
parent 3df1fd3857
commit 147cb75a80

@ -32,6 +32,11 @@ using namespace NLMISC;
// CRTWorld // CRTWorld
// *********************************************************************************************** // ***********************************************************************************************
std::map<INode *, std::pair<NL3D::CMesh::CMeshBuild *, NL3D::CMeshBase::CMeshBaseBuild *>> CRTWorld::s_WorldCache;
std::map<INode *, NLMISC::CAABBox> CRTWorld::s_WorldCacheAABBox;
INode *CRTWorld::s_WorldCacheRoot;
std::string CRTWorld::s_WorldCacheFile;
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
CRTWorld::CRTWorld (bool errorInDialog, bool view, bool absolutePath, Interface *ip, std::string errorTitle, CExportNel *exp) CRTWorld::CRTWorld (bool errorInDialog, bool view, bool absolutePath, Interface *ip, std::string errorTitle, CExportNel *exp)
{ {
@ -351,22 +356,33 @@ void CRTWorld::testCell (CRGBAF &retValue, SGridCell &cell, CVector &vLightPos,
void CRTWorld::addNode (INode *pNode, vector< CMesh::CMeshBuild* > &Meshes, vector< CMeshBase::CMeshBaseBuild* > &MeshesBase, void CRTWorld::addNode (INode *pNode, vector< CMesh::CMeshBuild* > &Meshes, vector< CMeshBase::CMeshBaseBuild* > &MeshesBase,
vector< INode* > &INodes, vector<SLightBuild> &AllLights, const set<INode*> &excludeNode, TimeValue tvTime) vector< INode* > &INodes, vector<SLightBuild> &AllLights, const set<INode*> &excludeNode, TimeValue tvTime)
{ {
if (! RPO::isZone (*pNode, tvTime) ) if (!RPO::isZone(*pNode, tvTime)
if (CExportNel::isMesh (*pNode, tvTime)) && CExportNel::isMesh(*pNode, tvTime))
{ {
// Nel export // Nel export
CExportNel exportNel (_ErrorInDialog, _View, true, _Ip, _ErrorTitle, NULL); nlassert(_Ip->GetRootNode() == s_WorldCacheRoot);
CAABBox aabbox; CAABBox aabbox;
exportNel.buildMeshAABBox(*pNode, aabbox, tvTime); std::map<INode *, CAABBox>::iterator aabboxIt = s_WorldCacheAABBox.find(pNode);
aabbox.setCenter(aabbox.getCenter()+GlobalTrans); if (aabboxIt == s_WorldCacheAABBox.end())
{
CExportNel exportNel(_ErrorInDialog, _View, true, _Ip, _ErrorTitle, NULL);
exportNel.buildMeshAABBox(*pNode, aabbox, tvTime);
s_WorldCacheAABBox[pNode] = aabbox;
}
else
{
// FIXME: This breaks repeated exports while the file is open and being changed!!! Not an issue for now
aabbox = aabboxIt->second;
}
aabbox.setCenter(aabbox.getCenter() + GlobalTrans);
// Not an excluded node ? // Not an excluded node ?
bool bInteract = false; bool bInteract = false;
if (excludeNode.find (pNode) == excludeNode.end()) if (excludeNode.find(pNode) == excludeNode.end())
{ {
for( uint32 i = 0; i < AllLights.size(); ++i ) for (uint32 i = 0; i < AllLights.size(); ++i)
{ {
if( isInteractionWithLight (AllLights[i], aabbox)) // FIXME: This is always true with sunlight! if (isInteractionWithLight(AllLights[i], aabbox)) // FIXME: This is always true with sunlight!
{ {
bInteract = true; bInteract = true;
break; break;
@ -374,25 +390,41 @@ void CRTWorld::addNode (INode *pNode, vector< CMesh::CMeshBuild* > &Meshes, vec
} }
} }
if (bInteract)
if( bInteract )
{ {
int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32); int nAccelType = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_ACCEL, 32);
if ((nAccelType&3) == 0) // If not an accelerator if ((nAccelType & 3) == 0) // If not an accelerator
{ {
nlassert(_Ip->GetRootNode() == s_WorldCacheRoot);
CMesh::CMeshBuild *pMB; CMesh::CMeshBuild *pMB;
CMeshBase::CMeshBaseBuild *pMBB; CMeshBase::CMeshBaseBuild *pMBB;
pMB = exportNel.createMeshBuild ( *pNode, tvTime, pMBB); // FIXME: This is slow! std::map<INode *, std::pair<NL3D::CMesh::CMeshBuild *, NL3D::CMeshBase::CMeshBaseBuild *>>::iterator buildIt = s_WorldCache.find(pNode);
if( pMBB->bCastShadows ) if (buildIt == s_WorldCache.end())
{ {
Meshes.push_back( pMB ); CExportNel exportNel(_ErrorInDialog, _View, true, _Ip, _ErrorTitle, NULL);
MeshesBase.push_back( pMBB ); pMB = exportNel.createMeshBuild(*pNode, tvTime, pMBB);
INodes.push_back( pNode ); if (!pMBB->bCastShadows)
{
delete pMB; // No interaction so delete the mesh
pMB = NULL;
delete pMBB; // No interaction so delete the mesh
pMBB = NULL;
}
s_WorldCache[pNode] = std::make_pair(pMB ? new CMesh::CMeshBuild(*pMB) : NULL, pMBB ? new CMeshBase::CMeshBaseBuild(*pMBB) : NULL);
} }
else else
{ {
delete pMB; // No interaction so delete the mesh // FIXME: This breaks repeated exports while the file is open and being changed!!! Not an issue for now
delete pMBB; // No interaction so delete the mesh pMB = buildIt->second.first ? new CMesh::CMeshBuild(*buildIt->second.first) : NULL;
pMBB = buildIt->second.second ? new CMeshBase::CMeshBaseBuild(*buildIt->second.second) : NULL;
}
if (pMBB) // Implies pMBB->bCastShadows
{
Meshes.push_back(pMB);
MeshesBase.push_back(pMBB);
INodes.push_back(pNode);
} }
} }
} }
@ -405,6 +437,20 @@ void CRTWorld::getAllSelectedNode (vector< CMesh::CMeshBuild* > &Meshes,
vector< INode* > &INodes, vector< INode* > &INodes,
vector<SLightBuild> &AllLights, const set<INode*> &excludeNode, const set<INode*> &includeNode) vector<SLightBuild> &AllLights, const set<INode*> &excludeNode, const set<INode*> &includeNode)
{ {
if (_Ip->GetRootNode() != s_WorldCacheRoot || MaxTStrToUtf8(_Ip->GetCurFileName()) != s_WorldCacheFile) // FIXME: This breaks repeated exports while the file is open and being changed!!! Not an issue for now
{
// Erase all cached builds
for (std::map<INode *, std::pair<NL3D::CMesh::CMeshBuild *, NL3D::CMeshBase::CMeshBaseBuild *>>::iterator it(s_WorldCache.begin()), end(s_WorldCache.end()); it != end; ++it)
{
delete it->second.first;
delete it->second.second;
}
s_WorldCache.clear();
s_WorldCacheAABBox.clear();
s_WorldCacheRoot = _Ip->GetRootNode();
s_WorldCacheFile = MaxTStrToUtf8(_Ip->GetCurFileName());
}
// Get time // Get time
TimeValue tvTime = _Ip->GetTime(); TimeValue tvTime = _Ip->GetTime();
@ -443,6 +489,20 @@ void CRTWorld::getAllNodeInScene (vector< CMesh::CMeshBuild* > &Meshes,
vector<SLightBuild> &AllLights, const set<INode*> &excludeNode, vector<SLightBuild> &AllLights, const set<INode*> &excludeNode,
INode* pNode) INode* pNode)
{ {
if (_Ip->GetRootNode() != s_WorldCacheRoot || MaxTStrToUtf8(_Ip->GetCurFileName()) != s_WorldCacheFile) // FIXME: This breaks repeated exports while the file is open and being changed!!! Not an issue for now
{
// Erase all cached builds
for (std::map<INode *, std::pair<NL3D::CMesh::CMeshBuild *, NL3D::CMeshBase::CMeshBaseBuild *>>::iterator it(s_WorldCache.begin()), end(s_WorldCache.end()); it != end; ++it)
{
delete it->second.first;
delete it->second.second;
}
s_WorldCache.clear();
s_WorldCacheAABBox.clear();
s_WorldCacheRoot = _Ip->GetRootNode();
s_WorldCacheFile = MaxTStrToUtf8(_Ip->GetCurFileName());
}
if( pNode == NULL ) if( pNode == NULL )
pNode = _Ip->GetRootNode(); pNode = _Ip->GetRootNode();

@ -131,6 +131,12 @@ class CRTWorld
//vector<SCubeGrid> cgAccel; // One cube grid by light point or spot //vector<SCubeGrid> cgAccel; // One cube grid by light point or spot
//vector<SDirGrid> dirAccel; // One grid by light (directionnal only) //vector<SDirGrid> dirAccel; // One grid by light (directionnal only)
NLMISC::CVector GlobalTrans; NLMISC::CVector GlobalTrans;
static std::map<INode *, std::pair<NL3D::CMesh::CMeshBuild *, NL3D::CMeshBase::CMeshBaseBuild *>> s_WorldCache;
static std::map<INode *, NLMISC::CAABBox> s_WorldCacheAABBox;
static INode *s_WorldCacheRoot;
static std::string s_WorldCacheFile;
public: public:
CRTWorld (bool errorInDialog, bool view, bool absolutePath, Interface *ip, std::string errorTitle, CExportNel *exp); CRTWorld (bool errorInDialog, bool view, bool absolutePath, Interface *ip, std::string errorTitle, CExportNel *exp);

Loading…
Cancel
Save