00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/scene_group.h"
00029 #include "nel/misc/stream.h"
00030 #include "nel/misc/matrix.h"
00031 #include "3d/scene.h"
00032 #include "3d/transform_shape.h"
00033 #include "3d/mesh_instance.h"
00034 #include "3d/shape_bank.h"
00035 #include "nel/3d/u_instance_group.h"
00036
00037 using namespace NLMISC;
00038 using namespace std;
00039
00040 namespace NL3D
00041 {
00042
00043
00044
00045
00046
00047
00048 CInstanceGroup::CInstance::CInstance ()
00049 {
00050 DontAddToScene = false;
00051 AvoidStaticLightPreCompute= false;
00052 StaticLightEnabled= false;
00053 DontCastShadow= false;
00054 LocalAmbientId= 0xFF;
00055 }
00056
00057
00058 void CInstanceGroup::CInstance::serial (NLMISC::IStream& f)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 sint version=f.serialVersion (4);
00072
00073
00074
00075 if (version >= 4)
00076 {
00077 f.serial(LocalAmbientId);
00078 }
00079 else if(f.isReading())
00080 {
00081 LocalAmbientId= 0xFF;
00082 }
00083
00084
00085 if (version >= 3)
00086 {
00087 f.serial (AvoidStaticLightPreCompute);
00088 f.serial (DontCastShadow);
00089 f.serial (StaticLightEnabled);
00090 f.serial (SunContribution);
00091 nlassert(CInstanceGroup::NumStaticLightPerInstance==2);
00092 f.serial (Light[0]);
00093 f.serial (Light[1]);
00094 }
00095 else if(f.isReading())
00096 {
00097 AvoidStaticLightPreCompute= false;
00098 StaticLightEnabled= false;
00099 DontCastShadow= false;
00100 }
00101
00102
00103 if (version >= 2)
00104 {
00105 f.serial (InstanceName);
00106 f.serial (DontAddToScene);
00107 }
00108
00109
00110 if (version >= 1)
00111 f.serialCont (Clusters);
00112
00113
00114 f.serial (Name);
00115
00116
00117 f.serial (Pos);
00118
00119
00120 f.serial (Rot);
00121
00122
00123 f.serial (Scale);
00124
00125
00126 f.serial (nParent);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 uint CInstanceGroup::getNumInstance () const
00136 {
00137 return _InstancesInfos.size();
00138 }
00139
00140
00141
00142 const string& CInstanceGroup::getShapeName (uint instanceNb) const
00143 {
00144
00145 return _InstancesInfos[instanceNb].Name;
00146 }
00147
00148
00149
00150 const string& CInstanceGroup::getInstanceName (uint instanceNb) const
00151 {
00152
00153 return _InstancesInfos[instanceNb].InstanceName;
00154 }
00155
00156
00157
00158 const CVector& CInstanceGroup::getInstancePos (uint instanceNb) const
00159 {
00160
00161 return _InstancesInfos[instanceNb].Pos;
00162 }
00163
00164
00165
00166 const CQuat& CInstanceGroup::getInstanceRot (uint instanceNb) const
00167 {
00168
00169 return _InstancesInfos[instanceNb].Rot;
00170 }
00171
00172
00173
00174 const CVector& CInstanceGroup::getInstanceScale (uint instanceNb) const
00175 {
00176
00177 return _InstancesInfos[instanceNb].Scale;
00178 }
00179
00180
00181
00182 void CInstanceGroup::getInstanceMatrix(uint instanceNb,NLMISC::CMatrix &dest) const
00183 {
00184 dest.identity();
00185 dest.translate(getInstancePos(instanceNb));
00186 dest.rotate(getInstanceRot(instanceNb));
00187 dest.scale(getInstanceScale(instanceNb));
00188 }
00189
00190
00191
00192
00193
00194 const sint32 CInstanceGroup::getInstanceParent (uint instanceNb) const
00195 {
00196
00197 return _InstancesInfos[instanceNb].nParent;
00198 }
00199
00200
00201
00202 const CInstanceGroup::CInstance &CInstanceGroup::getInstance(uint instanceNb) const
00203 {
00204 return _InstancesInfos[instanceNb];
00205 }
00206
00207
00208 CInstanceGroup::CInstance &CInstanceGroup::getInstance(uint instanceNb)
00209 {
00210 return _InstancesInfos[instanceNb];
00211 }
00212
00213
00214 CTransformShape *CInstanceGroup::getTransformShape(uint instanceNb) const
00215 {
00216 if(instanceNb>_Instances.size())
00217 return NULL;
00218 return _Instances[instanceNb];
00219 }
00220
00221
00222 CInstanceGroup::CInstanceGroup()
00223 {
00224 _IGSurfaceLight.setOwner(this);
00225 _GlobalPos = CVector(0,0,0);
00226 _Root = NULL;
00227 _ClusterSystem = NULL;
00228 _RealTimeSunContribution= true;
00229 _AddToSceneState = StateNotAdded;
00230 _TransformName = NULL;
00231 _AddRemoveInstance = NULL;
00232 _IGAddBeginCallback = NULL;
00233 }
00234
00235
00236 CInstanceGroup::~CInstanceGroup()
00237 {
00238 }
00239
00240
00241 void CInstanceGroup::build (const CVector &vGlobalPos, const TInstanceArray& array,
00242 const std::vector<CCluster>& Clusters,
00243 const std::vector<CPortal>& Portals,
00244 const std::vector<CPointLightNamed> &pointLightList,
00245 const CIGSurfaceLight::TRetrieverGridMap *retrieverGridMap,
00246 float igSurfaceLightCellSize)
00247 {
00248 _GlobalPos = vGlobalPos;
00249
00250 _InstancesInfos = array;
00251
00252 _Portals = Portals;
00253 _ClusterInfos = Clusters;
00254
00255
00256 uint32 i, j, k;
00257 for (i = 0; i < _Portals.size(); ++i)
00258 {
00259 for (j = 0; j < _ClusterInfos.size(); ++j)
00260 {
00261 bool bPortalInCluster = true;
00262 for (k = 0; k < _Portals[i]._Poly.size(); ++k)
00263 if (!_ClusterInfos[j].isIn (_Portals[i]._Poly[k]) )
00264 {
00265 bPortalInCluster = false;
00266 break;
00267 }
00268 if (bPortalInCluster)
00269 {
00270 _Portals[i].setCluster(&_ClusterInfos[j]);
00271 _ClusterInfos[j].link (&_Portals[i]);
00272 }
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 std::vector<uint> plRemap;
00303 buildPointLightList(pointLightList, plRemap);
00304
00305
00306
00307 _IGSurfaceLight.clear();
00308 if(retrieverGridMap)
00309 {
00310
00311 _IGSurfaceLight.build(*retrieverGridMap, igSurfaceLightCellSize, plRemap);
00312 }
00313 }
00314
00315
00316
00317 void CInstanceGroup::build (const CVector &vGlobalPos, const TInstanceArray& array,
00318 const std::vector<CCluster>& Clusters,
00319 const std::vector<CPortal>& Portals)
00320 {
00321
00322 std::vector<CPointLightNamed> pointLightList;
00323
00324 build(vGlobalPos, array, Clusters, Portals, pointLightList);
00325 }
00326
00327
00328
00329 void CInstanceGroup::retrieve (CVector &vGlobalPos, TInstanceArray& array,
00330 std::vector<CCluster>& Clusters,
00331 std::vector<CPortal>& Portals,
00332 std::vector<CPointLightNamed> &pointLightList) const
00333 {
00334
00335 vGlobalPos= _GlobalPos;
00336 array= _InstancesInfos;
00337
00338 Portals= _Portals;
00339 Clusters= _ClusterInfos;
00340
00341 uint i;
00342 for(i=0; i<Portals.size(); i++)
00343 Portals[i].resetClusterLinks();
00344 for(i=0; i<Clusters.size(); i++)
00345 Clusters[i].resetPortalLinks();
00346
00347
00348 pointLightList= getPointLightList();
00349 }
00350
00351
00352
00353
00354 void CInstanceGroup::serial (NLMISC::IStream& f)
00355 {
00356
00357 f.serialCheck ((uint32)'TPRG');
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 sint version=f.serialVersion (5);
00369
00370
00371
00372 if (version >= 5)
00373 {
00374 f.serial(_RealTimeSunContribution);
00375 }
00376 else if(f.isReading())
00377 {
00378 _RealTimeSunContribution= true;
00379 }
00380
00381
00382
00383 if (version >= 4)
00384 {
00385 f.serial(_IGSurfaceLight);
00386 }
00387 else if(f.isReading())
00388 {
00389 _IGSurfaceLight.clear();
00390 }
00391
00392
00393
00394 if (version >= 3)
00395 {
00396 f.serial(_PointLightArray);
00397 }
00398 else if(f.isReading())
00399 {
00400 _PointLightArray.clear();
00401 }
00402
00403
00404 if (version >= 2)
00405 f.serial(_GlobalPos);
00406
00407 if (version >= 1)
00408 {
00409 f.serialCont (_ClusterInfos);
00410 f.serialCont (_Portals);
00411
00412 if (f.isReading())
00413 {
00414 uint32 i, j;
00415 for (i = 0; i < _ClusterInfos.size(); ++i)
00416 {
00417 uint32 nNbPortals;
00418 f.serial (nNbPortals);
00419 _ClusterInfos[i]._Portals.resize (nNbPortals);
00420
00421 for (j = 0; j < nNbPortals; ++j)
00422 {
00423 sint32 nPortalNb;
00424 f.serial (nPortalNb);
00425 _ClusterInfos[i]._Portals[j] = &_Portals[nPortalNb];
00426 _Portals[nPortalNb].setCluster (&_ClusterInfos[i]);
00427 }
00428 }
00429 }
00430 else
00431 {
00432 uint32 i, j;
00433 for (i = 0; i < _ClusterInfos.size(); ++i)
00434 {
00435 uint32 nNbPortals = _ClusterInfos[i]._Portals.size();
00436 f.serial (nNbPortals);
00437 for (j = 0; j < nNbPortals; ++j)
00438 {
00439 sint32 nPortalNb = (_ClusterInfos[i]._Portals[j] - &_Portals[0]);
00440 f.serial (nPortalNb);
00441 }
00442 }
00443 }
00444 }
00445
00446
00447 f.serialCont (_InstancesInfos);
00448 }
00449
00450
00451 void CInstanceGroup::createRoot (CScene& scene)
00452 {
00453 _Root = (CTransform*)scene.createModel (TransformId);
00454 _Root->setDontUnfreezeChildren (true);
00455 setPos (CVector(0,0,0));
00456 }
00457
00458
00459 void CInstanceGroup::setTransformNameCallback (ITransformName *pTN)
00460 {
00461 _TransformName = pTN;
00462 }
00463
00464
00465
00466 void CInstanceGroup::setAddRemoveInstanceCallback(IAddRemoveInstance *callback)
00467 {
00468 _AddRemoveInstance = callback;
00469 }
00470
00471
00472 void CInstanceGroup::setIGAddBeginCallback(IIGAddBegin *callback)
00473 {
00474 _IGAddBeginCallback = callback;
00475 }
00476
00477
00478 bool CInstanceGroup::addToScene (CScene& scene, IDriver *driver)
00479 {
00480 uint32 i;
00481
00482 _Instances.resize (_InstancesInfos.size(), NULL);
00483
00484 if (_IGAddBeginCallback)
00485 _IGAddBeginCallback->startAddingIG(_InstancesInfos.size());
00486
00487
00488
00489 vector<CInstance>::iterator it = _InstancesInfos.begin();
00490
00491 for (i = 0; i < _InstancesInfos.size(); ++i, ++it)
00492 {
00493 CInstance &rInstanceInfo = *it;
00494 if (!rInstanceInfo.DontAddToScene)
00495 {
00496 string shapeName;
00497
00498 bool getShapeName = true;
00499
00500
00501
00502 if (_TransformName != NULL && !rInstanceInfo.InstanceName.empty())
00503 {
00504 shapeName = _TransformName->transformName (i, rInstanceInfo.InstanceName);
00505 if (!shapeName.empty())
00506 getShapeName = false;
00507 }
00508
00509 if (getShapeName)
00510 {
00511 if (rInstanceInfo.Name.find('.') == std::string::npos)
00512 {
00513 shapeName = rInstanceInfo.Name + ".shape";
00514 }
00515 else
00516 {
00517 shapeName = rInstanceInfo.Name;
00518 }
00519 }
00520 strlwr (shapeName);
00521
00522
00523 _Instances[i] = scene.createInstance (shapeName);
00524 if( _Instances[i] == NULL )
00525 {
00526
00527 nlwarning("Not found '%s' file\n", shapeName.c_str());
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 }
00541 }
00542 }
00543
00544 return addToSceneWhenAllShapesLoaded (scene, driver);
00545 }
00546
00547
00548
00549 bool CInstanceGroup::addToSceneWhenAllShapesLoaded (CScene& scene, IDriver *driver)
00550 {
00551 uint32 i, j;
00552 vector<CInstance>::iterator it = _InstancesInfos.begin();
00553 for (i = 0; i < _InstancesInfos.size(); ++i, ++it)
00554 {
00555 CInstance &rInstanceInfo = *it;
00556
00557 if (!rInstanceInfo.DontAddToScene)
00558 {
00559 if (_Instances[i])
00560 {
00561 _Instances[i]->setPos (rInstanceInfo.Pos);
00562 _Instances[i]->setRotQuat (rInstanceInfo.Rot);
00563 _Instances[i]->setScale (rInstanceInfo.Scale);
00564 _Instances[i]->setPivot (CVector::Null);
00565
00566
00567 if( rInstanceInfo.StaticLightEnabled )
00568 {
00569
00570 uint numPointLights;
00571 for(numPointLights= 0; numPointLights<CInstanceGroup::NumStaticLightPerInstance; numPointLights++)
00572 {
00573 if(rInstanceInfo.Light[numPointLights]==0xFF)
00574 break;
00575 }
00576
00577 numPointLights= min(numPointLights, (uint)NL3D_MAX_LIGHT_CONTRIBUTION);
00578
00579
00580 CPointLight *pls[CInstanceGroup::NumStaticLightPerInstance];
00581 for(uint j=0; j<numPointLights;j++)
00582 {
00583 uint plId= rInstanceInfo.Light[j];
00584 pls[j]= (CPointLight*)(&_PointLightArray.getPointLights()[plId]);
00585 }
00586
00587
00588 CPointLight *frozenAmbientlight;
00589 if(rInstanceInfo.LocalAmbientId == 0xFF)
00590
00591 frozenAmbientlight= NULL;
00592 else
00593
00594 frozenAmbientlight= (CPointLight*)(&_PointLightArray.getPointLights()[rInstanceInfo.LocalAmbientId]);
00595
00596
00597 _Instances[i]->freezeStaticLightSetup(pls, numPointLights, rInstanceInfo.SunContribution, frozenAmbientlight);
00598 }
00599
00600
00601 if (driver)
00602 {
00603
00604 _Instances[i]->Shape->flushTextures (*driver);
00605 }
00606 }
00607 }
00608 else
00609 {
00610 _Instances[i] = NULL;
00611 }
00612 }
00613
00614
00615
00616 ITrav *pHrcTrav = scene.getTrav (HrcTravId);
00617
00618 if (_Root == NULL)
00619 {
00620 createRoot (scene);
00621 }
00622 it = _InstancesInfos.begin();
00623 for (i = 0; i < _InstancesInfos.size(); ++i, ++it)
00624 if (!_InstancesInfos[i].DontAddToScene && _Instances[i] != NULL)
00625 {
00626 CInstance &rInstanceInfo = *it;
00627 if( rInstanceInfo.nParent != -1 )
00628 pHrcTrav->link (_Instances[rInstanceInfo.nParent], _Instances[i]);
00629 else
00630 pHrcTrav->link (_Root, _Instances[i]);
00631 }
00632
00633 pHrcTrav->link (NULL, _Root);
00634
00635
00636
00637
00638 CClipTrav *pClipTrav = (CClipTrav*)(scene.getTrav (ClipTravId));
00639 _ClipTrav = pClipTrav;
00640
00641
00642 _ClusterInstances.resize (_ClusterInfos.size());
00643 for (i = 0; i < _ClusterInstances.size(); ++i)
00644 {
00645 _ClusterInstances[i] = (CCluster*)scene.createModel (ClusterId);
00646 _ClusterInstances[i]->Group = this;
00647 _ClusterInstances[i]->_Portals = _ClusterInfos[i]._Portals;
00648 _ClusterInstances[i]->_LocalVolume = _ClusterInfos[i]._LocalVolume;
00649 _ClusterInstances[i]->_LocalBBox = _ClusterInfos[i]._LocalBBox;
00650 _ClusterInstances[i]->_Volume = _ClusterInfos[i]._Volume;
00651 _ClusterInstances[i]->_BBox = _ClusterInfos[i]._BBox;
00652 _ClusterInstances[i]->FatherVisible = _ClusterInfos[i].FatherVisible;
00653 _ClusterInstances[i]->VisibleFromFather = _ClusterInfos[i].VisibleFromFather;
00654 _ClusterInstances[i]->Name = _ClusterInfos[i].Name;
00655 pClipTrav->registerCluster (_ClusterInstances[i]);
00656 pClipTrav->unlink (NULL, _ClusterInstances[i]);
00657 }
00658
00659
00660 for (i = 0; i < _Portals.size(); ++i)
00661 for (j = 0; j < 2; ++j)
00662 {
00663 sint32 nClusterNb;
00664 nClusterNb = (_Portals[i]._Clusters[j] - &_ClusterInfos[0]);
00665 _Portals[i]._Clusters[j] = _ClusterInstances[nClusterNb];
00666 }
00667
00668
00669 for (i = 0; i < _Instances.size(); ++i)
00670 if (_Instances[i] != NULL && !_InstancesInfos[i].DontAddToScene)
00671 {
00672 if (_InstancesInfos[i].Clusters.size() > 0)
00673 {
00674 pClipTrav->unlink (NULL, _Instances[i]);
00675 for (j = 0; j < _InstancesInfos[i].Clusters.size(); ++j)
00676 pClipTrav->link (_ClusterInstances[_InstancesInfos[i].Clusters[j]], _Instances[i]);
00677
00678 _Instances[i]->freeze();
00679 _Instances[i]->setClusterSystem (this);
00680 }
00681 else
00682 {
00683
00684
00685 _Instances[i]->setClusterSystem (_ClusterSystem);
00686 }
00687 }
00688 _Root->freeze();
00689
00690
00691 for (i = 0; i < _ClusterInstances.size(); ++i)
00692 {
00693 _ClusterInstances[i]->setWorldMatrix (_Root->getMatrix());
00694
00695 for (j = 0; j < _ClusterInstances[i]->getNbPortals(); ++j)
00696 {
00697 CPortal *pPortal = _ClusterInstances[i]->getPortal(j);
00698 pPortal->setWorldMatrix (_Root->getMatrix());
00699 }
00700
00701
00702 if (!_ClusterInstances[i]->isRoot())
00703 {
00704 _ClipTrav->Accel.erase (_ClusterInstances[i]->AccelIt);
00705 _ClipTrav->registerCluster (_ClusterInstances[i]);
00706 }
00707 }
00708
00709
00710
00711 linkToParent (scene.getGlobalInstanceGroup());
00712
00713
00714 for (i = 0; i < _ClusterInstances.size(); ++i)
00715 pHrcTrav->link (_Root, _ClusterInstances[i]);
00716
00717
00718
00719 freezeHRC();
00720
00721
00722
00723
00724
00725 if(_PointLightArray.getPointLights().size() > 0)
00726 scene.addInstanceGroupForLightAnimation(this);
00727
00728 _AddToSceneState = StateAdded;
00729
00730 if (_AddRemoveInstance)
00731 _AddRemoveInstance->instanceGroupAdded();
00732 return true;
00733 }
00734
00735
00736 bool CInstanceGroup::addToSceneAsync (CScene& scene, IDriver *driver)
00737 {
00738 uint32 i;
00739
00740 _AddToSceneState = StateAdding;
00741 _AddToSceneTempScene = &scene;
00742 _AddToSceneTempDriver = driver;
00743
00744 _Instances.resize (_InstancesInfos.size(), NULL);
00745
00746 if (_IGAddBeginCallback)
00747 _IGAddBeginCallback->startAddingIG(_InstancesInfos.size());
00748
00749
00750
00751 vector<CInstance>::iterator it = _InstancesInfos.begin();
00752 set<string> allShapesToLoad;
00753 _AddToSceneSignal = false;
00754 bool loadAsyncStarted = false;
00755 for (i = 0; i < _InstancesInfos.size(); ++i, ++it)
00756 {
00757 CInstance &rInstanceInfo = *it;
00758 if (!rInstanceInfo.DontAddToScene)
00759 {
00760 string shapeName;
00761 bool getShapeName = true;
00762
00763 if (_TransformName != NULL && !rInstanceInfo.InstanceName.empty())
00764 {
00765 shapeName = _TransformName->transformName (i, rInstanceInfo.InstanceName);
00766 if (!shapeName.empty())
00767 getShapeName = false;
00768 }
00769
00770
00771 if (getShapeName)
00772 {
00773 if (rInstanceInfo.Name.find('.') == std::string::npos)
00774 {
00775 shapeName = rInstanceInfo.Name + ".shape";
00776 }
00777 else
00778 {
00779 shapeName = rInstanceInfo.Name;
00780 }
00781 }
00782 shapeName = strlwr (shapeName);
00783
00784 shapeName = strlwr (shapeName);
00785 if (allShapesToLoad.find(shapeName) == allShapesToLoad.end())
00786 {
00787 allShapesToLoad.insert (shapeName);
00788 if (scene.getShapeBank()->isPresent(shapeName) != CShapeBank::Present)
00789 {
00790
00791 scene.getShapeBank()->loadAsync (shapeName, scene.getDriver(), &_AddToSceneSignal);
00792 loadAsyncStarted = true;
00793 }
00794 }
00795 }
00796 }
00797 if (!loadAsyncStarted)
00798 _AddToSceneSignal = true;
00799 else
00800 _AddToSceneSignal = false;
00801
00802 return true;
00803 }
00804
00805
00806 void CInstanceGroup::stopAddToSceneAsync ()
00807 {
00808 if (_AddToSceneState != StateAdding)
00809 return;
00810 vector<CInstance>::iterator it = _InstancesInfos.begin();
00811 CAsyncFileManager::getInstance().cancelSignal (&_AddToSceneSignal);
00812 for (uint32 i = 0; i < _InstancesInfos.size(); ++i, ++it)
00813 {
00814 CInstance &rInstanceInfo = *it;
00815 if (!rInstanceInfo.DontAddToScene)
00816 {
00817 string shapeName;
00818
00819
00820 bool getShapeName = true;
00821
00822 if (_TransformName != NULL && !rInstanceInfo.InstanceName.empty())
00823 {
00824 shapeName = _TransformName->transformName (i, rInstanceInfo.InstanceName);
00825 if (!shapeName.empty())
00826 getShapeName = false;
00827 }
00828
00829
00830 if (getShapeName)
00831 {
00832 if (rInstanceInfo.Name.find('.') == std::string::npos)
00833 shapeName = rInstanceInfo.Name + ".shape";
00834 else
00835 shapeName = rInstanceInfo.Name;
00836 }
00837
00838 shapeName = strlwr (shapeName);
00839 _AddToSceneTempScene->getShapeBank()->cancelLoadAsync (shapeName);
00840 }
00841 }
00842 _AddToSceneState = StateNotAdded;
00843 }
00844
00845
00846 CInstanceGroup::TState CInstanceGroup::getAddToSceneState ()
00847 {
00848
00849 if (_AddToSceneState == StateAdding)
00850 {
00851 if (_AddToSceneSignal)
00852 {
00853 addToScene (*_AddToSceneTempScene, _AddToSceneTempDriver);
00854 }
00855 }
00856 return _AddToSceneState;
00857 }
00858
00859
00860
00861
00862 bool CInstanceGroup::linkToParent (CInstanceGroup *pFather)
00863 {
00864 uint32 i, j;
00865 bool ret;
00866
00867
00868
00869 for (i = 0; i < pFather->_ClusterInstances.size(); ++i)
00870 {
00871 for(j = 0; j < pFather->_ClusterInstances[i]->Children.size(); ++j)
00872 {
00873 if (linkToParent(pFather->_ClusterInstances[i]->Children[j]->Group))
00874 return true;
00875 }
00876 }
00877 ret = false;
00878 if (this != pFather)
00879 {
00880 for (j = 0; j < this->_ClusterInstances.size(); ++j)
00881 {
00882 if ((this->_ClusterInstances[j]->FatherVisible) ||
00883 (this->_ClusterInstances[j]->VisibleFromFather))
00884 {
00885 for (i = 0; i < pFather->_ClusterInstances .size(); ++i)
00886 {
00887
00888 if (pFather->_ClusterInstances[i]->isIn(this->_ClusterInstances[j]->getBBox()))
00889 {
00890 if (this->_ClusterInstances[j]->Father != pFather->_ClusterInstances[i])
00891 {
00892
00893 this->_ClusterInstances[j]->unlinkFromParent();
00894
00895
00896 pFather->_ClusterInstances[i]->Children.push_back(this->_ClusterInstances[j]);
00897 this->_ClusterInstances[j]->Father = pFather->_ClusterInstances[i];
00898 }
00899 ret = true;
00900 }
00901 }
00902 }
00903 }
00904 }
00905 return ret;
00906 }
00907
00908
00909 bool CInstanceGroup::removeFromScene (CScene& scene)
00910 {
00911 uint32 i, j, k;
00912
00913 vector<CTransformShape*>::iterator it = _Instances.begin();
00914 for (i = 0; i < _InstancesInfos.size(); ++i, ++it)
00915 {
00916 CTransformShape *pTShape = *it;
00917 if(pTShape)
00918 {
00919
00920 pTShape->unfreezeStaticLightSetup();
00921
00922 scene.deleteInstance (pTShape);
00923 *it = NULL;
00924 }
00925 }
00926
00927
00928 for (i = 0; i < _Portals.size(); ++i)
00929 for (k = 0; k < 2; ++k)
00930 {
00931 for (j = 0; j < _ClusterInstances.size(); ++j)
00932 if( _Portals[i]._Clusters[k] == _ClusterInstances[j] )
00933 break;
00934
00935 nlassert (j!=_ClusterInstances.size());
00936 _Portals[i]._Clusters[k] = &_ClusterInfos[j];
00937 }
00938
00939
00940 CClipTrav *pClipTrav = (CClipTrav*)(scene.getTrav (ClipTravId));
00941 for (i = 0; i < _ClusterInstances.size(); ++i)
00942 {
00943 pClipTrav->unregisterCluster (_ClusterInstances[i]);
00944 scene.deleteModel (_ClusterInstances[i]);
00945 }
00946
00947 scene.deleteModel (_Root);
00948 _Root = NULL;
00949
00950
00951
00952
00953
00954 if(_PointLightArray.getPointLights().size() > 0)
00955 scene.removeInstanceGroupForLightAnimation(this);
00956
00957 if (_AddRemoveInstance)
00958 _AddRemoveInstance->instanceGroupRemoved();
00959 return true;
00960 }
00961
00962
00963
00964 void CInstanceGroup::getLights( set<string> &LightNames )
00965 {
00966 LightNames.clear();
00967 for( uint32 i = 0; i < _Instances.size(); ++i )
00968 {
00969 CMeshInstance *pMI = dynamic_cast<CMeshInstance*>(_Instances[i]);
00970 if( pMI != NULL )
00971 {
00972 uint32 nNbLM = pMI->getNbLightMap();
00973 for( uint32 j = 0; j < nNbLM; ++j )
00974 {
00975 string sTmp;
00976 pMI->getLightMapName( j, sTmp );
00977 set<string>::iterator itSet = LightNames.find(sTmp);
00978 if( itSet == LightNames.end() )
00979 LightNames.insert( sTmp );
00980 }
00981 }
00982 }
00983 }
00984
00985
00986 void CInstanceGroup::setLightFactor( const string &LightName, CRGBA Factor )
00987 {
00988 for( uint32 i = 0; i < _Instances.size(); ++i )
00989 {
00990 CMeshBaseInstance *pMI = dynamic_cast<CMeshBaseInstance*>(_Instances[i]);
00991 if( pMI != NULL )
00992 {
00993 pMI->setLightMapFactor( LightName, Factor );
00994 }
00995 }
00996 }
00997
00998
00999 void CInstanceGroup::getBlendShapes( set<string> &BlendShapeNames )
01000 {
01001 BlendShapeNames.clear();
01002 for( uint32 i = 0; i < _Instances.size(); ++i )
01003 {
01004 CMeshBaseInstance *pMBI = dynamic_cast<CMeshBaseInstance*>(_Instances[i]);
01005 if (pMBI != NULL)
01006 {
01007 uint32 nNbBS = pMBI->getNbBlendShape();
01008 for( uint32 j = 0; j < nNbBS; ++j )
01009 {
01010 string sTmp;
01011 pMBI->getBlendShapeName( j, sTmp );
01012 set<string>::iterator itSet = BlendShapeNames.find(sTmp);
01013 if( itSet == BlendShapeNames.end() )
01014 BlendShapeNames.insert( sTmp );
01015 }
01016 }
01017 }
01018 }
01019
01020
01021 void CInstanceGroup::setBlendShapeFactor( const string &BlendShapeName, float rFactor )
01022 {
01023 for( uint32 i = 0; i < _Instances.size(); ++i )
01024 {
01025 CMeshBaseInstance *pMI = dynamic_cast<CMeshBaseInstance*>(_Instances[i]);
01026 if( pMI != NULL )
01027 {
01028 pMI->setBlendShapeFactor( BlendShapeName, rFactor );
01029 }
01030 }
01031 }
01032
01033
01034 void CInstanceGroup::addCluster(CCluster *pCluster)
01035 {
01036 _ClusterInstances.push_back(pCluster);
01037 }
01038
01039
01040 void CInstanceGroup::setClusterSystem(CInstanceGroup *pIG)
01041 {
01042 _ClusterSystem = pIG;
01043 for (uint32 i = 0; i < _Instances.size(); ++i)
01044 if (_Instances[i] && _InstancesInfos[i].Clusters.size() == 0)
01045 _Instances[i]->setClusterSystem (_ClusterSystem);
01046 }
01047
01048
01049 void CInstanceGroup::getDynamicPortals (std::vector<std::string> &names)
01050 {
01051 for (uint32 i = 0; i < _Portals.size(); ++i)
01052 if (_Portals[i].getName() != "")
01053 names.push_back (_Portals[i].getName());
01054 }
01055
01056
01057 void CInstanceGroup::setDynamicPortal (std::string& name, bool opened)
01058 {
01059 for (uint32 i = 0; i < _Portals.size(); ++i)
01060 if (_Portals[i].getName() == name)
01061 _Portals[i].open (opened);
01062 }
01063
01064
01065 bool CInstanceGroup::getDynamicPortal (std::string& name)
01066 {
01067 for (uint32 i = 0; i < _Portals.size(); ++i)
01068 if (_Portals[i].getName() == name)
01069 return _Portals[i].isOpened ();
01070 return false;
01071 }
01072
01073
01074 void CInstanceGroup::setPos (const CVector &pos)
01075 {
01076 if (_Root != NULL)
01078 _Root->setPos (pos);
01079 }
01080
01081
01082 void CInstanceGroup::setRotQuat (const CQuat &quat)
01083 {
01084 if (_Root != NULL)
01085 _Root->setRotQuat (quat);
01086 }
01087
01088
01089 CVector CInstanceGroup::getPos ()
01090 {
01091 if (_Root != NULL)
01092 return _Root->getPos ();
01093 else
01094 return CVector(0.0f, 0.0f, 0.0f);
01095 }
01096
01097
01098 CQuat CInstanceGroup::getRotQuat ()
01099 {
01100 if (_Root != NULL)
01101 return _Root->getRotQuat ();
01102 else
01103 return CQuat();
01104 }
01105
01106
01107 void CInstanceGroup::linkRoot (CScene &scene, CTransform *father)
01108 {
01109 if(_Root)
01110 {
01111 ITrav *pHrcTrav = scene.getTrav (HrcTravId);
01112 pHrcTrav->link(father, _Root);
01113 }
01114 }
01115
01116
01117 void CInstanceGroup::freezeHRC()
01118 {
01119
01120 for (uint i=0; i < _Instances.size(); i++)
01121 {
01122 if(_Instances[i])
01123 _Instances[i]->freezeHRC();
01124 }
01125
01126 _Root->freezeHRC();
01127 }
01128
01129
01130
01131 void CInstanceGroup::unfreezeHRC()
01132 {
01133
01134 for (uint i=0; i < _Instances.size(); i++)
01135 {
01136 if(_Instances[i])
01137 _Instances[i]->unfreezeHRC();
01138 }
01139
01140 _Root->unfreezeHRC();
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150 void CInstanceGroup::buildPointLightList(const std::vector<CPointLightNamed> &pointLightList,
01151 std::vector<uint> &plRemap)
01152 {
01153
01154 _PointLightArray.build(pointLightList, plRemap);
01155
01156
01157 for(uint i=0; i<_InstancesInfos.size(); i++)
01158 {
01159 CInstance &inst= _InstancesInfos[i];
01160
01161 if(!inst.StaticLightEnabled)
01162 continue;
01163
01164
01165 for(uint l=0; l<CInstanceGroup::NumStaticLightPerInstance; l++)
01166 {
01167
01168 if(inst.Light[l]== 0xFF)
01169 break;
01170 else
01171 {
01172
01173 nlassert(inst.Light[l] < _PointLightArray.getPointLights().size());
01174
01175 inst.Light[l]= plRemap[inst.Light[l]];
01176 }
01177 }
01178
01179
01180 if(inst.LocalAmbientId!=0xFF)
01181 {
01182 nlassert(inst.LocalAmbientId < _PointLightArray.getPointLights().size());
01183 inst.LocalAmbientId= plRemap[inst.LocalAmbientId];
01184 }
01185 }
01186
01187 }
01188
01189
01190 void CInstanceGroup::setPointLightFactor(const std::string &lightGroupName, NLMISC::CRGBA nFactor)
01191 {
01192 _PointLightArray.setPointLightFactor(lightGroupName, nFactor);
01193 }
01194
01195
01196
01197 void CInstanceGroup::enableRealTimeSunContribution(bool enable)
01198 {
01199 _RealTimeSunContribution= enable;
01200 }
01201
01202
01203 }