// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "std3d.h" #include "nel/3d/landscapeig_manager.h" #include "nel/3d/scene_user.h" #include "nel/3d/instance_group_user.h" #include "nel/3d/shape.h" #include "nel/misc/common.h" #include "nel/misc/debug.h" #include "nel/misc/path.h" #include "nel/misc/file.h" #include "nel/misc/hierarchical_timer.h" using namespace NLMISC; using namespace std; H_AUTO_DECL ( NL3D_Load_Zone_IG ) H_AUTO_DECL ( NL3D_Unload_Zone_IG ) #define NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG H_AUTO_USE( NL3D_Load_Zone_IG ) #define NL3D_HAUTO_LAND_MNGR_UNLOAD_ZONEIG H_AUTO_USE( NL3D_Unload_Zone_IG ) namespace NL3D { // *************************************************************************** CLandscapeIGManager::CInstanceGroupElement::CInstanceGroupElement(UInstanceGroup *ig, const char *fileName) { Ig = ig; AddedToScene = false; if (fileName != NULL) FileName = fileName; } // *************************************************************************** void CLandscapeIGManager::CInstanceGroupElement::release() { delete Ig; Ig= NULL; } // *************************************************************************** CLandscapeIGManager::CLandscapeIGManager() { _Scene=NULL; } // *************************************************************************** CLandscapeIGManager::~CLandscapeIGManager() { // reset should have been called. if(_Scene != NULL) nlwarning ("CLandscapeIGManager not reseted"); } // *************************************************************************** void CLandscapeIGManager::initIG(UScene *scene, const std::string &igDesc, UDriver *driver, uint selectedTexture, NLMISC::IProgressCallback * /* callBack */) { nlassert(scene); _Scene= scene; // Load the file. if(igDesc.empty()) return; string igFile = CPath::lookup(igDesc); CIFile file; // Shape to add should be empty ! nlassert(_ShapeAdded.empty ()); // if loading ok. //if(file.is_open()) if (file.open (igFile)) { char tmpBuff[260]; char delimiterBox[] = "\t"; // While the end of the file is not reached. while(!file.eof()) { // Get a line file.getline(tmpBuff, 260); char *token = strtok(tmpBuff, delimiterBox); // create the instance group. if(token != NULL) { if( _ZoneInstanceGroupMap.find(token)!=_ZoneInstanceGroupMap.end() ) throw Exception("CLandscapeIGManager::initIG() found 2 igs with same name in %s", igFile.c_str()); else { // create the instanceGroup. UInstanceGroup *ig = UInstanceGroup::createInstanceGroup(token); if (ig) { // add it to the map. string tokId= toUpper(string(token)); _ZoneInstanceGroupMap[tokId]= CInstanceGroupElement(ig, token); // Add a reference on the shapes CInstanceGroup &_ig = static_cast(ig)->getInternalIG(); CScene &_scene = static_cast(scene)->getScene(); uint i; for (i=0; i<_ig.getNumInstance(); i++) { // Get the instance name string shapeName; _ig.getShapeName(i, shapeName); if (!shapeName.empty ()) { if (toLower(CFile::getExtension(shapeName)) != "pacs_prim") { // Insert a new shape ? if (_ShapeAdded.find(shapeName) == _ShapeAdded.end()) { // Shape present ? CShapeBank *shapeBank = _scene.getShapeBank(); IShape *shape = NULL; if (shapeBank->getPresentState (shapeName) == CShapeBank::NotPresent) shapeBank->load (shapeName); if (shapeBank->getPresentState (shapeName) == CShapeBank::Present) shape = shapeBank->addRef(shapeName); // Shape loaded ? if (shape) { // Insert the shape CSmartPtr *smartPtr = new CSmartPtr; *smartPtr = shape; _ShapeAdded.insert (TShapeMap::value_type (shapeName, smartPtr)); // Flush the shape IDriver *_driver = static_cast(driver)->getDriver(); shape->flushTextures(*_driver, selectedTexture); } } } } } } else { nlwarning ("CLandscapeIGManager::initIG() Can't load instance group '%s' in '%s'", token, igFile.c_str()); } } } } file.close(); } else { nlwarning ("Couldn't load '%s'", igFile.c_str()); } } // *************************************************************************** UInstanceGroup *CLandscapeIGManager::loadZoneIG(const std::string &name) { NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG if(name.empty()) return NULL; // try to find this InstanceGroup. ItZoneInstanceGroupMap it; it= _ZoneInstanceGroupMap.find( translateName(name) ); // if found. if( it!= _ZoneInstanceGroupMap.end() ) { // if not already added to the scene. if( !it->second.AddedToScene ) { // add to the scene. if (it->second.Ig != NULL) { it->second.Ig->addToScene(*_Scene); it->second.AddedToScene= true; } } return it->second.Ig; } else { return NULL; } } // *************************************************************************** void CLandscapeIGManager::loadArrayZoneIG(const std::vector &names, std::vector *dest /*= NULL*/) { if (dest) { dest->clear(); dest->reserve(names.size()); } for(uint i=0; ipush_back(ig); } } } // *************************************************************************** void CLandscapeIGManager::unloadArrayZoneIG(const std::vector &names) { for(uint i=0; isecond.AddedToScene ) { // remove from the scene. it->second.Ig->removeFromScene(*_Scene); it->second.AddedToScene= false; } } } // *************************************************************************** bool CLandscapeIGManager::isIGAddedToScene(const std::string &name) const { if(name.empty()) return false; // try to find this InstanceGroup. ConstItZoneInstanceGroupMap it; it= _ZoneInstanceGroupMap.find( translateName(name) ); // if found. if( it!= _ZoneInstanceGroupMap.end() ) return it->second.AddedToScene; else return false; } // *************************************************************************** UInstanceGroup *CLandscapeIGManager::getIG(const std::string &name) const { if(name.empty()) return NULL; // try to find this InstanceGroup. ConstItZoneInstanceGroupMap it; it= _ZoneInstanceGroupMap.find( translateName(name) ); // if found. if( it!= _ZoneInstanceGroupMap.end() ) return it->second.Ig; else return NULL; } // *************************************************************************** std::string CLandscapeIGManager::translateName(const std::string &name) const { std::string ret; ret= toUpper(name + ".ig"); return ret; } // *************************************************************************** void CLandscapeIGManager::reset() { while( _ZoneInstanceGroupMap.begin() != _ZoneInstanceGroupMap.end() ) { string name= _ZoneInstanceGroupMap.begin()->first; // first remove from scene unloadZoneIG( name.substr(0, name.find('.')) ); // then delete this entry. _ZoneInstanceGroupMap.begin()->second.release(); _ZoneInstanceGroupMap.erase(_ZoneInstanceGroupMap.begin()); } // For all shape reference TShapeMap::iterator ite = _ShapeAdded.begin (); while (ite != _ShapeAdded.end()) { // Unreference shape CScene &_scene = static_cast(_Scene)->getScene(); CSmartPtr *smartPtr = (CSmartPtr *)(ite->second); IShape *shapeToRelease = *smartPtr; *smartPtr = NULL; _scene.getShapeBank()->release(shapeToRelease); delete smartPtr; // Next ite++; } _ShapeAdded.clear (); _Scene=NULL; } // *************************************************************************** void CLandscapeIGManager::reloadAllIgs() { vector bkupIgFileNameList; vector bkupIgAddedToScene; // First, erase all igs. while( _ZoneInstanceGroupMap.begin() != _ZoneInstanceGroupMap.end() ) { string name= _ZoneInstanceGroupMap.begin()->first; // bkup the state of this ig. bkupIgFileNameList.push_back(_ZoneInstanceGroupMap.begin()->second.FileName); bkupIgAddedToScene.push_back(_ZoneInstanceGroupMap.begin()->second.AddedToScene); // first remove from scene unloadZoneIG( name.substr(0, name.find('.')) ); // then delete this entry. _ZoneInstanceGroupMap.begin()->second.release(); _ZoneInstanceGroupMap.erase(_ZoneInstanceGroupMap.begin()); } // Then reload all Igs. for(uint i=0; i &dest) const { dest.clear(); dest.reserve(_ZoneInstanceGroupMap.size()); // add the instances for(TZoneInstanceGroupMap::const_iterator it = _ZoneInstanceGroupMap.begin(); it != _ZoneInstanceGroupMap.end(); ++it) { dest.push_back(it->second.Ig); } } // *************************************************************************** void CLandscapeIGManager::getAllIGWithNames(std::vector > &dest) const { dest.clear(); dest.reserve(_ZoneInstanceGroupMap.size()); // add the instances for(TZoneInstanceGroupMap::const_iterator it = _ZoneInstanceGroupMap.begin(); it != _ZoneInstanceGroupMap.end(); ++it) { dest.push_back(std::make_pair(it->second.Ig, it->second.FileName)); } } } // NL3D