bool EntityManager::MakeEntityTree(BSPTree* pSrcBSPTree) { // Reset(); vector<EntityNode> entity_tree; // allocate some memory in advance // not doing this may cause error in Release build entity_tree.reserve( 10000 ); // create the new entity tree on the temporary node buffer entity_tree // - Do not copy the tree to m_paEntityTree until all the entities are unlinked MakeEntityNode_r(0, pSrcBSPTree, &entity_tree); if(entity_tree.size() == 0) return false; // entity tree costruction failed entity_tree[0].sParent = -1; // the root node has no parent // unlink all the entities from the current entity tree if( m_pEntityInUse ) { for( CCopyEntity* pEntity = m_pEntityInUse.get(); pEntity != NULL; pEntity = pEntity->m_pNextRawPtr ) { pEntity->Unlink(); } } // Do this AFTER all the entities are unlinked from the entity nodes SafeDeleteArray( m_paEntityTree ); // copy the new tree m_NumEntityNodes = (int)entity_tree.size(); m_paEntityTree = new EntityNode [ m_NumEntityNodes ]; for(int i=0; i<m_NumEntityNodes; i++) m_paEntityTree[i] = entity_tree[i]; entity_tree.clear(); // set stage and entity set for(int i=0; i<m_NumEntityNodes; i++) { m_paEntityTree[i].m_pStage = m_pStage; m_paEntityTree[i].m_pEntitySet = this; } // update entity tree of the render manager m_pRenderManager->UpdateEntityTree( m_paEntityTree, m_NumEntityNodes ); WriteEntityTreeToFile( "debug/entity_tree - recreated the tree.txt" ); // re-link all the entities to the new tree nodes if( m_pEntityInUse ) { for( CCopyEntity* pEntity = m_pEntityInUse.get(); pEntity != NULL; pEntity = pEntity->m_pNextRawPtr ) { // added: 11:34 PM 5/25/2008 // Do not re-link an entity if it has already been marked as 'not in use' // - Failure to do this leads to an invalid link in the entity tree node // - Caused infinite loops in EntityNode::CheckPosition_r() if( !IsValidEntity( pEntity ) ) continue; Link( pEntity ); } } WriteEntityTreeToFile( "debug/entity_tree - re-linked entities to the tree.txt" ); // re-link all the light entities to the new tree nodes // m_pLightEntityManager->RelinkLightEntities(); return true; }