Change Encyclo button name and macros icon
[ryzomcore.git] / nel / src / 3d / instance_group_user.cpp
blob536e14e94ba4deed549db9865b5373f19e282388
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
17 #include "std3d.h"
19 #include "nel/misc/debug.h"
20 #include "nel/3d/instance_group_user.h"
21 #include "nel/3d/scene_user.h"
22 #include "nel/3d/mesh_multi_lod_instance.h"
23 #include "nel/3d/text_context_user.h"
24 #include "nel/3d/particle_system_model.h"
25 #include "nel/misc/path.h"
26 #include "nel/misc/file.h"
27 #include "nel/3d/u_instance.h"
29 using namespace NLMISC;
30 using namespace std;
32 #ifdef DEBUG_NEW
33 #define new DEBUG_NEW
34 #endif
36 namespace NL3D
39 // ***************************************************************************
41 UInstanceGroup *UInstanceGroup::createInstanceGroup (const std::string &instanceGroup)
43 // Create the instance group
44 CInstanceGroupUser *user=new CInstanceGroupUser;
46 // Init the class
47 if (!user->init (instanceGroup))
49 // Prb, erase it
50 delete user;
52 // Return error code
53 return NULL;
56 // return the good value
57 return user;
60 // ***************************************************************************
62 void UInstanceGroup::createInstanceGroupAsync (const std::string &instanceGroup, UInstanceGroup **pIG)
64 CAsyncFileManager3D::getInstance().loadIGUser (instanceGroup, pIG);
67 // ***************************************************************************
69 void UInstanceGroup::stopCreateInstanceGroupAsync (UInstanceGroup **ppIG)
71 // Theorically should stop the async file manager but the async file manager can only be stopped
72 // between tasks (a file reading) so that is no sense to do anything here
73 while (*ppIG == NULL)
75 nlSleep (2);
77 if (*ppIG != (UInstanceGroup*)-1)
79 delete *ppIG;
83 // ***************************************************************************
84 CInstanceGroupUser::CInstanceGroupUser()
86 /* ***********************************************
87 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
88 * It can be loaded/called through CAsyncFileManager for instance
89 * ***********************************************/
91 _AddToSceneState = StateNotAdded;
93 // set user info for possible get
94 _InstanceGroup.setUserInterface(this);
97 // ***************************************************************************
98 CInstanceGroupUser::~CInstanceGroupUser()
100 /* ***********************************************
101 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
102 * It can be loaded/called through CAsyncFileManager for instance
103 * ***********************************************/
105 // ensure all instances proxys are deleted
106 removeInstancesUser();
109 // ***************************************************************************
110 bool CInstanceGroupUser::init (const std::string &instanceGroup, bool async)
112 // Create a file
113 CIFile file;
114 if(async)
116 file.setAsyncLoading(true);
117 file.setCacheFileOnOpen(true);
119 std::string path = CPath::lookup (instanceGroup, false);
120 if (!path.empty() && file.open (path))
122 // Serialize this class
125 // Read the class
126 _InstanceGroup.serial (file);
128 catch (const EStream& e)
130 // Avoid visual warning
131 EStream ee=e;
133 // Serial problem
134 return false;
137 else
139 // Failed.
140 return false;
143 // Ok
144 return true;
147 // ***************************************************************************
148 void CInstanceGroupUser::setTransformNameCallback (ITransformName *pTN)
150 _InstanceGroup.setTransformNameCallback (pTN);
154 // ***************************************************************************
155 void CInstanceGroupUser::setAddRemoveInstanceCallback(IAddRemoveInstance *callback)
157 _InstanceGroup.setAddRemoveInstanceCallback(callback);
161 // ***************************************************************************
162 void CInstanceGroupUser::setIGAddBeginCallback(IIGAddBegin *callback)
164 _InstanceGroup.setIGAddBeginCallback(callback);
169 // ***************************************************************************
170 void CInstanceGroupUser::addToScene (class UScene& scene, UDriver *driver, uint selectedTexture)
172 // Get driver pointer
173 IDriver *cDriver= driver ? NLMISC::safe_cast<CDriverUser*>(driver)->getDriver() : NULL;
175 // Add to the scene
176 addToScene (((CSceneUser*)&scene)->getScene(), cDriver, selectedTexture);
179 // ***************************************************************************
180 void CInstanceGroupUser::getInstanceMatrix(uint instanceNb,NLMISC::CMatrix &dest) const
182 _InstanceGroup.getInstanceMatrix(instanceNb, dest);
186 // ***************************************************************************
187 void CInstanceGroupUser::addToScene (class CScene& scene, IDriver *driver, uint selectedTexture)
189 if (!_InstanceGroup.addToScene (scene, driver, selectedTexture))
190 return;
191 // Fill in the vector and the map accelerating search of instance by names
192 for( uint32 i = 0; i < _InstanceGroup._Instances.size(); ++i)
194 string stmp;
195 if (_InstanceGroup._Instances[i] != NULL)
197 // insert in map (may fail if double name)
198 stmp = _InstanceGroup.getInstanceName (i);
199 _InstanceMap.insert (map<string,CTransformShape*>::value_type(stmp, _InstanceGroup._Instances[i]));
204 // ***************************************************************************
205 void CInstanceGroupUser::addToSceneAsync (class UScene& scene, UDriver *driver, uint selectedTexture)
207 IDriver *cDriver= driver ? NLMISC::safe_cast<CDriverUser*>(driver)->getDriver() : NULL;
208 // Add to the scene
209 _InstanceGroup.addToSceneAsync (((CSceneUser*)&scene)->getScene(), cDriver, selectedTexture);
210 _AddToSceneState = StateAdding;
211 _AddToSceneTempScene = &scene;
212 _AddToSceneTempDriver = driver;
215 // ***************************************************************************
216 void CInstanceGroupUser::stopAddToSceneAsync ()
218 _InstanceGroup.stopAddToSceneAsync ();
221 // ***************************************************************************
222 UInstanceGroup::TState CInstanceGroupUser::getAddToSceneState ()
224 UInstanceGroup::TState newState = (UInstanceGroup::TState)_InstanceGroup.getAddToSceneState ();
225 if ((_AddToSceneState == StateAdding) && (newState == StateAdded))
227 // Fill in the vector and the map accelerating search of instance by names
228 for( uint32 i = 0; i < _InstanceGroup._Instances.size(); ++i)
230 string stmp;
231 if (_InstanceGroup._Instances[i] != NULL)
233 // create but don't want to delete from scene, since added/removed with _InstanceGroup
234 // insert in map (may fail if double name)
235 stmp = _InstanceGroup.getInstanceName (i);
236 _InstanceMap.insert (map<string,CTransformShape*>::value_type(stmp, _InstanceGroup._Instances[i]));
239 _AddToSceneState = StateAdded;
241 return newState;
244 // ***************************************************************************
245 void CInstanceGroupUser::removeFromScene (class UScene& scene)
247 _InstanceGroup.removeFromScene (((CSceneUser*)&scene)->getScene());
248 // Remove all instance user object in the array/map
249 removeInstancesUser();
252 // ***************************************************************************
253 uint CInstanceGroupUser::getNumInstance () const
255 return _InstanceGroup.getNumInstance ();
258 // ***************************************************************************
260 const std::string& CInstanceGroupUser::getShapeName (uint instanceNb) const
262 // Check args
263 if (instanceNb>=_InstanceGroup.getNumInstance ())
264 nlerror("getShapeName*(): bad instance Id");
266 return _InstanceGroup.getShapeName (instanceNb);
269 // ***************************************************************************
270 const std::string& CInstanceGroupUser::getInstanceName (uint instanceNb) const
272 // Check args
273 if (instanceNb>=_InstanceGroup.getNumInstance ())
274 nlerror("getInstanceName*(): bad instance Id");
276 return _InstanceGroup.getInstanceName (instanceNb);
279 // ***************************************************************************
280 const NLMISC::CVector& CInstanceGroupUser::getInstancePos (uint instanceNb) const
282 // Check args
283 if (instanceNb>=_InstanceGroup.getNumInstance ())
284 nlerror("getInstancePos*(): bad instance Id");
286 return _InstanceGroup.getInstancePos (instanceNb);
289 // ***************************************************************************
290 const NLMISC::CQuat& CInstanceGroupUser::getInstanceRot (uint instanceNb) const
292 // Check args
293 if (instanceNb>=_InstanceGroup.getNumInstance ())
294 nlerror("getInstanceRot*(): bad instance Id");
296 return _InstanceGroup.getInstanceRot (instanceNb);
299 // ***************************************************************************
300 const NLMISC::CVector& CInstanceGroupUser::getInstanceScale (uint instanceNb) const
302 // Check args
303 if (instanceNb>=_InstanceGroup.getNumInstance ())
304 nlerror("getInstanceScale*(): bad instance Id");
306 return _InstanceGroup.getInstanceScale (instanceNb);
309 // ***************************************************************************
311 UInstance CInstanceGroupUser::getByName (const std::string &name) const
313 map<string,CTransformShape*>::const_iterator it = _InstanceMap.find (name);
314 if (it != _InstanceMap.end())
315 return UInstance (it->second);
316 else
317 return UInstance ();
320 // ***************************************************************************
321 sint CInstanceGroupUser::getIndexByName(const std::string &name) const
323 map<string,CTransformShape*>::const_iterator it = _InstanceMap.find (name);
324 if (it == _InstanceMap.end()) return -1;
325 for(uint k = 0; k < _InstanceGroup._Instances.size(); ++k)
327 if (_InstanceGroup._Instances[k] == it->second) return (sint) k;
329 return -1;
333 // ***************************************************************************
334 void CInstanceGroupUser::setBlendShapeFactor (const std::string &bsName, float rFactor)
336 _InstanceGroup.setBlendShapeFactor (bsName, rFactor);
339 // ***************************************************************************
341 void CInstanceGroupUser::createRoot (UScene &scene)
343 _InstanceGroup.createRoot (((CSceneUser*)&scene)->getScene());
346 // ***************************************************************************
347 void CInstanceGroupUser::setClusterSystemForInstances (UInstanceGroup *pClusterSystem)
349 _InstanceGroup.setClusterSystemForInstances (&((CInstanceGroupUser*)pClusterSystem)->_InstanceGroup);
352 // ***************************************************************************
353 bool CInstanceGroupUser::linkToParentCluster(UInstanceGroup *father)
355 if (father)
356 return _InstanceGroup.linkToParent(&(NLMISC::safe_cast<CInstanceGroupUser *>(father)->_InstanceGroup));
357 else
359 nlwarning("Trying to link a cluster system to a NULL parent cluster");
360 return false;
364 // ***************************************************************************
365 void CInstanceGroupUser::getDynamicPortals (std::vector<std::string> &names)
367 _InstanceGroup.getDynamicPortals (names);
370 // ***************************************************************************
371 void CInstanceGroupUser::setDynamicPortal (std::string& name, bool opened)
373 _InstanceGroup.setDynamicPortal (name, opened);
376 // ***************************************************************************
377 bool CInstanceGroupUser::getDynamicPortal (std::string& name)
379 return _InstanceGroup.getDynamicPortal (name);
382 // ***************************************************************************
383 void CInstanceGroupUser::setPos (const NLMISC::CVector &pos)
385 _InstanceGroup.setPos (pos);
388 // ***************************************************************************
389 void CInstanceGroupUser::setRotQuat (const NLMISC::CQuat &q)
391 _InstanceGroup.setRotQuat (q);
394 // ***************************************************************************
395 CVector CInstanceGroupUser::getPos ()
397 return _InstanceGroup.getPos ();
400 // ***************************************************************************
401 CQuat CInstanceGroupUser::getRotQuat ()
403 return _InstanceGroup.getRotQuat();
407 // ***************************************************************************
408 void CInstanceGroupUser::freezeHRC()
410 _InstanceGroup.freezeHRC();
413 // ***************************************************************************
414 void CInstanceGroupUser::unfreezeHRC()
416 _InstanceGroup.unfreezeHRC();
420 // ***************************************************************************
421 bool CInstanceGroupUser::getStaticLightSetup(NLMISC::CRGBA sunAmbient,
422 uint retrieverIdentifier, sint surfaceId, const NLMISC::CVector &localPos,
423 std::vector<CPointLightInfluence> &pointLightList, uint8 &sunContribution, NLMISC::CRGBA &localAmbient)
425 return _InstanceGroup.getStaticLightSetup(sunAmbient, retrieverIdentifier, surfaceId, localPos, pointLightList,
426 sunContribution, localAmbient);
429 // ***************************************************************************
430 /*virtual*/ void CInstanceGroupUser::setDistMax(uint instance, float dist)
432 if (instance > _InstanceGroup.getNumInstance())
434 nlwarning("CInstanceGroupUser::setDistMax : instance index %d is invalid", instance);
435 return;
437 if (_InstanceGroup._Instances[instance]) _InstanceGroup._Instances[instance]->setDistMax(dist);
440 // ***************************************************************************
441 /*virtual*/ float CInstanceGroupUser::getDistMax(uint instance) const
443 if (instance > _InstanceGroup.getNumInstance())
445 nlwarning("CInstanceGroupUser::getDistMax : instance index %d is invalid", instance);
446 return -1.f;
448 if (_InstanceGroup._Instances[instance]) return _InstanceGroup._Instances[instance]->getDistMax();
449 else return -1.f;
452 // ***************************************************************************
453 /*virtual*/ void CInstanceGroupUser::setCoarseMeshDist(uint instance, float dist)
455 if (instance > _InstanceGroup.getNumInstance())
457 nlwarning("CInstanceGroupUser::setCoarseMeshDist : instance index %d is invalid", instance);
458 return;
460 if (_InstanceGroup._Instances[instance])
462 CMeshMultiLodInstance *mmli = dynamic_cast<CMeshMultiLodInstance *>(_InstanceGroup._Instances[instance]);
463 if (mmli) mmli->setCoarseMeshDist(dist);
467 // ***************************************************************************
468 /*virtual*/ float CInstanceGroupUser::getCoarseMeshDist(uint instance) const
470 if (instance > _InstanceGroup.getNumInstance())
472 nlwarning("getCoarseMeshDist::getDistMax : instance index %d is invalid", instance);
473 return -1.f;
475 if (_InstanceGroup._Instances[instance])
477 CMeshMultiLodInstance *mmli = dynamic_cast<CMeshMultiLodInstance *>(_InstanceGroup._Instances[instance]);
478 if (mmli) return mmli->getCoarseMeshDist();
479 else return -1.f;
481 else return -1.f;
484 // ***************************************************************************
485 UInstance CInstanceGroupUser::getInstance (uint instanceNb) const
487 if(instanceNb<_InstanceGroup._Instances.size())
488 return UInstance (_InstanceGroup._Instances[instanceNb]);
489 else
490 return UInstance ();
493 // ***************************************************************************
494 void CInstanceGroupUser::removeInstancesUser()
496 /* ***********************************************
497 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
498 * It can be loaded/called through CAsyncFileManager for instance
499 * ***********************************************/
501 // clear the array and the map
502 _InstanceMap.clear();
505 // ***************************************************************************
506 UInstanceGroup *CInstanceGroupUser::getParentCluster() const
508 CInstanceGroup *parent= _InstanceGroup.getParentClusterSystem();
509 if(parent)
510 // NB: return NULL if this is the GlobalInstanceGroup.
511 return parent->getUserInterface();
512 else
513 return NULL;
516 // ***************************************************************************
517 void CInstanceGroupUser::displayDebugClusters(UDriver *drv, UTextContext *txtCtx)
519 if(!drv)
520 return;
521 CTextContext *pTxtCtx= NULL;
522 if(txtCtx)
523 pTxtCtx= &((CTextContextUser*)txtCtx)->getTextContext();
524 _InstanceGroup.displayDebugClusters(((CDriverUser*)drv)->getDriver(), pTxtCtx);
526 // restore the matrix context cause of font rendering
527 ((CDriverUser*)drv)->restoreMatrixContext();
530 // ***************************************************************************
531 bool CInstanceGroupUser::dontCastShadowForInterior(uint instance) const
533 if (instance>=_InstanceGroup.getNumInstance ())
534 return false;
535 return _InstanceGroup.getInstance(instance).DontCastShadowForInterior;
538 // ***************************************************************************
539 bool CInstanceGroupUser::dontCastShadowForExterior(uint instance) const
541 if (instance>=_InstanceGroup.getNumInstance ())
542 return false;
543 return _InstanceGroup.getInstance(instance).DontCastShadowForExterior;
547 } // NL3D