1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
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
;
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 )
50 // ***************************************************************************
51 CLandscapeIGManager::CInstanceGroupElement::CInstanceGroupElement(UInstanceGroup
*ig
, const char *fileName
)
59 // ***************************************************************************
60 void CLandscapeIGManager::CInstanceGroupElement::release()
67 // ***************************************************************************
68 CLandscapeIGManager::CLandscapeIGManager()
72 // ***************************************************************************
73 CLandscapeIGManager::~CLandscapeIGManager()
75 // reset should have been called.
77 nlwarning ("CLandscapeIGManager not reseted");
79 // ***************************************************************************
80 void CLandscapeIGManager::initIG(UScene
*scene
, const std::string
&igDesc
, UDriver
*driver
, uint selectedTexture
,
81 NLMISC::IProgressCallback
* /* callBack */)
90 string igFile
= CPath::lookup(igDesc
);
94 // Shape to add should be empty !
95 nlassert(_ShapeAdded
.empty ());
99 if (file
.open (igFile
))
102 char delimiterBox
[] = "\t";
103 // While the end of the file is not reached.
107 file
.getline(tmpBuff
, 260);
108 char *token
= strtok(tmpBuff
, delimiterBox
);
109 // create the instance group.
112 if( _ZoneInstanceGroupMap
.find(token
)!=_ZoneInstanceGroupMap
.end() )
113 throw Exception("CLandscapeIGManager::initIG() found 2 igs with same name in %s", igFile
.c_str());
116 // create the instanceGroup.
117 UInstanceGroup
*ig
= UInstanceGroup::createInstanceGroup(token
);
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();
128 for (i
=0; i
<_ig
.getNumInstance(); i
++)
130 // Get the instance name
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())
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
);
152 CSmartPtr
<IShape
> *smartPtr
= new CSmartPtr
<IShape
>;
154 _ShapeAdded
.insert (TShapeMap::value_type (shapeName
, smartPtr
));
157 IDriver
*_driver
= static_cast<CDriverUser
*>(driver
)->getDriver();
158 shape
->flushTextures(*_driver
, selectedTexture
);
167 nlwarning ("CLandscapeIGManager::initIG() Can't load instance group '%s' in '%s'", token
, igFile
.c_str());
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
187 // try to find this InstanceGroup.
188 ItZoneInstanceGroupMap it
;
189 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
192 if( it
!= _ZoneInstanceGroupMap
.end() )
194 // if not already added to the scene.
195 if( !it
->second
.AddedToScene
)
198 if (it
->second
.Ig
!= NULL
)
200 it
->second
.Ig
->addToScene(*_Scene
);
201 it
->second
.AddedToScene
= true;
204 return it
->second
.Ig
;
211 // ***************************************************************************
212 void CLandscapeIGManager::loadArrayZoneIG(const std::vector
<std::string
> &names
, std::vector
<UInstanceGroup
*> *dest
/*= NULL*/)
217 dest
->reserve(names
.size());
219 for(uint i
=0; i
<names
.size(); i
++)
221 UInstanceGroup
*ig
= loadZoneIG(names
[i
]);
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
245 // try to find this InstanceGroup.
246 ItZoneInstanceGroupMap it
;
247 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
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
268 // try to find this InstanceGroup.
269 ConstItZoneInstanceGroupMap it
;
270 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
273 if( it
!= _ZoneInstanceGroupMap
.end() )
274 return it
->second
.AddedToScene
;
279 // ***************************************************************************
280 UInstanceGroup
*CLandscapeIGManager::getIG(const std::string
&name
) const
285 // try to find this InstanceGroup.
286 ConstItZoneInstanceGroupMap it
;
287 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
290 if( it
!= _ZoneInstanceGroupMap
.end() )
291 return it
->second
.Ig
;
297 // ***************************************************************************
298 std::string
CLandscapeIGManager::translateName(const std::string
&name
) const
301 ret
= toUpperAscii(name
+ ".ig");
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())
325 CScene
&_scene
= static_cast<CSceneUser
*>(_Scene
)->getScene();
326 CSmartPtr
<IShape
> *smartPtr
= (CSmartPtr
<IShape
> *)(ite
->second
);
327 IShape
*shapeToRelease
= *smartPtr
;
329 _scene
.getShapeBank()->release(shapeToRelease
);
335 _ShapeAdded
.clear ();
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
386 dest
.reserve(_ZoneInstanceGroupMap
.size());
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
398 dest
.reserve(_ZoneInstanceGroupMap
.size());
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
));