From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/scene__group_8cpp-source.html | 1271 ++++++++++++++++++++++++ 1 file changed, 1271 insertions(+) create mode 100644 docs/doxygen/nel/scene__group_8cpp-source.html (limited to 'docs/doxygen/nel/scene__group_8cpp-source.html') diff --git a/docs/doxygen/nel/scene__group_8cpp-source.html b/docs/doxygen/nel/scene__group_8cpp-source.html new file mode 100644 index 00000000..71306eaa --- /dev/null +++ b/docs/doxygen/nel/scene__group_8cpp-source.html @@ -0,0 +1,1271 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

scene_group.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+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 // CInstance
+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         Version 4:
+00062                 - LocalAmbientId.
+00063         Version 3:
+00064                 - StaticLight.
+00065         Version 2:
+00066                 - gameDev data.
+00067         Version 1:
+00068                 - Clusters
+00069         */
+00070         // Serial a version number
+00071         sint version=f.serialVersion (4);
+00072 
+00073 
+00074         // Serial the LocalAmbientId.
+00075         if (version >= 4)
+00076         {
+00077                 f.serial(LocalAmbientId);
+00078         }
+00079         else if(f.isReading())
+00080         {
+00081                 LocalAmbientId= 0xFF;
+00082         }
+00083 
+00084         // Serial the StaticLight
+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         // Serial the gamedev data
+00103         if (version >= 2)
+00104         {
+00105                 f.serial (InstanceName);
+00106                 f.serial (DontAddToScene);
+00107         }
+00108 
+00109         // Serial the clusters
+00110         if (version >= 1)
+00111                 f.serialCont (Clusters);
+00112 
+00113         // Serial the name
+00114         f.serial (Name);
+00115 
+00116         // Serial the position vector
+00117         f.serial (Pos);
+00118 
+00119         // Serial the rotation vector
+00120         f.serial (Rot);
+00121 
+00122         // Serial the scale vector
+00123         f.serial (Scale);
+00124 
+00125         // Serial the parent location in the vector (-1 if no parent)
+00126         f.serial (nParent);
+00127 }
+00128 
+00129 // ---------------------------------------------------------------------------
+00130 // CInstanceGroup
+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         // Return the name of the n-th instance
+00145         return _InstancesInfos[instanceNb].Name;
+00146 }
+00147 
+00148 // ***************************************************************************
+00149 
+00150 const string& CInstanceGroup::getInstanceName (uint instanceNb) const
+00151 {
+00152         // Return the name of the n-th instance
+00153         return _InstancesInfos[instanceNb].InstanceName;
+00154 }
+00155 
+00156 // ***************************************************************************
+00157 
+00158 const CVector& CInstanceGroup::getInstancePos (uint instanceNb) const
+00159 {
+00160         // Return the position vector of the n-th instance
+00161         return _InstancesInfos[instanceNb].Pos;
+00162 }
+00163 
+00164 // ***************************************************************************
+00165 
+00166 const CQuat& CInstanceGroup::getInstanceRot (uint instanceNb) const
+00167 {
+00168         // Return the rotation vector of the n-th instance
+00169         return _InstancesInfos[instanceNb].Rot;
+00170 }
+00171 
+00172 // ***************************************************************************
+00173 
+00174 const CVector& CInstanceGroup::getInstanceScale (uint instanceNb) const
+00175 {
+00176         // Return the scale vector of the n-th instance
+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         // Return the scale vector of the n-th instance
+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         // Copy the array
+00250         _InstancesInfos = array;
+00251 
+00252         _Portals = Portals;
+00253         _ClusterInfos = Clusters;
+00254 
+00255         // Link portals and clusters
+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         // Create Meta Cluster if needed
+00277         /*
+00278         CCluster clusterTemp;
+00279         bool mustAdd = false;
+00280         for (i = 0; i < _Portals.size(); ++i)
+00281         if (_Portals[i].getNbCluster() == 1)
+00282         {
+00283                 mustAdd = true;
+00284                 break;
+00285         }
+00286         if (mustAdd)
+00287         {
+00288                 CCluster clusterTemp;
+00289                 _ClusterInfos.push_back(clusterTemp);
+00290                 CCluster *pMetaCluster = &_ClusterInfos[_ClusterInfos.size()-1];
+00291                 pMetaCluster->setMetaCluster();
+00292                 for (i = 0; i < _Portals.size(); ++i)
+00293                 if (_Portals[i].getNbCluster() == 1)
+00294                 {
+00295                         _Portals[i].setCluster(pMetaCluster);
+00296                         pMetaCluster->link(&_Portals[i]);
+00297                 }
+00298         }*/
+00299 
+00300 
+00301         // Build the list of light. NB: sort by LightGroupName the array.
+00302         std::vector<uint>       plRemap;
+00303         buildPointLightList(pointLightList, plRemap);
+00304 
+00305         // Build IgSurfaceLight
+00306         // clear
+00307         _IGSurfaceLight.clear();
+00308         if(retrieverGridMap)
+00309         {
+00310                 //build
+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         // empty pointLightList
+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         // Just copy infos. NB: light information order have change but is still valid
+00335         vGlobalPos= _GlobalPos;
+00336         array= _InstancesInfos;
+00337 
+00338         Portals= _Portals;
+00339         Clusters= _ClusterInfos;
+00340         // Must reset links to all portals and clusters.
+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         // Serial a header
+00357         f.serialCheck ((uint32)'TPRG');
+00358 
+00359         /*
+00360         Version 5:
+00361                 _ _RealTimeSunContribution
+00362         Version 4:
+00363                 _ IGSurfaceLight
+00364         Version 3:
+00365                 - PointLights
+00366         */
+00367         // Serial a version number
+00368         sint version=f.serialVersion (5);
+00369 
+00370 
+00371         // _RealTimeSunContribution
+00372         if (version >= 5)
+00373         {
+00374                 f.serial(_RealTimeSunContribution);
+00375         }
+00376         else if(f.isReading())
+00377         {
+00378                 _RealTimeSunContribution= true;
+00379         }
+00380 
+00381 
+00382         // Serial the IGSurfaceLight
+00383         if (version >= 4)
+00384         {
+00385                 f.serial(_IGSurfaceLight);
+00386         }
+00387         else if(f.isReading())
+00388         {
+00389                 _IGSurfaceLight.clear();
+00390         }
+00391 
+00392 
+00393         // Serial the PointLights info
+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                 // Links
+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                                 // Recreate clusters to portals links
+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 // We are writing to the stream
+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         // Serial the array
+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         // Creation and positionning of the new instance
+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                         // If there is a callback added to this instance group then transform
+00501                         // the name of the shape to load.
+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    // extension has already been added
+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                                 //#if defined(NL_DEBUG) && defined(__STL_DEBUG)
+00529                                 //      nlstop;
+00530                                 //#endif
+00531 
+00532                                 /*
+00533                                         for (uint32 j = 0; j < i; ++j)
+00534                                         {
+00535                                                 scene.deleteInstance(_Instances[j]);
+00536                                                 _Instances[j] = NULL;
+00537                                         }
+00538                                         throw NLMISC::Exception("CInstanceGroup::addToScene : unable to create %s shape file", rInstanceInfo.Name.c_str());
+00539                                 */
+00540                         }
+00541                 }
+00542         }
+00543 
+00544         return addToSceneWhenAllShapesLoaded (scene, driver);
+00545 }
+00546 
+00547 // ***************************************************************************
+00548 // Private method
+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                                 // Static Light Setup
+00567                                 if( rInstanceInfo.StaticLightEnabled )
+00568                                 {
+00569                                         // Count lights.
+00570                                         uint numPointLights;
+00571                                         for(numPointLights= 0; numPointLights<CInstanceGroup::NumStaticLightPerInstance; numPointLights++)
+00572                                         {
+00573                                                 if(rInstanceInfo.Light[numPointLights]==0xFF)
+00574                                                         break;
+00575                                         }
+00576                                         // Max allowed.
+00577                                         numPointLights= min(numPointLights, (uint)NL3D_MAX_LIGHT_CONTRIBUTION);
+00578 
+00579                                         // Get pl ptrs.
+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                                         // get frozenAmbientlight.
+00588                                         CPointLight *frozenAmbientlight;
+00589                                         if(rInstanceInfo.LocalAmbientId == 0xFF)
+00590                                                 // must take the sun one.
+00591                                                 frozenAmbientlight= NULL;
+00592                                         else
+00593                                                 // ok, take the local ambient one.
+00594                                                 frozenAmbientlight= (CPointLight*)(&_PointLightArray.getPointLights()[rInstanceInfo.LocalAmbientId]);
+00595 
+00596                                         // Setup the instance.
+00597                                         _Instances[i]->freezeStaticLightSetup(pls, numPointLights, rInstanceInfo.SunContribution, frozenAmbientlight);
+00598                                 }
+00599 
+00600                                 // Driver not NULL ?
+00601                                 if (driver)
+00602                                 {
+00603                                         // Flush shape's texture with this driver
+00604                                         _Instances[i]->Shape->flushTextures (*driver);
+00605                                 }
+00606                         }
+00607                 }
+00608                 else
+00609                 {
+00610                         _Instances[i] = NULL;
+00611                 }
+00612         }
+00613 
+00614         // Setup the hierarchy
+00615         // We just have to set the traversal HRC (Hierarchy)
+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 ) // Is the instance get a parent
+00628                         pHrcTrav->link (_Instances[rInstanceInfo.nParent], _Instances[i]);
+00629                 else
+00630                         pHrcTrav->link (_Root, _Instances[i]);
+00631         }
+00632         // Attach the root of the instance group to the root of the hierarchy traversal
+00633         pHrcTrav->link (NULL, _Root);
+00634 
+00635         // Cluster / Portals
+00636         // -----------------
+00637 
+00638         CClipTrav *pClipTrav = (CClipTrav*)(scene.getTrav (ClipTravId));
+00639         _ClipTrav = pClipTrav;
+00640 
+00641         // Create the MOT links (create the physical clusters)
+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         // Relink portals with newly created clusters
+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         // Link shapes to clusters
+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                         // For the first time we have to set all the instances to NOT move (and not be rebinded)
+00678                         _Instances[i]->freeze();
+00679                         _Instances[i]->setClusterSystem (this);
+00680                 }
+00681                 else
+00682                 {
+00683                         // These instances are not attached to a cluster at this level so we cannot freeze them
+00684                         // Moreover we must set their clustersystem they will be tested against
+00685                         _Instances[i]->setClusterSystem (_ClusterSystem);
+00686                 }
+00687         }
+00688         _Root->freeze();
+00689 
+00690         // HRC OBS like
+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                 // Re affect the cluster to the accelerator if not the root
+00702                 if (!_ClusterInstances[i]->isRoot())
+00703                 {
+00704                         _ClipTrav->Accel.erase (_ClusterInstances[i]->AccelIt);
+00705                         _ClipTrav->registerCluster (_ClusterInstances[i]);
+00706                 }
+00707         }
+00708 
+00709 
+00710         // Link the instance group to the parent
+00711         linkToParent (scene.getGlobalInstanceGroup());
+00712 
+00713         // Attach the clusters to the root of the instance group
+00714         for (i = 0; i < _ClusterInstances.size(); ++i)
+00715                 pHrcTrav->link (_Root, _ClusterInstances[i]);
+00716 
+00717 
+00718         // Default: freezeHRC all instances.
+00719         freezeHRC();
+00720 
+00721 
+00722         // Register the instanceGroup for light animation
+00723         // -----------------
+00724         // If some PointLight to animate
+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         // Creation and positionning of the new instance
+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    // extension has already been added
+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                                         // Load it from file asynchronously
+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         //CAsyncFileManager::getInstance().signal (&_AddToSceneSignal);
+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    // extension has already been added
+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         // If we are adding but we have finished loading shapes (all shapes are here)
+00849         if (_AddToSceneState == StateAdding)
+00850         {
+00851                 if (_AddToSceneSignal)
+00852                 {
+00853                         addToScene (*_AddToSceneTempScene, _AddToSceneTempDriver);
+00854                 }
+00855         }
+00856         return _AddToSceneState;
+00857 }
+00858 
+00859 // ***************************************************************************
+00860 // Search in the hierarchy of ig the most low level (child) ig that contains the clusters that
+00861 // are flagged to be visible from father or which father is visible
+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]) // not already sons of the right cluster ?
+00891                                                 {                                               
+00892                                                         // unlink from parent
+00893                                                         this->_ClusterInstances[j]->unlinkFromParent();
+00894 
+00895                                                         // relink in hierarchy
+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         // Remove shapes
+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                         // For security, unfreeze any StaticLightSetup setuped.
+00920                         pTShape->unfreezeStaticLightSetup();
+00921                         // delete the instance
+00922                         scene.deleteInstance (pTShape);
+00923                         *it = NULL;
+00924                 }
+00925         }
+00926 
+00927         // Relink portals with old clusters
+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         // Remove clusters
+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         // UnRegister the instanceGroup for light animation
+00952         // -----------------
+00953         // If some PointLight to animate
+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         // For all instances.
+01120         for (uint i=0; i < _Instances.size(); i++)
+01121         {
+01122                 if(_Instances[i])
+01123                         _Instances[i]->freezeHRC();
+01124         }
+01125         // and for root.
+01126         _Root->freezeHRC();
+01127 }
+01128 
+01129 
+01130 // ***************************************************************************
+01131 void            CInstanceGroup::unfreezeHRC()
+01132 {
+01133         // For all instances.
+01134         for (uint i=0; i < _Instances.size(); i++)
+01135         {
+01136                 if(_Instances[i])
+01137                         _Instances[i]->unfreezeHRC();
+01138         }
+01139         // and for root.
+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         // build.
+01154         _PointLightArray.build(pointLightList, plRemap);
+01155 
+01156         // remap Instance precalc lighted.
+01157         for(uint i=0; i<_InstancesInfos.size(); i++)
+01158         {
+01159                 CInstance       &inst= _InstancesInfos[i];
+01160                 // If the instance has no precomputed lighting, skip
+01161                 if(!inst.StaticLightEnabled)
+01162                         continue;
+01163 
+01164                 // remap pointlights
+01165                 for(uint l=0; l<CInstanceGroup::NumStaticLightPerInstance; l++)
+01166                 {
+01167                         // If NULL light, break and continue to next instance
+01168                         if(inst.Light[l]== 0xFF)
+01169                                 break;
+01170                         else
+01171                         {
+01172                                 // Check good index.
+01173                                 nlassert(inst.Light[l] < _PointLightArray.getPointLights().size());
+01174                                 // Remap index, because of light sorting.
+01175                                 inst.Light[l]= plRemap[inst.Light[l]];
+01176                         }
+01177                 }
+01178 
+01179                 // remap ambient light
+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 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1