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/clip__trav_8cpp-source.html | 554 +++++++++++++++++++++++++++ 1 file changed, 554 insertions(+) create mode 100644 docs/doxygen/nel/clip__trav_8cpp-source.html (limited to 'docs/doxygen/nel/clip__trav_8cpp-source.html') diff --git a/docs/doxygen/nel/clip__trav_8cpp-source.html b/docs/doxygen/nel/clip__trav_8cpp-source.html new file mode 100644 index 00000000..6d69ed98 --- /dev/null +++ b/docs/doxygen/nel/clip__trav_8cpp-source.html @@ -0,0 +1,554 @@ + + + + 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  
+

clip_trav.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 "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         // Increment the current date of the traversal
+00113         ++CurrentDate;
+00114         // Update Clip infos.
+00115         ITravCameraScene::update();
+00116 
+00117         // Compute pyramid in view basis.
+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         // Compute pyramid in World basis.
+00139         // The vector transformation M of a plane p is computed as p*M-1.
+00140         // Here, ViewMatrix== CamMatrix-1. Hence the following formula.
+00141         for (i = 0; i < 6; i++)
+00142         {
+00143                 WorldPyramid[i]= ViewPyramid[i]*ViewMatrix;
+00144         }
+00145 
+00146         // bkup this pyramid (because this one may be modified by the cluster system).
+00147         WorldFrustumPyramid= WorldPyramid;
+00148 
+00149 
+00150         // update the QuadGridClipManager.
+00151         if(_QuadGridClipManager)
+00152         {
+00153                 _QuadGridClipManager->updateClustersFromCamera(this, CamPos);
+00154         }
+00155 
+00156         // Clear the traversals list.
+00157         nlassert(AnimDetailTrav && LoadBalancingTrav && LightTrav && RenderTrav);
+00158         AnimDetailTrav->clearVisibleList();
+00159         LoadBalancingTrav->clearVisibleList();
+00160         LightTrav->clearLightedList();
+00161         RenderTrav->clearRenderList();
+00162 
+00163 
+00164         /* For all objects marked visible in preceding render, reset Visible state here.
+00165                 NB: must reset Visible State to false because sometimes ClipObs::traverse() are even not executed
+00166                 (Cluster clip, QuadGridClipManager clip...).
+00167                 And somes models read this Visible state. eg: Skins/StickedObjects test the Visible state of 
+00168                 their _AncestorSkeletonModel.
+00169         */
+00170         for (i=0;i<_VisibleList.size();i++)
+00171         {
+00172                 // if the observer still exists (see ~IBaseClipObs())
+00173                 if( _VisibleList[i] )
+00174                 {
+00175                         // disable his visibility.
+00176                         _VisibleList[i]->Visible= false;
+00177                         // let him know that it is no more in the list.
+00178                         _VisibleList[i]->_IndexInVisibleList= -1;
+00179                 }
+00180         }
+00181         // Clear The visible List.
+00182         _VisibleList.clear();
+00183 
+00184 
+00185         // Found where is the camera
+00186         //========================
+00187 
+00188         // Found the cluster where the camera is
+00189         static vector<CCluster*> vCluster;
+00190 
+00191         vCluster.clear();
+00192 
+00193         // In which cluster is the camera ?
+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         // Manage Moving Objects
+00230         //=====================
+00231 
+00232         // Unlink the moving objects from their clusters
+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                         // Does the father is a cluster, or a CQuadGridClipCluster ??
+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         // Affect the moving objects to their clusters
+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                 // Transform the box in the world
+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                 // Moving object in the world -> link to root or to the CQuadGridClipManager.
+00291                 if (bInWorld)
+00292                 {
+00293                         if( _QuadGridClipManager && pTfmShp->isQuadGridClipEnabled() )
+00294                         {
+00295                                 // try to insert in the best cluster of the _QuadGridClipManager.
+00296                                 if(!_QuadGridClipManager->linkModel(pTfmShp, this))
+00297                                         // if fails, link to "root".
+00298                                         link (RootCluster, pTfmShp);
+00299                         }
+00300                         else
+00301                         {
+00302                                 link (RootCluster, pTfmShp);
+00303                         }
+00304                 }
+00305         }
+00306 
+00307         // Clip the graph.
+00308         //=====================
+00309 
+00310         // Traverse the graph.
+00311         if (Root)
+00312                 Root->traverse (NULL);
+00313 
+00314 
+00315         // Unlink the cluster where we are
+00316         for (i = 0; i < vCluster.size(); ++i)
+00317         {
+00318                 unlink (NULL, vCluster[i]);
+00319         }
+00320 
+00321 
+00322         // Load Balance the Skeleton CLod state here. 
+00323         // =========================
+00324         /* Can't do it in LoadBalancingTrav because sons with _AncestorSkeletonModel!=NULL may be hiden if a skeleton
+00325                 is displayed in CLod mode.
+00326                 So must do it here, then clip all sons of AncestoreSkeletonModelGroup.
+00327         */
+00328         loadBalanceSkeletonCLod();
+00329 
+00330 
+00331         // At the end of the clip traverse, must update clip for Objects which have a skeleton ancestor
+00332         // =========================
+00333         // those are linked to the SonsOfAncestorSkeletonModelGroup, so traverse it now.
+00334         if (SonsOfAncestorSkeletonModelGroup)
+00335                 SonsOfAncestorSkeletonModelGroup->getObs(ClipTravId)->traverse(NULL);
+00336 
+00337 
+00338         // Update Here the Skin render Lists of All visible Skeletons
+00339         // =========================
+00340         /*
+00341                 Done here, because AnimDetail and Render need correct lists. NB: important to do it 
+00342                 before Render Traversal, because updateSkinRenderLists() may change the transparency flag!!
+00343                 NB: can't do it in the clipObs of the skeleton since _DisplayLodCharacterFlag must be updated for this frame.
+00344         */
+00345         CScene::ItSkeletonModelList             itSkel;
+00346         for(itSkel= Scene->getSkeletonModelListBegin(); itSkel!=Scene->getSkeletonModelListEnd(); itSkel++)
+00347         {
+00348                 CSkeletonModel  *sm= *itSkel;
+00349                 // if visible
+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         // **** compute CLod priority of each skeleton,
+00439         for(itSkel= Scene->getSkeletonModelListBegin(); itSkel!=Scene->getSkeletonModelListEnd(); itSkel++)
+00440         {
+00441                 CSkeletonModel  *sm= *itSkel;
+00442                 float   pr= sm->computeDisplayLodCharacterPriority();
+00443                 // If valid priority (CLOd enabled, and skeleton visible)
+00444                 if(pr>0)
+00445                 {
+00446                         // if the priority is >1, then display as CLod
+00447                         if(pr>1)
+00448                                 sm->setDisplayLodCharacterFlag(true);
+00449                         // else load balance.
+00450                         else
+00451                         {
+00452                                 CSkeletonKey    key;
+00453                                 // don't bother OptFastFloor precision. NB: 0<pr<=1 here.
+00454                                 key.Priority= OptFastFloor(pr*0xFFFFFF00);
+00455                                 key.SkeletonModel= sm;
+00456                                 _TmpSortSkeletons.push_back(key);
+00457                         }
+00458                 }
+00459         }
+00460 
+00461         // **** sort by priority in ascending order
+00462         uint    nMaxSkelsInNotCLodForm= Scene->getMaxSkeletonsInNotCLodForm();
+00463         // Optim: need it only if too many skels
+00464         if(_TmpSortSkeletons.size()>nMaxSkelsInNotCLodForm)
+00465         {
+00466                 sort(_TmpSortSkeletons.begin(), _TmpSortSkeletons.end());
+00467         }
+00468 
+00469         // **** set CLod flag 
+00470         uint    n= min(nMaxSkelsInNotCLodForm, _TmpSortSkeletons.size());
+00471         uint    i;
+00472         // The lowest priority are displayed in std form
+00473         for(i=0;i<n;i++)
+00474         {
+00475                 _TmpSortSkeletons[i].SkeletonModel->setDisplayLodCharacterFlag(false);
+00476         }
+00477         // the other are displayed in CLod form
+00478         for(i=n;i<_TmpSortSkeletons.size();i++)
+00479         {
+00480                 _TmpSortSkeletons[i].SkeletonModel->setDisplayLodCharacterFlag(true);
+00481         }
+00482 
+00483 }
+00484 
+00485 
+00486 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1