# 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.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 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.h"
00029 #include "3d/trav_scene.h"
00030 #include "3d/hrc_trav.h"
00031 #include "3d/clip_trav.h"
00032 #include "3d/light_trav.h"
00033 #include "3d/anim_detail_trav.h"
00034 #include "3d/load_balancing_trav.h"
00035 #include "3d/render_trav.h"
00036 #include "3d/transform.h"
00037 #include "3d/camera.h"
00038 #include "3d/landscape_model.h"
00039 #include "3d/driver.h"
00040 #include "3d/transform_shape.h"
00041 #include "3d/mesh_base.h"
00042 #include "3d/mesh_base_instance.h"
00043 #include "3d/mesh_instance.h"
00044 #include "3d/mesh_mrm_instance.h"
00045 #include "3d/mesh_multi_lod_instance.h"
00046 #include "3d/shape_bank.h"
00047 #include "3d/skeleton_model.h"
00048 #include "3d/particle_system_model.h"
00049 #include "3d/coarse_mesh_manager.h"
00050 #include "3d/cluster.h"
00051 #include "3d/scene_group.h"
00052 #include "3d/flare_model.h"
00053 #include "3d/skip_model.h"
00054 #include "3d/quad_grid_clip_cluster.h"
00055 #include "3d/water_model.h"
00056 #include "3d/vegetable_blend_layer_model.h"
00057 #include "3d/root_model.h"
00058 #include "3d/point_light_model.h"
00059 #include "3d/animation.h"
00060 #include "3d/lod_character_manager.h"
00061 #include "3d/seg_remanence.h"
00062 #include "3d/async_texture_manager.h"
00063 
00064 #include <memory>
00065 
00066 #include "nel/misc/time_nl.h"
00067 #include "nel/misc/file.h"
00068 #include "nel/misc/path.h"
00069 using namespace std;
00070 using namespace NLMISC;
00071 
00072 #define NL3D_SCENE_STATIC_COARSE_MANAGER_TEXTURE        "nel_coarse_texture.tga"
00073 #define NL3D_SCENE_DYNAMIC_COARSE_MANAGER_TEXTURE       NL3D_SCENE_STATIC_COARSE_MANAGER_TEXTURE
00074 
00075 #define NL3D_MEM_INSTANCE                                       NL_ALLOC_CONTEXT( 3dInst )
00076 #define NL3D_MEM_MOT                                            NL_ALLOC_CONTEXT( 3dMot )
00077 
00078 #define NL3D_SCENE_QUADGRID_CLIP_CLUSTER_SIZE   400
00079 #define NL3D_SCENE_QUADGRID_CLIP_NUM_MAXDIST    3
00080 const   float   NL3D_QuadGridClipManagerMaxDist[NL3D_SCENE_QUADGRID_CLIP_NUM_MAXDIST]= {200, 400, 600};
00081 // The manager is limited to a square of 3000m*3000m around the camera. Beyond, models are clipped individually (bad!!).
00082 const   float   NL3D_QuadGridClipManagerRadiusMax= 1500;
00083 
00084 
00085 namespace NL3D
00086 {
00087 
00088 // ***************************************************************************
00089 // ***************************************************************************
00090 // ***************************************************************************
00091 
00092         
00093 void    CScene::registerBasics()
00094 {
00095         CTransform::registerBasic();
00096         CCamera::registerBasic();
00097         CMeshBaseInstance::registerBasic();
00098         CMeshInstance::registerBasic();
00099         CMeshMRMInstance::registerBasic();
00100         CLandscapeModel::registerBasic();
00101         CTransformShape::registerBasic();
00102         CSkeletonModel::registerBasic();
00103         CParticleSystemModel::registerBasic() ;
00104         CMeshMultiLodInstance::registerBasic();
00105         CCoarseMeshManager::registerBasic();
00106         CCluster::registerBasic();
00107         CFlareModel::registerBasic();
00108         CSkipModel::registerBasic();
00109         CQuadGridClipCluster::registerBasic();
00110         CWaterModel::registerBasic();
00111         CWaveMakerModel::registerBasic();
00112         CVegetableBlendLayerModel::registerBasic();
00113         CRootModel::registerBasic();
00114         CPointLightModel::registerBasic();
00115         CSegRemanence::registerBasic();
00116 }
00117 
00118         
00119 // ***************************************************************************
00120 // ***************************************************************************
00121 // ***************************************************************************
00122 
00123 // ***************************************************************************
00124 CScene::CScene()
00125 {
00126         HrcTrav= NULL;
00127         ClipTrav= NULL;
00128         LightTrav= NULL;
00129         AnimDetailTrav= NULL;
00130         LoadBalancingTrav= NULL;
00131         RenderTrav= NULL;
00132 
00133         _ShapeBank = NULL;
00134 
00135         _StaticCoarseMeshManager = NULL;
00136         _DynamicCoarseMeshManager = NULL;
00137 
00138         Root= NULL;
00139         SkipModelRoot= NULL;
00140         SonsOfAncestorSkeletonModelGroup= NULL;
00141         LightModelRoot= NULL;
00142 
00143         _CurrentTime = 0 ;
00144         _EllapsedTime = 0 ;
00145         _RealTime = 0 ;
00146         _FirstAnimateCall = true ;
00147 
00148         _LightingSystemEnabled= false;
00149         _CoarseMeshLightingUpdate= 50;
00150 
00151         _GlobalWindDirection.set(1,0,0);
00152         // Default as Sithikt wants.
00153         _GlobalWindPower= 0.2f;
00154 
00155         // global manager (created in CDriverUser)
00156         _LodCharacterManager= NULL;
00157         _AsyncTextureManager= NULL;
00158 
00159         _NumRender = 0;
00160 
00161         _MaxSkeletonsInNotCLodForm= 20;
00162 }
00163 // ***************************************************************************
00164 void    CScene::release()
00165 {
00166         // terminate async loading
00167         CAsyncFileManager::terminate();
00168 
00169         // reset the _QuadGridClipManager, => unlink models, and delete clusters.
00170         _QuadGridClipManager.reset();
00171 
00172         // First, delete models and un-register traversals.
00173         CMOT::release();
00174 
00175         for (uint k = 0; k < getNumTrav(); ++k)
00176         {
00177                 ITravScene *ts = dynamic_cast<ITravScene *>(getTrav(k));
00178                 if (ts)
00179                 {
00180                         ts->Scene =     NULL; 
00181                 }
00182         }
00183 
00184         // Unlink the rendertrav.
00185         RenderTraversals.clear();
00186 
00187         // Delete only the 5 default Traversals (owned by CScene).
00188         if (HrcTrav != NULL)
00189         {
00190                 delete  HrcTrav;
00191                 HrcTrav= NULL;
00192         }
00193 
00194         if (ClipTrav != NULL)
00195         {
00196                 delete  ClipTrav;
00197                 ClipTrav= NULL;
00198         }
00199 
00200         if (LightTrav != NULL)
00201         {
00202                 delete  LightTrav;
00203                 LightTrav= NULL;
00204         }
00205 
00206         if (AnimDetailTrav != NULL)
00207         {
00208                 delete  AnimDetailTrav;
00209                 AnimDetailTrav= NULL;
00210         }
00211 
00212         if (LoadBalancingTrav != NULL)
00213         {
00214                 delete LoadBalancingTrav;
00215                 LoadBalancingTrav= NULL;
00216         }
00217 
00218         if (RenderTrav != NULL)
00219         {
00220                 delete  RenderTrav;
00221                 RenderTrav= NULL;
00222         }
00223 
00224         _ShapeBank = NULL;
00225         Root= NULL;
00226         SkipModelRoot= NULL;
00227         SonsOfAncestorSkeletonModelGroup= NULL;
00228         LightModelRoot= NULL;
00229         CurrentCamera= NULL;
00230 
00231         // reset the _LodCharacterManager
00232         if(_LodCharacterManager)
00233                 _LodCharacterManager->reset();
00234 }
00235 // ***************************************************************************
00236 CScene::~CScene()
00237 {
00238         release();
00239 }
00240 // ***************************************************************************
00241 void    CScene::initDefaultTravs()
00242 {
00243         NL3D_MEM_MOT
00244 
00245         // Add the 4 default traversals.
00246         HrcTrav= new CHrcTrav;
00247         ClipTrav= new CClipTrav;
00248         LightTrav= new CLightTrav;
00249         AnimDetailTrav= new CAnimDetailTrav;
00250         LoadBalancingTrav= new CLoadBalancingTrav;
00251         RenderTrav= new CRenderTrav;
00252 
00253         // Register them to the scene.
00254         addTrav(HrcTrav);
00255         addTrav(ClipTrav);
00256         addTrav(LightTrav);
00257         addTrav(AnimDetailTrav);
00258         addTrav(LoadBalancingTrav);
00259         addTrav(RenderTrav);
00260 }
00261 // ***************************************************************************
00262 void    CScene::initDefaultRoots()
00263 {
00264         // Create and set root the default models.
00265         Root= static_cast<CTransform*>(createModel(TransformId));
00266         HrcTrav->setRoot(Root);
00267         ClipTrav->setRoot(Root);
00268 
00269         // need no root for AnimDetailTrav, LoadBalancingTrav, LightTrav and RenderTrav
00270         // because all of them use either the ClipVisibilityList or their own list.
00271         // AnimDetailTrav->setRoot(Root);
00272         // LoadBalancingTrav->setRoot(Root);
00273         // LightTrav->setRoot(Root);
00274         // RenderTrav->setRoot(Root);
00275 
00276 
00277         // The root is always freezed (never move).
00278         Root->freeze();
00279 
00280 
00281         // Create a SkipModelRoot, for CTransform::freezeHRC().
00282         SkipModelRoot= static_cast<CSkipModel*>(createModel(SkipModelId));
00283 
00284 
00285         // Create a SonsOfAncestorSkeletonModelGroup, for models which have a skeleton ancestor
00286         SonsOfAncestorSkeletonModelGroup= static_cast<CRootModel*>(createModel(RootModelId));
00287         // must unlink it from all traversals, because special, only used in CClipTrav::traverse()
00288         HrcTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00289         ClipTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00290         AnimDetailTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00291         LoadBalancingTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00292         LightTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00293         RenderTrav->unlink(NULL, SonsOfAncestorSkeletonModelGroup);
00294         // inform the clipTrav of this model.
00295         ClipTrav->setSonsOfAncestorSkeletonModelGroup(SonsOfAncestorSkeletonModelGroup);
00296 
00297 
00298         // init root for Lighting.
00299         LightModelRoot= static_cast<CRootModel*>(createModel(RootModelId));
00300         // unlink it from all traversals, because special, only used in CLightTrav::traverse()
00301         HrcTrav->unlink(NULL, LightModelRoot);
00302         ClipTrav->unlink(NULL, LightModelRoot);
00303         AnimDetailTrav->unlink(NULL, LightModelRoot);
00304         LoadBalancingTrav->unlink(NULL, LightModelRoot);
00305         LightTrav->unlink(NULL, LightModelRoot);
00306         RenderTrav->unlink(NULL, LightModelRoot);
00307         // inform the LightTrav of this model.
00308         LightTrav->setLightModelRoot(LightModelRoot);
00309 }
00310 
00311 // ***************************************************************************
00312 void    CScene::initCoarseMeshManager ()
00313 {
00314         _StaticCoarseMeshManager=(CCoarseMeshManager*)createModel (CoarseMeshManagerId);
00315         _DynamicCoarseMeshManager=(CCoarseMeshManager*)createModel (CoarseMeshManagerId);
00316 
00317         // Init default texture files
00318         _StaticCoarseMeshManager->setTextureFile (NL3D_SCENE_STATIC_COARSE_MANAGER_TEXTURE);
00319         _DynamicCoarseMeshManager->setTextureFile (NL3D_SCENE_DYNAMIC_COARSE_MANAGER_TEXTURE);
00320 }
00321 
00322 // ***************************************************************************
00323 void    CScene::initGlobalnstanceGroup ()
00324 {
00325         // Init the instance group that represent the world
00326         _GlobalInstanceGroup = new CInstanceGroup;
00327         CCluster *pCluster = (CCluster*)createModel (ClusterId);
00328         CClipTrav *pClipTrav = (CClipTrav*)(getTrav (ClipTravId));
00329         pClipTrav->unlink (NULL, pCluster);
00330         pCluster->Name = "ClusterRoot";
00331         pCluster->Group = _GlobalInstanceGroup;
00332         _GlobalInstanceGroup->addCluster (pCluster);
00333 
00334         // init the ClipTrav->RootCluster.
00335         pClipTrav->RootCluster = _GlobalInstanceGroup->_ClusterInstances[0];
00336 }
00337 
00338 
00339 // ***************************************************************************
00340 void    CScene::initQuadGridClipManager ()
00341 {
00342         // Init clip features.
00343         // setup maxDists clip.
00344         vector<float>   maxDists;
00345         for(uint i=0; i<NL3D_SCENE_QUADGRID_CLIP_NUM_MAXDIST; i++)
00346                 maxDists.push_back(NL3D_QuadGridClipManagerMaxDist[i]);
00347         // init _QuadGridClipManager.
00348         _QuadGridClipManager.init(this, NL3D_SCENE_QUADGRID_CLIP_CLUSTER_SIZE, maxDists, NL3D_QuadGridClipManagerRadiusMax);
00349 }
00350 
00351 
00352 // ***************************************************************************
00353 void    CScene::addTrav(ITrav *v)
00354 {
00355         nlassert(v);
00356         sint    order=0;
00357 
00358         ITravScene      *sv= dynamic_cast<ITravScene*>(v);
00359         if(sv)
00360         {               
00361                 order= sv->getRenderOrder();
00362         }
00363 
00364         // If ok, add it to the render traversal list.
00365         if(order)
00366         {
00367                 RenderTraversals.insert( TTravMap::value_type(order, sv) );
00368         }
00369 
00370         // And register it normally.
00371         CMOT::addTrav(v);
00372 }
00373 // ***************************************************************************
00374 void    CScene::render(bool     doHrcPass)
00375 {
00376         double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime());
00377         _DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime;
00378         _GlobalSystemTime = fNewGlobalSystemTime;
00379         //
00380         ++ _NumRender;
00381         //
00382         nlassert(CurrentCamera);
00383 
00384         // validate models.
00385         CMOT::validateModels();
00386 
00387         // Use the camera to setup Clip / Render pass.
00388         float left, right, bottom, top, znear, zfar;
00389         CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar);
00390 
00391         // setup basic camera.
00392         ClipTrav->setFrustum(left, right, bottom, top, znear, zfar, CurrentCamera->isPerspective());
00393 
00394         RenderTrav->setFrustum (left, right, bottom, top, znear, zfar, CurrentCamera->isPerspective());
00395         RenderTrav->setViewport (_Viewport);
00396 
00397         LoadBalancingTrav->setFrustum (left, right, bottom, top, znear, zfar, CurrentCamera->isPerspective());
00398 
00399 
00400         // Set the renderTrav for cliptrav.
00401         ClipTrav->setHrcTrav (HrcTrav);
00402         ClipTrav->setLightTrav (LightTrav);
00403         ClipTrav->setAnimDetailTrav (AnimDetailTrav);
00404         ClipTrav->setLoadBalancingTrav (LoadBalancingTrav);
00405         ClipTrav->setRenderTrav (RenderTrav);
00406         ClipTrav->Camera = CurrentCamera;
00407         ClipTrav->setQuadGridClipManager (&_QuadGridClipManager);
00408 
00409         // For all render traversals, traverse them (except the Hrc one), in ascending order.
00410         TTravMap::iterator      it;
00411         for(it= RenderTraversals.begin(); it!= RenderTraversals.end(); it++)
00412         {
00413                 ITravScene      *trav= (*it).second;
00414                 // TestYoyo
00415                 /*if(AnimDetailTravId!=trav->getClassId() && 
00416                         LoadBalancingTravId!=trav->getClassId() && 
00417                         HrcTravId!=trav->getClassId() && 
00418                         ClipTravId!=trav->getClassId() )
00419                         continue;*/
00420                 // maybe don't traverse HRC pass.
00421                 if(doHrcPass || HrcTravId!=trav->getClassId())
00422                         // Go!
00423                         trav->traverse();
00424 
00425                 // if HrcTrav done, set World Camera matrix for Clip and Render.
00426                 if(HrcTravId==trav->getClassId())
00427                 {
00428                         CTransformHrcObs        *camObs= (CTransformHrcObs*)CMOT::getModelObs(CurrentCamera, HrcTravId);
00429                         ClipTrav->setCamMatrix(camObs->WorldMatrix);
00430                         RenderTrav->setCamMatrix (camObs->WorldMatrix);
00431                         LoadBalancingTrav->setCamMatrix (camObs->WorldMatrix);
00432                 }
00433         }
00434 
00438         _ParticleSystemManager.refreshModels(ClipTrav->WorldFrustumPyramid, ClipTrav->CamPos);
00439         
00440         // Wainting Instance handling
00441         double deltaT = _DeltaSystemTimeBetweenRender;
00442         clamp (deltaT, 0.01, 0.1);
00443         updateWaitingInstances(deltaT);
00444 
00445 }
00446 
00447 // ***************************************************************************
00448 void CScene::updateWaitingInstances(double systemTimeEllapsed)
00449 {       
00450         // First set up max AGP upload
00451         double fMaxBytesToUp = 100 * 256 * 256 * systemTimeEllapsed;    
00452         _ShapeBank->setMaxBytesToUpload ((uint32)fMaxBytesToUp);
00453         // Parse all the waiting instance
00454         _ShapeBank->processWaitingShapes ();    // Process waiting shapes load shape, texture, and lightmaps
00455                                                                                         // and upload all maps to VRAM pieces by pieces
00456         TWaitingInstancesMMap::iterator wimmIt = _WaitingInstances.begin();
00457         while( wimmIt != _WaitingInstances.end() )
00458         {
00459                 CShapeBank::TShapeState st = _ShapeBank->isPresent (wimmIt->first);
00460                 if (st == CShapeBank::AsyncLoad_Error)
00461                 {
00462                         // Delete the waiting instance - Nobody can be informed of that...
00463                         TWaitingInstancesMMap::iterator itDel= wimmIt;
00464                         ++wimmIt;
00465                         _WaitingInstances.erase(itDel);
00466                 }
00467                 else if (st == CShapeBank::Present)
00468                 {
00469                         // Then create a reference to the shape
00470                         *(wimmIt->second) = _ShapeBank->addRef(wimmIt->first)->createInstance (*this);
00471                         // Delete the waiting instance
00472                         TWaitingInstancesMMap::iterator itDel= wimmIt;
00473                         ++wimmIt;
00474                         _WaitingInstances.erase(itDel);
00475                 }
00476                 else // st == CShapeBank::NotPresent or loading
00477                 {
00478                         ++wimmIt;
00479                 }
00480         }
00481 }
00482 
00483 // ***************************************************************************
00484 void    CScene::setDriver(IDriver *drv)
00485 {
00486         if (RenderTrav != NULL)
00487                 RenderTrav->setDriver(drv);
00488 }
00489 
00490 // ***************************************************************************
00491 IDriver *CScene::getDriver() const
00492 {
00493         if (RenderTrav != NULL)
00494                 return RenderTrav->getDriver();
00495         else
00496                 return NULL;
00497 }
00498 
00499 
00500 // ***************************************************************************
00501 // ***************************************************************************
00502 // Shape mgt.
00503 // ***************************************************************************
00504 // ***************************************************************************
00505 
00506 // ***************************************************************************
00507 
00508 void CScene::setShapeBank(CShapeBank*pShapeBank)
00509 {
00510         _ShapeBank = pShapeBank;
00511 }
00512 
00513 // ***************************************************************************
00514 
00515 CTransformShape *CScene::createInstance(const string &shapeName)
00516 {
00517         NL3D_MEM_INSTANCE
00518 
00519         // We must attach a bank to the scene (a ShapeBank handle the shape caches and 
00520         // the creation/deletion of the instances)
00521         nlassert( _ShapeBank != NULL );
00522         
00523         // If the shape is not present in the bank
00524         if (_ShapeBank->isPresent( shapeName ) != CShapeBank::Present)
00525         {
00526                 // Load it from file
00527                 _ShapeBank->load( shapeName );
00528                 if (_ShapeBank->isPresent( shapeName ) != CShapeBank::Present)
00529                 {
00530                         return NULL;
00531                 }
00532         }
00533         // Then create a reference to the shape
00534         CTransformShape *pTShp = _ShapeBank->addRef( shapeName )->createInstance(*this);
00535         if (pTShp) pTShp->setDistMax(pTShp->Shape->getDistMax());
00536 #ifdef NL_DEBUG
00537 //      pTShp->NameForDebug = shapeName; // \todo traptemp
00538 #endif
00539 
00540         // Look if this instance get lightmap information
00541 #if defined(__GNUC__) && __GNUC__ < 3
00542         CMeshBase *pMB = (CMeshBase*)((IShape*)(pTShp->Shape));
00543 #else // not GNUC
00544         CMeshBase *pMB = dynamic_cast<CMeshBase*>((IShape*)(pTShp->Shape));
00545 #endif // not GNUC
00546         CMeshBaseInstance *pMBI = dynamic_cast<CMeshBaseInstance*>( pTShp );
00547         if( ( pMB != NULL ) && ( pMBI != NULL ) )
00548         { // Try to bind to automatic animation
00549                 CMeshBase::TLightInfoMap::iterator itLM = pMB->_LightInfos.begin();
00550                 while( itLM != pMB->_LightInfos.end() )
00551                 {       // Is it the same name in the name of the lightmap ?
00552                         set<CAnimatedLightmap*>::iterator itSet = _AnimatedLightmap.begin();
00553                         while( itSet != _AnimatedLightmap.end() )
00554                         {
00555                                 const char *GroupName = strchr( (*itSet)->getName().c_str(), '.')+1;
00556                                 if( GroupName == itLM->first )
00557                                 {
00558                                         // Ok bind automatic animation
00559                                         pMBI->setAnimatedLightmap( *itSet );
00560                                 }
00561                                 ++itSet;
00562                         }
00563                         ++itLM;
00564                 }
00565 
00566                 // Auto animations
00567                 //==========================
00568 
00569                 if (_AutomaticAnimationSet)
00570                 {
00571                         if (pMB->getAutoAnim())
00572                         {
00573                                 
00574                                 std::string animName = CFile::getFilenameWithoutExtension(shapeName);                   
00575                                 uint animID = _AutomaticAnimationSet->getAnimationIdByName(animName);
00576                                 if (animID != CAnimationSet::NotFound)
00577                                 {
00578                                         CChannelMixer *chanMix = new CChannelMixer;
00579                                         chanMix->setAnimationSet((CAnimationSet *) _AutomaticAnimationSet);
00580                                         chanMix->setSlotAnimation(0, animID);
00581                                         
00582                                         pMBI->registerToChannelMixer(chanMix, "");
00583                                         // Gives this object ownership of the channel mixer so we don't need to keep track of it
00584                                         pMBI->setChannelMixerOwnerShip(true);
00585                                 }
00586                         }       
00587                 }
00588         }
00589 
00590         return pTShp;
00591 }
00592 
00593 // ***************************************************************************
00594 
00595 void CScene::createInstanceAsync(const string &shapeName, CTransformShape **pInstance)
00596 {
00597         // We must attach a bank to the scene (a ShapeBank handle the shape caches and 
00598         // the creation/deletion of the instances)
00599         nlassert( _ShapeBank != NULL );
00600         *pInstance = NULL;
00601         // Add the instance request
00602         _WaitingInstances.insert(TWaitingInstancesMMap::value_type(shapeName,pInstance));
00603         // If the shape is not present in the bank
00604         if (_ShapeBank->isPresent( shapeName ) != CShapeBank::Present)
00605         {
00606                 // Load it from file asynchronously
00607                 _ShapeBank->loadAsync( strlwr(shapeName), getDriver() );
00608         }
00609 }
00610 
00611 // ***************************************************************************
00612 void CScene::deleteInstance(CTransformShape *pTrfmShp)
00613 {
00614         IShape *pShp = NULL;
00615         if( pTrfmShp == NULL )
00616                 return;
00617 
00618         pShp = pTrfmShp->Shape;
00619         
00620         deleteModel( pTrfmShp );
00621 
00622         if (pShp)
00623         {
00624                 // Even if model already deleted by smarptr the release function works
00625                 _ShapeBank->release( pShp );
00626         }
00627         
00628 }
00629 
00630 // ***************************************************************************
00631 // ANIMATION FOR LIGHT MAPS
00632 void CScene::setAutoAnim( CAnimation *pAnim )
00633 {
00634         uint nAnimNb;
00635         // Reset the automatic animation if no animation wanted
00636         if( pAnim == NULL )
00637         {
00638                 set<CAnimatedLightmap*>::iterator itSAL = _AnimatedLightmap.begin();
00639                 while( itSAL != _AnimatedLightmap.end() )
00640                 {
00641                         delete *itSAL;
00642                         ++itSAL;
00643                 }
00644                 _AnimatedLightmap.clear();
00645                 nAnimNb = _LightmapAnimations.getAnimationIdByName("Automatic");
00646                 if( nAnimNb != CAnimationSet::NotFound )
00647                 {
00648                         CAnimation *anim = _LightmapAnimations.getAnimation( nAnimNb );
00649                         delete anim;
00650                 }
00651                 _LightmapAnimations.reset();
00652                 _LMAnimsAuto.deleteAll();
00653                 return;
00654         }
00655 
00656 
00657         set<string> setTrackNames;
00658         pAnim->getTrackNames( setTrackNames );
00659 
00660         nAnimNb = _LightmapAnimations.addAnimation( "Automatic", pAnim );
00661         _LightmapAnimations.build();
00662         CChannelMixer *cm = new CChannelMixer();
00663         cm->setAnimationSet( &_LightmapAnimations );
00664 
00665         set<string>::iterator itSel = setTrackNames.begin();
00666         while ( itSel != setTrackNames.end() )
00667         {
00668                 string ate = *itSel;
00669                 if( strncmp( itSel->c_str(), "LightmapController.", 19 ) == 0 )
00670                 {
00671                         CAnimatedLightmap *animLM = new CAnimatedLightmap();
00672                         animLM->setName( *itSel );
00673 
00674                         cm->addChannel( animLM->getName(), animLM, animLM->getValue(CAnimatedLightmap::FactorValue),
00675                                 animLM->getDefaultTrack(CAnimatedLightmap::FactorValue), CAnimatedLightmap::FactorValue, 
00676                                 CAnimatedLightmap::OwnerBit, false);
00677 
00678                         //animLM->registerToChannelMixer( cm, "" );
00679                         _AnimatedLightmap.insert( animLM );
00680 
00681                 }
00682                 ++itSel;
00683         }
00684 
00685         CAnimationPlaylist *pl = new CAnimationPlaylist();
00686         pl->setAnimation( 0, nAnimNb );
00687         pl->setWrapMode( 0, CAnimationPlaylist::Repeat );
00688         _LMAnimsAuto.addPlaylist(pl,cm);
00689 }
00690 
00691 // ***************************************************************************
00692 
00693 void CScene::loadLightmapAutoAnim( const std::string &filename )
00694 {
00695         try
00696         {
00697                 CAnimation *anim = new CAnimation();
00698                 CIFile fIn( CPath::lookup(filename) );
00699                 anim->serial( fIn );
00700 
00701                 setAutoAnim( anim );
00702         }
00703         catch(EPathNotFound &)
00704         {
00705                 return;
00706         }
00707 }
00708 
00709 // ***************************************************************************
00710 void CScene::animate( TGlobalAnimationTime atTime )
00711 {
00712         if (_FirstAnimateCall)
00713         {
00714                 _RealTime = atTime ;
00715                 // dummy value for first frame
00716                 _EllapsedTime = 0.01f ;
00717                 _FirstAnimateCall = false ;
00718         }
00719         else
00720         {
00721                 _EllapsedTime = (float) (atTime - _RealTime) ;
00722                 //nlassert(_EllapsedTime >= 0);
00723                 if (_EllapsedTime < 0.0f)       // NT WorkStation PATCH (Yes you are not dreaming
00724                         _EllapsedTime = 0.01f;  // deltaTime can be less than zero!!)
00725                 _EllapsedTime = fabsf(_EllapsedTime);
00726                 _RealTime = atTime ;
00727                 _CurrentTime += _EllapsedTime ;
00728         }
00729         
00730         _LMAnimsAuto.animate( atTime );
00731         _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems
00732 
00733 
00734         // Change PointLightFactors of all pointLights in registered Igs.
00735         //----------------
00736         static  vector<string>  anlNames;
00737         static  vector<CRGBA>   anlFactors;
00738         anlNames.clear();
00739         anlFactors.clear();
00740         // First list all current AnimatedLightmaps (for faster vector iteration per ig)
00741         std::set<CAnimatedLightmap*>::iterator  itAnlSet;
00742         for(itAnlSet= _AnimatedLightmap.begin(); itAnlSet!=_AnimatedLightmap.end(); itAnlSet++)
00743         {
00744                 const char *GroupName = strchr( (*itAnlSet)->getName().c_str(), '.')+1;
00745                 // Append to vector
00746                 anlNames.push_back(GroupName);
00747                 anlFactors.push_back( (*itAnlSet)->getFactor() );
00748         }
00749 
00750         // For all registered igs.
00751         ItAnimatedIgSet         itAnIgSet;
00752         for(itAnIgSet= _AnimatedIgSet.begin(); itAnIgSet!=_AnimatedIgSet.end(); itAnIgSet++)
00753         {
00754                 CInstanceGroup  *ig= *itAnIgSet;
00755                 // For all Animated Light Factor
00756                 for(uint i= 0; i<anlNames.size(); i++)
00757                 {
00758                         ig->setPointLightFactor(anlNames[i], anlFactors[i]);
00759                 }
00760         }
00761 }
00762 
00763 
00764 // ***************************************************************************
00765 float   CScene::getNbFaceAsked () const
00766 {
00767         nlassert(LoadBalancingTrav);
00768         return LoadBalancingTrav->getNbFaceAsked ();
00769 }
00770 
00771 
00772 // ***************************************************************************
00773 void    CScene::setGroupLoadMaxPolygon(const std::string &group, uint nFaces)
00774 {
00775         nlassert(LoadBalancingTrav);
00776         nFaces= max(nFaces, (uint)1);
00777         LoadBalancingTrav->setGroupNbFaceWanted(group, nFaces);
00778 }
00779 // ***************************************************************************
00780 uint    CScene::getGroupLoadMaxPolygon(const std::string &group)
00781 {
00782         nlassert(LoadBalancingTrav);
00783         return LoadBalancingTrav->getGroupNbFaceWanted(group);
00784 }
00785 // ***************************************************************************
00786 float   CScene::getGroupNbFaceAsked (const std::string &group) const
00787 {
00788         nlassert(LoadBalancingTrav);
00789         return LoadBalancingTrav->getGroupNbFaceAsked(group);
00790 }
00791 
00792 
00793 
00794 // ***************************************************************************
00795 void    CScene::setPolygonBalancingMode(TPolygonBalancingMode polBalMode)
00796 {
00797         nlassert(LoadBalancingTrav);
00798         LoadBalancingTrav->PolygonBalancingMode= (CLoadBalancingGroup::TPolygonBalancingMode)(uint)polBalMode;
00799 }
00800 
00801 
00802 // ***************************************************************************
00803 CScene::TPolygonBalancingMode   CScene::getPolygonBalancingMode() const
00804 {
00805         nlassert(LoadBalancingTrav);
00806         return (CScene::TPolygonBalancingMode)(uint)LoadBalancingTrav->PolygonBalancingMode;
00807 }
00808 
00809 // ***************************************************************************
00810 void  CScene::setLayersRenderingOrder(bool directOrder /*= true*/)
00811 {
00812         nlassert(RenderTrav);
00813         RenderTrav->setLayersRenderingOrder(directOrder);
00814 }
00815 
00816 // ***************************************************************************
00817 bool  CScene::getLayersRenderingOrder() const
00818 {
00819         nlassert(RenderTrav);
00820         return  RenderTrav->getLayersRenderingOrder();
00821 }
00822 
00823 // ***************************************************************************
00824 CParticleSystemManager &CScene::getParticleSystemManager()
00825 {
00826         return _ParticleSystemManager;
00827 }
00828 
00829 
00830 // ***************************************************************************
00831 // ***************************************************************************
00832 // Lighting Mgt.
00833 // ***************************************************************************
00834 // ***************************************************************************
00835 
00836 
00837 // ***************************************************************************
00838 void                    CScene::enableLightingSystem(bool enable)
00839 {
00840         _LightingSystemEnabled= enable;
00841 
00842         // Set to RenderTrav and LightTrav
00843         RenderTrav->LightingSystemEnabled= _LightingSystemEnabled;
00844         LightTrav->LightingSystemEnabled= _LightingSystemEnabled;
00845 }
00846 
00847 
00848 // ***************************************************************************
00849 void                    CScene::setAmbientGlobal(NLMISC::CRGBA ambient)
00850 {
00851         RenderTrav->AmbientGlobal= ambient;
00852 }
00853 void                    CScene::setSunAmbient(NLMISC::CRGBA ambient)
00854 {
00855         RenderTrav->SunAmbient= ambient;
00856 }
00857 void                    CScene::setSunDiffuse(NLMISC::CRGBA diffuse)
00858 {
00859         RenderTrav->SunDiffuse= diffuse;
00860 }
00861 void                    CScene::setSunSpecular(NLMISC::CRGBA specular)
00862 {
00863         RenderTrav->SunSpecular= specular;
00864 }
00865 void                    CScene::setSunDirection(const NLMISC::CVector &direction)
00866 {
00867         RenderTrav->setSunDirection(direction);
00868 }
00869 
00870 
00871 // ***************************************************************************
00872 NLMISC::CRGBA   CScene::getAmbientGlobal() const
00873 {
00874         return RenderTrav->AmbientGlobal;
00875 }
00876 NLMISC::CRGBA   CScene::getSunAmbient() const
00877 {
00878         return RenderTrav->SunAmbient;
00879 }
00880 NLMISC::CRGBA   CScene::getSunDiffuse() const
00881 {
00882         return RenderTrav->SunDiffuse;
00883 }
00884 NLMISC::CRGBA   CScene::getSunSpecular() const
00885 {
00886         return RenderTrav->SunSpecular;
00887 }
00888 NLMISC::CVector CScene::getSunDirection() const
00889 {
00890         return RenderTrav->getSunDirection();
00891 }
00892 
00893 
00894 // ***************************************************************************
00895 void            CScene::setMaxLightContribution(uint nlights)
00896 {
00897         LightTrav->LightingManager.setMaxLightContribution(nlights);
00898 }
00899 uint            CScene::getMaxLightContribution() const
00900 {
00901         return LightTrav->LightingManager.getMaxLightContribution();
00902 }
00903 
00904 void            CScene::setLightTransitionThreshold(float lightTransitionThreshold)
00905 {
00906         LightTrav->LightingManager.setLightTransitionThreshold(lightTransitionThreshold);
00907 }
00908 float           CScene::getLightTransitionThreshold() const
00909 {
00910         return LightTrav->LightingManager.getLightTransitionThreshold();
00911 }
00912 
00913 
00914 // ***************************************************************************
00915 void            CScene::addInstanceGroupForLightAnimation(CInstanceGroup *ig)
00916 {
00917         nlassert( ig );
00918         nlassert( _AnimatedIgSet.find(ig) == _AnimatedIgSet.end() );
00919         _AnimatedIgSet.insert(ig);
00920 }
00921 
00922 // ***************************************************************************
00923 void            CScene::removeInstanceGroupForLightAnimation(CInstanceGroup *ig)
00924 {
00925         nlassert( ig );
00926         ItAnimatedIgSet         itIg= _AnimatedIgSet.find(ig);
00927         nlassert( itIg != _AnimatedIgSet.end() );
00928         _AnimatedIgSet.erase(itIg);
00929 }
00930 
00931 
00932 // ***************************************************************************
00933 void            CScene::setCoarseMeshLightingUpdate(uint8 period)
00934 {
00935         _CoarseMeshLightingUpdate= max((uint8)1, period);
00936 }
00937 
00938 
00939 // ***************************************************************************
00940 // ***************************************************************************
00942 // ***************************************************************************
00943 // ***************************************************************************
00944 
00945 // ***************************************************************************
00946 void            CScene::setGlobalWindPower(float gwp)
00947 {
00948         _GlobalWindPower= gwp;
00949 }
00950 // ***************************************************************************
00951 void            CScene::setGlobalWindDirection(const CVector &gwd)
00952 {
00953         _GlobalWindDirection= gwd;
00954         _GlobalWindDirection.z= 0;
00955         _GlobalWindDirection.normalize();
00956 }
00957 
00958 
00959 // ***************************************************************************
00960 // ***************************************************************************
00962 // ***************************************************************************
00963 // ***************************************************************************
00964 
00965 // ***************************************************************************
00966 CScene::ItSkeletonModelList     CScene::appendSkeletonModelToList(CSkeletonModel *skel)
00967 {
00968         _SkeletonModelList.push_front(skel);
00969         return _SkeletonModelList.begin();
00970 }
00971 
00972 // ***************************************************************************
00973 void                                    CScene::eraseSkeletonModelToList(CScene::ItSkeletonModelList    it)
00974 {
00975         _SkeletonModelList.erase(it);
00976 }
00977 
00978 
00979 } // NL3D