00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "nel/misc/types_nl.h"
00029 #include "3d/clip_trav.h"
00030 #include "3d/hrc_trav.h"
00031 #include "3d/render_trav.h"
00032 #include "3d/anim_detail_trav.h"
00033 #include "3d/load_balancing_trav.h"
00034 #include "3d/cluster.h"
00035 #include "3d/scene_group.h"
00036 #include "3d/transform_shape.h"
00037 #include "3d/camera.h"
00038 #include "3d/quad_grid_clip_cluster.h"
00039 #include "3d/quad_grid_clip_manager.h"
00040 #include "3d/root_model.h"
00041 #include "nel/misc/hierarchical_timer.h"
00042 #include "3d/scene.h"
00043 #include "3d/skeleton_model.h"
00044 #include "3d/fast_floor.h"
00045
00046 using namespace std;
00047 using namespace NLMISC;
00048
00049
00050 namespace NL3D
00051 {
00052
00053
00054
00055 CClipTrav::CClipTrav() : ViewPyramid(6), WorldPyramid(6)
00056 {
00057 _VisibleList.reserve(1024);
00058 CurrentDate = 0;
00059 Accel.create (64, 16.0f);
00060
00061 ForceNoFrustumClip= false;
00062 _QuadGridClipManager= NULL;
00063
00064
00065 HrcTrav= NULL;
00066 AnimDetailTrav= NULL;
00067 LoadBalancingTrav= NULL;
00068 LightTrav= NULL;
00069 RenderTrav = NULL;
00070 }
00071
00072
00073 CClipTrav::~CClipTrav()
00074 {
00075 }
00076
00077
00078 IObs* CClipTrav::createDefaultObs() const
00079 {
00080 return new CDefaultClipObs;
00081 }
00082
00083
00084 bool CClipTrav::fullSearch (vector<CCluster*>& result, CInstanceGroup *pIG, CVector& pos)
00085 {
00086 uint32 i, j;
00087
00088 for (i = 0; i < pIG->_ClusterInstances.size(); ++i)
00089 {
00090 for (j = 0; j < pIG->_ClusterInstances[i]->Children.size(); ++j)
00091 {
00092 if (fullSearch (result, pIG->_ClusterInstances[i]->Children[j]->Group, pos))
00093 return true;
00094 }
00095 }
00096
00097 for (i = 0; i < pIG->_ClusterInstances.size(); ++i)
00098 {
00099 if (pIG->_ClusterInstances[i]->isIn(pos))
00100 result.push_back (pIG->_ClusterInstances[i]);
00101 }
00102 if (result.size() > 0)
00103 return true;
00104 return false;
00105 }
00106
00107
00108 void CClipTrav::traverse()
00109 {
00110 H_AUTO( NL3D_TravClip );
00111
00112
00113 ++CurrentDate;
00114
00115 ITravCameraScene::update();
00116
00117
00118 CVector pfoc(0,0,0);
00119 CVector lb(Left, Near, Bottom );
00120 CVector lt(Left, Near, Top );
00121 CVector rb(Right, Near, Bottom );
00122 CVector rt(Right, Near, Top );
00123
00124 CVector lbFar(Left, Far, Bottom);
00125 CVector ltFar(Left, Far, Top );
00126 CVector rtFar(Right, Far, Top );
00127
00128 uint32 i, j;
00129
00130 ViewPyramid[NL3D_CLIP_PLANE_NEAR].make(lt, lb, rt);
00131 ViewPyramid[NL3D_CLIP_PLANE_FAR].make(lbFar, ltFar, rtFar);
00132
00133 ViewPyramid[NL3D_CLIP_PLANE_LEFT].make(pfoc, lt, lb);
00134 ViewPyramid[NL3D_CLIP_PLANE_TOP].make(pfoc, rt, lt);
00135 ViewPyramid[NL3D_CLIP_PLANE_RIGHT].make(pfoc, rb, rt);
00136 ViewPyramid[NL3D_CLIP_PLANE_BOTTOM].make(pfoc, lb, rb);
00137
00138
00139
00140
00141 for (i = 0; i < 6; i++)
00142 {
00143 WorldPyramid[i]= ViewPyramid[i]*ViewMatrix;
00144 }
00145
00146
00147 WorldFrustumPyramid= WorldPyramid;
00148
00149
00150
00151 if(_QuadGridClipManager)
00152 {
00153 _QuadGridClipManager->updateClustersFromCamera(this, CamPos);
00154 }
00155
00156
00157 nlassert(AnimDetailTrav && LoadBalancingTrav && LightTrav && RenderTrav);
00158 AnimDetailTrav->clearVisibleList();
00159 LoadBalancingTrav->clearVisibleList();
00160 LightTrav->clearLightedList();
00161 RenderTrav->clearRenderList();
00162
00163
00164
00165
00166
00167
00168
00169
00170 for (i=0;i<_VisibleList.size();i++)
00171 {
00172
00173 if( _VisibleList[i] )
00174 {
00175
00176 _VisibleList[i]->Visible= false;
00177
00178 _VisibleList[i]->_IndexInVisibleList= -1;
00179 }
00180 }
00181
00182 _VisibleList.clear();
00183
00184
00185
00186
00187
00188
00189 static vector<CCluster*> vCluster;
00190
00191 vCluster.clear();
00192
00193
00194 bool bInWorld = true;
00195 CQuadGrid<CCluster*>::CIterator itAcc;
00196 if (Camera->getClusterSystem() == (CInstanceGroup*)-1)
00197 {
00198 if (fullSearch(vCluster, RootCluster->Group, CamPos))
00199 bInWorld = false;
00200 for (i = 0; i < vCluster.size(); ++i)
00201 link(NULL, vCluster[i]);
00202 }
00203 else
00204 {
00205 Accel.select (CamPos, CamPos);
00206 itAcc = Accel.begin();
00207 while (itAcc != Accel.end())
00208 {
00209 CCluster *pCluster = *itAcc;
00210 if (pCluster->Group == Camera->getClusterSystem())
00211 if (pCluster->isIn (CamPos))
00212 {
00213 link (NULL, pCluster);
00214 vCluster.push_back (pCluster);
00215 bInWorld = false;
00216 }
00217 ++itAcc;
00218 }
00219 }
00220
00222 if (bInWorld)
00223 {
00224 link (NULL, RootCluster);
00225 vCluster.push_back (RootCluster);
00226 }
00227
00228
00229
00230
00231
00232
00233 for (i = 0; i < HrcTrav->_MovingObjects.size(); ++i)
00234 {
00235 CTransformShape *pTfmShp = dynamic_cast<CTransformShape*>(HrcTrav->_MovingObjects[i]);
00236 if (pTfmShp == NULL)
00237 continue;
00238
00239 static vector<IModel*> vModels;
00240 vModels.clear();
00241 IModel *pFather = getFirstParent (HrcTrav->_MovingObjects[i]);
00242 while (pFather != NULL)
00243 {
00244
00245 if ( dynamic_cast<CCluster*>(pFather)!= NULL || dynamic_cast<CQuadGridClipCluster*>(pFather)!=NULL )
00246 {
00247 vModels.push_back (pFather);
00248 }
00249 pFather = getNextParent (HrcTrav->_MovingObjects[i]);
00250 }
00251 for (j = 0; j < vModels.size(); ++j)
00252 {
00253 unlink (vModels[j], HrcTrav->_MovingObjects[i]);
00254 }
00255 unlink (NULL, HrcTrav->_MovingObjects[i]);
00256 }
00257
00258
00259 for (i = 0; i < HrcTrav->_MovingObjects.size(); ++i)
00260 {
00261 CTransformShape *pTfmShp = dynamic_cast<CTransformShape*>(HrcTrav->_MovingObjects[i]);
00262 if (pTfmShp == NULL)
00263 continue;
00264
00265 bool bInWorld = true;
00266 CAABBox box;
00267 pTfmShp->getAABBox (box);
00268
00269 CVector c = box.getCenter();
00270 CVector p = box.getCenter()+box.getHalfSize();
00271 const CMatrix &wm = pTfmShp->getWorldMatrix();
00272 c = wm * c;
00273 p = wm * p;
00274 float s = (p - c).norm();
00275
00276 Accel.select (c+CVector(s,s,s), c+CVector(-s,-s,-s));
00277 itAcc = Accel.begin();
00278 while (itAcc != Accel.end())
00279 {
00280 CCluster *pCluster = *itAcc;
00281 if (pCluster->Group == pTfmShp->getClusterSystem())
00282 if (pCluster->isIn (c,s))
00283 {
00284 link (pCluster, pTfmShp);
00285 bInWorld = false;
00286 }
00287 ++itAcc;
00288 }
00289
00290
00291 if (bInWorld)
00292 {
00293 if( _QuadGridClipManager && pTfmShp->isQuadGridClipEnabled() )
00294 {
00295
00296 if(!_QuadGridClipManager->linkModel(pTfmShp, this))
00297
00298 link (RootCluster, pTfmShp);
00299 }
00300 else
00301 {
00302 link (RootCluster, pTfmShp);
00303 }
00304 }
00305 }
00306
00307
00308
00309
00310
00311 if (Root)
00312 Root->traverse (NULL);
00313
00314
00315
00316 for (i = 0; i < vCluster.size(); ++i)
00317 {
00318 unlink (NULL, vCluster[i]);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 loadBalanceSkeletonCLod();
00329
00330
00331
00332
00333
00334 if (SonsOfAncestorSkeletonModelGroup)
00335 SonsOfAncestorSkeletonModelGroup->getObs(ClipTravId)->traverse(NULL);
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 CScene::ItSkeletonModelList itSkel;
00346 for(itSkel= Scene->getSkeletonModelListBegin(); itSkel!=Scene->getSkeletonModelListEnd(); itSkel++)
00347 {
00348 CSkeletonModel *sm= *itSkel;
00349
00350 if(sm->isClipVisible())
00351 sm->updateSkinRenderLists();
00352 }
00353
00354 }
00355
00356
00357
00358 void CClipTrav::setHrcTrav (CHrcTrav* trav)
00359 {
00360 HrcTrav = trav;
00361 }
00362
00363
00364 void CClipTrav::setAnimDetailTrav(CAnimDetailTrav *trav)
00365 {
00366 AnimDetailTrav= trav;
00367 }
00368
00369
00370 void CClipTrav::setLoadBalancingTrav(CLoadBalancingTrav *trav)
00371 {
00372 LoadBalancingTrav= trav;
00373 }
00374
00375
00376 void CClipTrav::setLightTrav (CLightTrav* trav)
00377 {
00378 LightTrav = trav;
00379 }
00380
00381
00382 void CClipTrav::setRenderTrav (CRenderTrav* trav)
00383 {
00384 RenderTrav = trav;
00385 }
00386
00387
00388 void CClipTrav::setQuadGridClipManager(CQuadGridClipManager *mgr)
00389 {
00390 _QuadGridClipManager= mgr;
00391 }
00392
00393
00394 void CClipTrav::registerCluster (CCluster* pCluster)
00395 {
00396 pCluster->AccelIt = Accel.insert (pCluster->getBBox().getMin(), pCluster->getBBox().getMax(), pCluster);
00397 }
00398
00399
00400 void CClipTrav::unregisterCluster (CCluster* pCluster)
00401 {
00402 Accel.selectAll();
00403 CQuadGrid<CCluster*>::CIterator itAcc = Accel.begin();
00404 while (itAcc != Accel.end())
00405 {
00406 CCluster *pC = *itAcc;
00407 if (pCluster == pC)
00408 {
00409 Accel.erase (itAcc);
00410 break;
00411 }
00412 ++itAcc;
00413 }
00414 }
00415
00416
00417
00418 void CClipTrav::setSonsOfAncestorSkeletonModelGroup(CRootModel *m)
00419 {
00420 SonsOfAncestorSkeletonModelGroup= m;
00421 }
00422
00423
00424
00425 void CClipTrav::addVisibleObs(CTransformClipObs *obs)
00426 {
00427 obs->_IndexInVisibleList= _VisibleList.size();
00428 _VisibleList.push_back(obs);
00429 }
00430
00431
00432
00433 void CClipTrav::loadBalanceSkeletonCLod()
00434 {
00435 CScene::ItSkeletonModelList itSkel;
00436 _TmpSortSkeletons.clear();
00437
00438
00439 for(itSkel= Scene->getSkeletonModelListBegin(); itSkel!=Scene->getSkeletonModelListEnd(); itSkel++)
00440 {
00441 CSkeletonModel *sm= *itSkel;
00442 float pr= sm->computeDisplayLodCharacterPriority();
00443
00444 if(pr>0)
00445 {
00446
00447 if(pr>1)
00448 sm->setDisplayLodCharacterFlag(true);
00449
00450 else
00451 {
00452 CSkeletonKey key;
00453
00454 key.Priority= OptFastFloor(pr*0xFFFFFF00);
00455 key.SkeletonModel= sm;
00456 _TmpSortSkeletons.push_back(key);
00457 }
00458 }
00459 }
00460
00461
00462 uint nMaxSkelsInNotCLodForm= Scene->getMaxSkeletonsInNotCLodForm();
00463
00464 if(_TmpSortSkeletons.size()>nMaxSkelsInNotCLodForm)
00465 {
00466 sort(_TmpSortSkeletons.begin(), _TmpSortSkeletons.end());
00467 }
00468
00469
00470 uint n= min(nMaxSkelsInNotCLodForm, _TmpSortSkeletons.size());
00471 uint i;
00472
00473 for(i=0;i<n;i++)
00474 {
00475 _TmpSortSkeletons[i].SkeletonModel->setDisplayLodCharacterFlag(false);
00476 }
00477
00478 for(i=n;i<_TmpSortSkeletons.size();i++)
00479 {
00480 _TmpSortSkeletons[i].SkeletonModel->setDisplayLodCharacterFlag(true);
00481 }
00482
00483 }
00484
00485
00486 }