1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/landscapeig_manager.h"
20 #include "nel/3d/scene_user.h"
21 #include "nel/3d/instance_group_user.h"
22 #include "nel/3d/shape.h"
23 #include "nel/misc/common.h"
24 #include "nel/misc/debug.h"
25 #include "nel/misc/path.h"
26 #include "nel/misc/file.h"
27 #include "nel/misc/hierarchical_timer.h"
30 using namespace NLMISC
;
33 H_AUTO_DECL ( NL3D_Load_Zone_IG
)
34 H_AUTO_DECL ( NL3D_Unload_Zone_IG
)
36 #define NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG H_AUTO_USE( NL3D_Load_Zone_IG )
37 #define NL3D_HAUTO_LAND_MNGR_UNLOAD_ZONEIG H_AUTO_USE( NL3D_Unload_Zone_IG )
47 // ***************************************************************************
48 CLandscapeIGManager::CInstanceGroupElement::CInstanceGroupElement(UInstanceGroup
*ig
, const char *fileName
)
56 // ***************************************************************************
57 void CLandscapeIGManager::CInstanceGroupElement::release()
64 // ***************************************************************************
65 CLandscapeIGManager::CLandscapeIGManager()
69 // ***************************************************************************
70 CLandscapeIGManager::~CLandscapeIGManager()
72 // reset should have been called.
74 nlwarning ("CLandscapeIGManager not reseted");
76 // ***************************************************************************
77 void CLandscapeIGManager::initIG(UScene
*scene
, const std::string
&igDesc
, UDriver
*driver
, uint selectedTexture
,
78 NLMISC::IProgressCallback
* /* callBack */)
87 string igFile
= CPath::lookup(igDesc
);
91 // Shape to add should be empty !
92 nlassert(_ShapeAdded
.empty ());
96 if (file
.open (igFile
))
99 char delimiterBox
[] = "\t";
100 // While the end of the file is not reached.
104 file
.getline(tmpBuff
, 260);
105 char *token
= strtok(tmpBuff
, delimiterBox
);
106 // create the instance group.
109 if( _ZoneInstanceGroupMap
.find(token
)!=_ZoneInstanceGroupMap
.end() )
110 throw Exception("CLandscapeIGManager::initIG() found 2 igs with same name in %s", igFile
.c_str());
113 // create the instanceGroup.
114 UInstanceGroup
*ig
= UInstanceGroup::createInstanceGroup(token
);
117 // add it to the map.
118 string tokId
= toUpperAscii(string(token
));
119 _ZoneInstanceGroupMap
[tokId
]= CInstanceGroupElement(ig
, token
);
121 // Add a reference on the shapes
122 CInstanceGroup
&_ig
= static_cast<CInstanceGroupUser
*>(ig
)->getInternalIG();
123 CScene
&_scene
= static_cast<CSceneUser
*>(scene
)->getScene();
125 for (i
=0; i
<_ig
.getNumInstance(); i
++)
127 // Get the instance name
129 _ig
.getShapeName(i
, shapeName
);
130 if (!shapeName
.empty ())
132 if (toLowerAscii(CFile::getExtension(shapeName
)) != "pacs_prim")
134 // Insert a new shape ?
135 if (_ShapeAdded
.find(shapeName
) == _ShapeAdded
.end())
138 CShapeBank
*shapeBank
= _scene
.getShapeBank();
139 IShape
*shape
= NULL
;
140 if (shapeBank
->getPresentState (shapeName
) == CShapeBank::NotPresent
)
141 shapeBank
->load (shapeName
);
142 if (shapeBank
->getPresentState (shapeName
) == CShapeBank::Present
)
143 shape
= shapeBank
->addRef(shapeName
);
149 CSmartPtr
<IShape
> *smartPtr
= new CSmartPtr
<IShape
>;
151 _ShapeAdded
.insert (TShapeMap::value_type (shapeName
, smartPtr
));
154 IDriver
*_driver
= static_cast<CDriverUser
*>(driver
)->getDriver();
155 shape
->flushTextures(*_driver
, selectedTexture
);
164 nlwarning ("CLandscapeIGManager::initIG() Can't load instance group '%s' in '%s'", token
, igFile
.c_str());
173 nlwarning ("Couldn't load '%s'", igFile
.c_str());
176 // ***************************************************************************
177 UInstanceGroup
*CLandscapeIGManager::loadZoneIG(const std::string
&name
)
179 NL3D_HAUTO_LAND_MNGR_LOAD_ZONEIG
184 // try to find this InstanceGroup.
185 ItZoneInstanceGroupMap it
;
186 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
189 if( it
!= _ZoneInstanceGroupMap
.end() )
191 // if not already added to the scene.
192 if( !it
->second
.AddedToScene
)
195 if (it
->second
.Ig
!= NULL
)
197 it
->second
.Ig
->addToScene(*_Scene
);
198 it
->second
.AddedToScene
= true;
201 return it
->second
.Ig
;
208 // ***************************************************************************
209 void CLandscapeIGManager::loadArrayZoneIG(const std::vector
<std::string
> &names
, std::vector
<UInstanceGroup
*> *dest
/*= NULL*/)
214 dest
->reserve(names
.size());
216 for(uint i
=0; i
<names
.size(); i
++)
218 UInstanceGroup
*ig
= loadZoneIG(names
[i
]);
226 // ***************************************************************************
227 void CLandscapeIGManager::unloadArrayZoneIG(const std::vector
<std::string
> &names
)
229 for(uint i
=0; i
<names
.size(); i
++)
231 unloadZoneIG(names
[i
]);
235 // ***************************************************************************
236 void CLandscapeIGManager::unloadZoneIG(const std::string
&name
)
238 NL3D_HAUTO_LAND_MNGR_UNLOAD_ZONEIG
242 // try to find this InstanceGroup.
243 ItZoneInstanceGroupMap it
;
244 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
247 if( it
!= _ZoneInstanceGroupMap
.end() )
249 // if really added to the scene.
250 if( it
->second
.AddedToScene
)
252 // remove from the scene.
253 it
->second
.Ig
->removeFromScene(*_Scene
);
254 it
->second
.AddedToScene
= false;
259 // ***************************************************************************
260 bool CLandscapeIGManager::isIGAddedToScene(const std::string
&name
) const
265 // try to find this InstanceGroup.
266 ConstItZoneInstanceGroupMap it
;
267 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
270 if( it
!= _ZoneInstanceGroupMap
.end() )
271 return it
->second
.AddedToScene
;
276 // ***************************************************************************
277 UInstanceGroup
*CLandscapeIGManager::getIG(const std::string
&name
) const
282 // try to find this InstanceGroup.
283 ConstItZoneInstanceGroupMap it
;
284 it
= _ZoneInstanceGroupMap
.find( translateName(name
) );
287 if( it
!= _ZoneInstanceGroupMap
.end() )
288 return it
->second
.Ig
;
294 // ***************************************************************************
295 std::string
CLandscapeIGManager::translateName(const std::string
&name
) const
298 ret
= toUpperAscii(name
+ ".ig");
303 // ***************************************************************************
304 void CLandscapeIGManager::reset()
306 while( _ZoneInstanceGroupMap
.begin() != _ZoneInstanceGroupMap
.end() )
308 string name
= _ZoneInstanceGroupMap
.begin()->first
;
309 // first remove from scene
310 unloadZoneIG( name
.substr(0, name
.find('.')) );
312 // then delete this entry.
313 _ZoneInstanceGroupMap
.begin()->second
.release();
314 _ZoneInstanceGroupMap
.erase(_ZoneInstanceGroupMap
.begin());
317 // For all shape reference
318 TShapeMap::iterator ite
= _ShapeAdded
.begin ();
319 while (ite
!= _ShapeAdded
.end())
322 CScene
&_scene
= static_cast<CSceneUser
*>(_Scene
)->getScene();
323 CSmartPtr
<IShape
> *smartPtr
= (CSmartPtr
<IShape
> *)(ite
->second
);
324 IShape
*shapeToRelease
= *smartPtr
;
326 _scene
.getShapeBank()->release(shapeToRelease
);
332 _ShapeAdded
.clear ();
338 // ***************************************************************************
339 void CLandscapeIGManager::reloadAllIgs()
341 vector
<std::string
> bkupIgFileNameList
;
342 vector
<bool> bkupIgAddedToScene
;
344 // First, erase all igs.
345 while( _ZoneInstanceGroupMap
.begin() != _ZoneInstanceGroupMap
.end() )
347 string name
= _ZoneInstanceGroupMap
.begin()->first
;
349 // bkup the state of this ig.
350 bkupIgFileNameList
.push_back(_ZoneInstanceGroupMap
.begin()->second
.FileName
);
351 bkupIgAddedToScene
.push_back(_ZoneInstanceGroupMap
.begin()->second
.AddedToScene
);
353 // first remove from scene
354 unloadZoneIG( name
.substr(0, name
.find('.')) );
356 // then delete this entry.
357 _ZoneInstanceGroupMap
.begin()->second
.release();
358 _ZoneInstanceGroupMap
.erase(_ZoneInstanceGroupMap
.begin());
361 // Then reload all Igs.
362 for(uint i
=0; i
<bkupIgFileNameList
.size(); i
++)
364 const char *token
= bkupIgFileNameList
[i
].c_str();
365 UInstanceGroup
*ig
= UInstanceGroup::createInstanceGroup(token
);
366 // add it to the map.
367 string tokId
= toUpperAscii(token
);
368 _ZoneInstanceGroupMap
[tokId
]= CInstanceGroupElement(ig
, token
);
370 // If was addedToScene before, re-add to scene now.
371 if(bkupIgAddedToScene
[i
])
373 loadZoneIG( tokId
.substr(0, tokId
.find('.')) );
379 // ***************************************************************************
380 void CLandscapeIGManager::getAllIG(std::vector
<UInstanceGroup
*> &dest
) const
383 dest
.reserve(_ZoneInstanceGroupMap
.size());
385 for(TZoneInstanceGroupMap::const_iterator it
= _ZoneInstanceGroupMap
.begin(); it
!= _ZoneInstanceGroupMap
.end(); ++it
)
387 dest
.push_back(it
->second
.Ig
);
391 // ***************************************************************************
392 void CLandscapeIGManager::getAllIGWithNames(std::vector
<std::pair
<UInstanceGroup
*, std::string
> > &dest
) const
395 dest
.reserve(_ZoneInstanceGroupMap
.size());
397 for(TZoneInstanceGroupMap::const_iterator it
= _ZoneInstanceGroupMap
.begin(); it
!= _ZoneInstanceGroupMap
.end(); ++it
)
399 dest
.push_back(std::make_pair(it
->second
.Ig
, it
->second
.FileName
));