Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / 3d / landscapeig_manager.cpp
blob1d56a4785dac3585b1d5b9f4f627f36c61cbe7cf
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "std3d.h"
22 #include "nel/3d/landscapeig_manager.h"
23 #include "nel/3d/scene_user.h"
24 #include "nel/3d/instance_group_user.h"
25 #include "nel/3d/shape.h"
26 #include "nel/misc/common.h"
27 #include "nel/misc/debug.h"
28 #include "nel/misc/path.h"
29 #include "nel/misc/file.h"
30 #include "nel/misc/hierarchical_timer.h"
33 using namespace NLMISC;
34 using namespace std;
36 H_AUTO_DECL ( NL3D_Load_Zone_IG )
37 H_AUTO_DECL ( NL3D_Unload_Zone_IG )
39 #define NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG H_AUTO_USE( NL3D_Load_Zone_IG )
40 #define NL3D_HAUTO_LAND_MNGR_UNLOAD_ZONEIG H_AUTO_USE( NL3D_Unload_Zone_IG )
42 #ifdef DEBUG_NEW
43 #define new DEBUG_NEW
44 #endif
46 namespace NL3D
50 // ***************************************************************************
51 CLandscapeIGManager::CInstanceGroupElement::CInstanceGroupElement(UInstanceGroup *ig, const char *fileName)
53 Ig = ig;
54 AddedToScene = false;
55 if (fileName != NULL)
56 FileName = fileName;
59 // ***************************************************************************
60 void CLandscapeIGManager::CInstanceGroupElement::release()
62 delete Ig;
63 Ig= NULL;
67 // ***************************************************************************
68 CLandscapeIGManager::CLandscapeIGManager()
70 _Scene=NULL;
72 // ***************************************************************************
73 CLandscapeIGManager::~CLandscapeIGManager()
75 // reset should have been called.
76 if(_Scene != NULL)
77 nlwarning ("CLandscapeIGManager not reseted");
79 // ***************************************************************************
80 void CLandscapeIGManager::initIG(UScene *scene, const std::string &igDesc, UDriver *driver, uint selectedTexture,
81 NLMISC::IProgressCallback * /* callBack */)
83 nlassert(scene);
84 _Scene= scene;
86 // Load the file.
87 if(igDesc.empty())
88 return;
90 string igFile = CPath::lookup(igDesc);
92 CIFile file;
94 // Shape to add should be empty !
95 nlassert(_ShapeAdded.empty ());
97 // if loading ok.
98 //if(file.is_open())
99 if (file.open (igFile))
101 char tmpBuff[260];
102 char delimiterBox[] = "\t";
103 // While the end of the file is not reached.
104 while(!file.eof())
106 // Get a line
107 file.getline(tmpBuff, 260);
108 char *token = strtok(tmpBuff, delimiterBox);
109 // create the instance group.
110 if(token != NULL)
112 if( _ZoneInstanceGroupMap.find(token)!=_ZoneInstanceGroupMap.end() )
113 throw Exception("CLandscapeIGManager::initIG() found 2 igs with same name in %s", igFile.c_str());
114 else
116 // create the instanceGroup.
117 UInstanceGroup *ig = UInstanceGroup::createInstanceGroup(token);
118 if (ig)
120 // add it to the map.
121 string tokId= toUpperAscii(string(token));
122 _ZoneInstanceGroupMap[tokId]= CInstanceGroupElement(ig, token);
124 // Add a reference on the shapes
125 CInstanceGroup &_ig = static_cast<CInstanceGroupUser*>(ig)->getInternalIG();
126 CScene &_scene = static_cast<CSceneUser*>(scene)->getScene();
127 uint i;
128 for (i=0; i<_ig.getNumInstance(); i++)
130 // Get the instance name
131 string shapeName;
132 _ig.getShapeName(i, shapeName);
133 if (!shapeName.empty ())
135 if (toLowerAscii(CFile::getExtension(shapeName)) != "pacs_prim")
137 // Insert a new shape ?
138 if (_ShapeAdded.find(shapeName) == _ShapeAdded.end())
140 // Shape present ?
141 CShapeBank *shapeBank = _scene.getShapeBank();
142 IShape *shape = NULL;
143 if (shapeBank->getPresentState (shapeName) == CShapeBank::NotPresent)
144 shapeBank->load (shapeName);
145 if (shapeBank->getPresentState (shapeName) == CShapeBank::Present)
146 shape = shapeBank->addRef(shapeName);
148 // Shape loaded ?
149 if (shape)
151 // Insert the shape
152 CSmartPtr<IShape> *smartPtr = new CSmartPtr<IShape>;
153 *smartPtr = shape;
154 _ShapeAdded.insert (TShapeMap::value_type (shapeName, smartPtr));
156 // Flush the shape
157 IDriver *_driver = static_cast<CDriverUser*>(driver)->getDriver();
158 shape->flushTextures(*_driver, selectedTexture);
165 else
167 nlwarning ("CLandscapeIGManager::initIG() Can't load instance group '%s' in '%s'", token, igFile.c_str());
172 file.close();
174 else
176 nlwarning ("Couldn't load '%s'", igFile.c_str());
179 // ***************************************************************************
180 UInstanceGroup *CLandscapeIGManager::loadZoneIG(const std::string &name)
182 NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG
184 if(name.empty())
185 return NULL;
187 // try to find this InstanceGroup.
188 ItZoneInstanceGroupMap it;
189 it= _ZoneInstanceGroupMap.find( translateName(name) );
191 // if found.
192 if( it!= _ZoneInstanceGroupMap.end() )
194 // if not already added to the scene.
195 if( !it->second.AddedToScene )
197 // add to the scene.
198 if (it->second.Ig != NULL)
200 it->second.Ig->addToScene(*_Scene);
201 it->second.AddedToScene= true;
204 return it->second.Ig;
206 else
208 return NULL;
211 // ***************************************************************************
212 void CLandscapeIGManager::loadArrayZoneIG(const std::vector<std::string> &names, std::vector<UInstanceGroup *> *dest /*= NULL*/)
214 if (dest)
216 dest->clear();
217 dest->reserve(names.size());
219 for(uint i=0; i<names.size(); i++)
221 UInstanceGroup *ig = loadZoneIG(names[i]);
222 if (dest && ig)
224 dest->push_back(ig);
229 // ***************************************************************************
230 void CLandscapeIGManager::unloadArrayZoneIG(const std::vector<std::string> &names)
232 for(uint i=0; i<names.size(); i++)
234 unloadZoneIG(names[i]);
238 // ***************************************************************************
239 void CLandscapeIGManager::unloadZoneIG(const std::string &name)
241 NL3D_HAUTO_LAND_MNGR_UNLOAD_ZONEIG
242 if(name.empty())
243 return;
245 // try to find this InstanceGroup.
246 ItZoneInstanceGroupMap it;
247 it= _ZoneInstanceGroupMap.find( translateName(name) );
249 // if found.
250 if( it!= _ZoneInstanceGroupMap.end() )
252 // if really added to the scene.
253 if( it->second.AddedToScene )
255 // remove from the scene.
256 it->second.Ig->removeFromScene(*_Scene);
257 it->second.AddedToScene= false;
262 // ***************************************************************************
263 bool CLandscapeIGManager::isIGAddedToScene(const std::string &name) const
265 if(name.empty())
266 return false;
268 // try to find this InstanceGroup.
269 ConstItZoneInstanceGroupMap it;
270 it= _ZoneInstanceGroupMap.find( translateName(name) );
272 // if found.
273 if( it!= _ZoneInstanceGroupMap.end() )
274 return it->second.AddedToScene;
275 else
276 return false;
279 // ***************************************************************************
280 UInstanceGroup *CLandscapeIGManager::getIG(const std::string &name) const
282 if(name.empty())
283 return NULL;
285 // try to find this InstanceGroup.
286 ConstItZoneInstanceGroupMap it;
287 it= _ZoneInstanceGroupMap.find( translateName(name) );
289 // if found.
290 if( it!= _ZoneInstanceGroupMap.end() )
291 return it->second.Ig;
292 else
293 return NULL;
297 // ***************************************************************************
298 std::string CLandscapeIGManager::translateName(const std::string &name) const
300 std::string ret;
301 ret= toUpperAscii(name + ".ig");
302 return ret;
306 // ***************************************************************************
307 void CLandscapeIGManager::reset()
309 while( _ZoneInstanceGroupMap.begin() != _ZoneInstanceGroupMap.end() )
311 string name= _ZoneInstanceGroupMap.begin()->first;
312 // first remove from scene
313 unloadZoneIG( name.substr(0, name.find('.')) );
315 // then delete this entry.
316 _ZoneInstanceGroupMap.begin()->second.release();
317 _ZoneInstanceGroupMap.erase(_ZoneInstanceGroupMap.begin());
320 // For all shape reference
321 TShapeMap::iterator ite = _ShapeAdded.begin ();
322 while (ite != _ShapeAdded.end())
324 // Unreference shape
325 CScene &_scene = static_cast<CSceneUser*>(_Scene)->getScene();
326 CSmartPtr<IShape> *smartPtr = (CSmartPtr<IShape> *)(ite->second);
327 IShape *shapeToRelease = *smartPtr;
328 *smartPtr = NULL;
329 _scene.getShapeBank()->release(shapeToRelease);
330 delete smartPtr;
332 // Next
333 ite++;
335 _ShapeAdded.clear ();
337 _Scene=NULL;
341 // ***************************************************************************
342 void CLandscapeIGManager::reloadAllIgs()
344 vector<std::string> bkupIgFileNameList;
345 vector<bool> bkupIgAddedToScene;
347 // First, erase all igs.
348 while( _ZoneInstanceGroupMap.begin() != _ZoneInstanceGroupMap.end() )
350 string name= _ZoneInstanceGroupMap.begin()->first;
352 // bkup the state of this ig.
353 bkupIgFileNameList.push_back(_ZoneInstanceGroupMap.begin()->second.FileName);
354 bkupIgAddedToScene.push_back(_ZoneInstanceGroupMap.begin()->second.AddedToScene);
356 // first remove from scene
357 unloadZoneIG( name.substr(0, name.find('.')) );
359 // then delete this entry.
360 _ZoneInstanceGroupMap.begin()->second.release();
361 _ZoneInstanceGroupMap.erase(_ZoneInstanceGroupMap.begin());
364 // Then reload all Igs.
365 for(uint i=0; i<bkupIgFileNameList.size(); i++)
367 const char *token= bkupIgFileNameList[i].c_str();
368 UInstanceGroup *ig = UInstanceGroup::createInstanceGroup(token);
369 // add it to the map.
370 string tokId= toUpperAscii(token);
371 _ZoneInstanceGroupMap[tokId]= CInstanceGroupElement(ig, token);
373 // If was addedToScene before, re-add to scene now.
374 if(bkupIgAddedToScene[i])
376 loadZoneIG( tokId.substr(0, tokId.find('.')) );
382 // ***************************************************************************
383 void CLandscapeIGManager::getAllIG(std::vector<UInstanceGroup *> &dest) const
385 dest.clear();
386 dest.reserve(_ZoneInstanceGroupMap.size());
387 // add the instances
388 for(TZoneInstanceGroupMap::const_iterator it = _ZoneInstanceGroupMap.begin(); it != _ZoneInstanceGroupMap.end(); ++it)
390 dest.push_back(it->second.Ig);
394 // ***************************************************************************
395 void CLandscapeIGManager::getAllIGWithNames(std::vector<std::pair<UInstanceGroup *, std::string> > &dest) const
397 dest.clear();
398 dest.reserve(_ZoneInstanceGroupMap.size());
399 // add the instances
400 for(TZoneInstanceGroupMap::const_iterator it = _ZoneInstanceGroupMap.begin(); it != _ZoneInstanceGroupMap.end(); ++it)
402 dest.push_back(std::make_pair(it->second.Ig, it->second.FileName));
407 } // NL3D