From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/quad__grid__clip__manager_8cpp-source.html | 415 +++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 docs/doxygen/nel/quad__grid__clip__manager_8cpp-source.html (limited to 'docs/doxygen/nel/quad__grid__clip__manager_8cpp-source.html') diff --git a/docs/doxygen/nel/quad__grid__clip__manager_8cpp-source.html b/docs/doxygen/nel/quad__grid__clip__manager_8cpp-source.html new file mode 100644 index 00000000..d2697702 --- /dev/null +++ b/docs/doxygen/nel/quad__grid__clip__manager_8cpp-source.html @@ -0,0 +1,415 @@ + + + + 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  
+

quad_grid_clip_manager.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/quad_grid_clip_manager.h"
+00029 #include "3d/scene.h"
+00030 #include "3d/transform_shape.h"
+00031 #include "3d/clip_trav.h"
+00032 #include "nel/misc/aabbox.h"
+00033 #include "3d/cluster.h"
+00034 #include "3d/skip_model.h"
+00035 
+00036 
+00037 using namespace std;
+00038 using namespace NLMISC;
+00039 
+00040 
+00041 namespace NL3D 
+00042 {
+00043 
+00044 
+00045 // ***************************************************************************
+00046 CQuadGridClipManager::CQuadGridClipManager()
+00047 {
+00048         _Scene= NULL;
+00049         _ClusterSize= 0;
+00050         _X= _Y= 0;
+00051         _Width= _Height= 0;
+00052 }
+00053 // ***************************************************************************
+00054 CQuadGridClipManager::~CQuadGridClipManager()
+00055 {
+00056         reset();
+00057 }
+00058 
+00059 
+00060 // ***************************************************************************
+00061 void                            CQuadGridClipManager::init(CScene *scene, float clusterSize, std::vector<float> maxDists, float radiusMax )
+00062 {
+00063         // reset first.
+00064         reset();
+00065 
+00066         // copy params.
+00067         nlassert(clusterSize>0);
+00068         _Scene= scene;
+00069         _ClusterSize= clusterSize;
+00070         _MaxDists= maxDists;
+00071         _RadiusMax= radiusMax;
+00072 
+00073         // verify growing order.
+00074         float   prec= 0;
+00075         for(uint i=0; i<_MaxDists.size(); i++)
+00076         {
+00077                 nlassert(_MaxDists[i] > prec);
+00078                 prec=_MaxDists[i];
+00079         }
+00080 }
+00081 
+00082 // ***************************************************************************
+00083 void                            CQuadGridClipManager::reset()
+00084 {
+00085         // delete the clusters.
+00086         if(_Scene)
+00087         {
+00088                 sint    oldX0, oldX1, oldY0, oldY1;
+00089 
+00090                 oldX0= _X;
+00091                 oldX1= _X+_Width;
+00092                 oldY0= _Y;
+00093                 oldY1= _Y+_Height;
+00094 
+00095                 for(sint y=oldY0; y<oldY1; y++)
+00096                 {
+00097                         for(sint x=oldX0; x<oldX1; x++)
+00098                         {
+00099                                 deleteCaseModels((CClipTrav*)_Scene->getTrav(ClipTravId), x,y);
+00100                         }
+00101                 }
+00102 
+00103                 // clear the grid.
+00104                 _QuadGridClusterCases.clear();
+00105         }
+00106 
+00107         // reset others params.
+00108         _MaxDists.clear();
+00109         _Scene= NULL;
+00110         _ClusterSize= 0;
+00111         _X= _Y= 0;
+00112         _Width= _Height= 0;
+00113 }
+00114 
+00115 // ***************************************************************************
+00116 void                            CQuadGridClipManager::updateClustersFromCamera(CClipTrav *pClipTrav, const CVector &camPos)
+00117 {
+00118         sint    newX0, newX1, newY0, newY1;
+00119         sint    oldX0, oldX1, oldY0, oldY1;
+00120 
+00121         oldX0= _X;
+00122         oldX1= _X+_Width;
+00123         oldY0= _Y;
+00124         oldY1= _Y+_Height;
+00125 
+00126         // compute the new square of clusters to build.
+00127         newX0= (sint)floor( (camPos.x - _RadiusMax) / _ClusterSize);
+00128         newX1= (sint)ceil( (camPos.x + _RadiusMax) / _ClusterSize);
+00129         newY0= (sint)floor( (camPos.y - _RadiusMax) / _ClusterSize);
+00130         newY1= (sint)ceil( (camPos.y + _RadiusMax) / _ClusterSize);
+00131 
+00132         // keep an histeresis of one cluster: do not delete "young" clusters created before.
+00133         if(newX0>= oldX0+1)             // NB: if newX0==oldX0+1, then newX0= _X => no change.
+00134                 newX0--;        
+00135         if(newY0>= oldY0+1)             // same reasoning.
+00136                 newY0--;        
+00137         if(newX1<= oldX1-1)             // NB: if newX1==oldX1-1, then newX1= oldX1 => no change.
+00138                 newX1++;        
+00139         if(newY1<= oldY1-1)             // same reasoning.
+00140                 newY1++;
+00141 
+00142         // Have we got to update the array.
+00143         if(newX0!=oldX0 || newX1!=oldX1 || newY0!=oldY0 || newY1!=oldY1)
+00144         {
+00145                 sint    x,y;
+00146 
+00147                 // delete olds models.
+00148                 // simple: test all cases
+00149                 for(y=oldY0; y<oldY1; y++)
+00150                 {
+00151                         for(x=oldX0; x<oldX1; x++)
+00152                         {
+00153                                 // if out the new square?
+00154                                 if(x<newX0 || x>=newX1 || y<newY0 || y>=newY1)
+00155                                         deleteCaseModels(pClipTrav, x,y);
+00156                         }
+00157                 }
+00158 
+00159                 // build new array
+00160                 // satic for alloc optimisation.
+00161                 static  vector<CQuadGridClusterCase>    newQuadGridClusterCases;
+00162                 sint    newWidth= newX1-newX0;
+00163                 sint    newHeight= newY1-newY0;
+00164                 newQuadGridClusterCases.resize(newWidth * newHeight);
+00165                 // simple: test all cases
+00166                 for(y=newY0; y<newY1; y++)
+00167                 {
+00168                         for(x=newX0; x<newX1; x++)
+00169                         {
+00170                                 CQuadGridClusterCase    &newCase= newQuadGridClusterCases[ (y-newY0)*newWidth + (x-newX0) ];
+00171 
+00172                                 // if out the old square?
+00173                                 if(x<oldX0 || x>=oldX1 || y<oldY0 || y>=oldY1)
+00174                                 {
+00175                                         // build new case. Clusters are empty.
+00176                                         newCaseModels(newCase);
+00177                                 }
+00178                                 else
+00179                                 {
+00180                                         // copy from old.
+00181                                         CQuadGridClusterCase    &oldCase= _QuadGridClusterCases[ (y-_Y)*_Width + (x-_X) ];
+00182 
+00183                                         newCase= oldCase;
+00184                                 }
+00185                         }
+00186                 }
+00187 
+00188                 // just copy from new.
+00189                 _QuadGridClusterCases= newQuadGridClusterCases;
+00190                 _X= newX0;
+00191                 _Y= newY0;
+00192                 _Width= newWidth;
+00193                 _Height= newHeight;
+00194         }
+00195 }
+00196 
+00197 
+00198 // ***************************************************************************
+00199 bool                            CQuadGridClipManager::linkModel(CTransformShape *pTfmShp, CClipTrav *pClipTrav)
+00200 {
+00201         // use the position to get the cluster to use.
+00202         CAABBox box;
+00203         pTfmShp->getAABBox (box);
+00204         float   distModelMax = pTfmShp->getDistMax();
+00205 
+00206         // Transform the box in the world
+00207         const CMatrix &wm = pTfmShp->getWorldMatrix();
+00208         // compute center in world.
+00209         CVector cLocal  = box.getCenter();
+00210         CVector cWorld  = wm * cLocal;
+00211         // prepare bbox.
+00212         CAABBox worldBBox;
+00213         worldBBox.setCenter(cWorld);
+00214         CVector hs = box.getHalfSize();
+00215 
+00216         // For 8 corners.
+00217         for(uint i=0;i<8;i++)
+00218         {
+00219                 CVector         corner;
+00220                 // compute the corner of the bbox.
+00221                 corner= cLocal;
+00222                 if(i&1)         corner.x+=hs.x;
+00223                 else            corner.x-=hs.x;
+00224                 if((i/2)&1)     corner.y+=hs.y;
+00225                 else            corner.y-=hs.y;
+00226                 if((i/4)&1)     corner.z+=hs.z;
+00227                 else            corner.z-=hs.z;
+00228                 // Transform the corner in world.
+00229                 corner = wm * corner;
+00230                 // Extend the bbox with it.
+00231                 worldBBox.extend(corner);
+00232         }
+00233 
+00234 
+00235         // Position in the grid.
+00236         sint    x,y;
+00237         x= (sint)floor( cWorld.x / _ClusterSize);
+00238         y= (sint)floor( cWorld.y / _ClusterSize);
+00239 
+00240         // verify if IN the current grid of clusters created.
+00241         if( x>=_X && x<_X+_Width && y>=_Y && y<_Y+_Height )
+00242         {
+00243                 CQuadGridClusterCase    &clusterCase= _QuadGridClusterCases[ (y-_Y)*_Width + (x-_X) ];
+00244                 nlassert( _MaxDists.size()+1 == clusterCase.QuadGridClipClusters.size() );
+00245 
+00246                 // search the best cluster.
+00247                 uint    bestCluster;
+00248                 if(distModelMax==-1)
+00249                 {
+00250                         bestCluster= clusterCase.QuadGridClipClusters.size()-1;
+00251                 }
+00252                 else
+00253                 {
+00254                         nlassert(distModelMax>=0);
+00255                         // search in which cluster against we must test.
+00256                         uint i;
+00257                         for(i=0; i<clusterCase.QuadGridClipClusters.size()-1;i++)
+00258                         {
+00259                                 if(distModelMax<=_MaxDists[i])
+00260                                         break;
+00261                         }
+00262                         // NB: interval [?? , +oo[,  if i==clusterCase.QuadGridClipClusters.size()-1;
+00263                         bestCluster= i;
+00264                 }
+00265 
+00266                 // extend the bbox of this cluster.
+00267                 clusterCase.QuadGridClipClusters[bestCluster]->extendCluster(worldBBox);
+00268                 // link the model to this cluster.
+00269                 pClipTrav->link(clusterCase.QuadGridClipClusters[bestCluster], pTfmShp);
+00270 
+00271 
+00272                 return true;
+00273         }
+00274         else
+00275         {
+00276                 return false;
+00277         }
+00278 
+00279 }
+00280 
+00281 
+00282 // ***************************************************************************
+00283 void                            CQuadGridClipManager::deleteCaseModels(CClipTrav *pClipTrav, sint x, sint y)
+00284 {
+00285         nlassert(x>=_X && x<_X+_Width && y>=_Y && y<_Y+_Height);
+00286 
+00287         CQuadGridClusterCase    &clusterCase= _QuadGridClusterCases[ (y-_Y)*_Width + (x-_X) ];
+00288         for(uint j=0; j<clusterCase.QuadGridClipClusters.size(); j++)
+00289         {
+00290                 CQuadGridClipCluster    *cluster= clusterCase.QuadGridClipClusters[j];
+00291 
+00292                 // first, unlink all sons from cluster, and link thems to RootCluster.
+00293                 IModel  *son= pClipTrav->getFirstChild(cluster);
+00294                 while( son != NULL )
+00295                 {
+00296                         // unlink from us.
+00297                         pClipTrav->unlink(cluster, son);
+00298                         // link to the rootCluster
+00299                         pClipTrav->link(pClipTrav->RootCluster, son);
+00300 
+00301                         // next son.
+00302                         son= pClipTrav->getFirstChild(cluster);
+00303                 }
+00304 
+00305                 // delete the cluster.
+00306                 _Scene->deleteModel(cluster);
+00307         }
+00308 
+00309         // NB: do not delete array for alloc/free optimisation.
+00310 }
+00311 
+00312 
+00313 // ***************************************************************************
+00314 void                            CQuadGridClipManager::newCaseModels(CQuadGridClusterCase &clusterCase)
+00315 {
+00316         // resize of the number of bbox per distance.
+00317         clusterCase.QuadGridClipClusters.resize(_MaxDists.size()+1);
+00318 
+00319         // create clusters.
+00320         for(uint i=0; i<clusterCase.QuadGridClipClusters.size(); i++)
+00321         {
+00322                 // create the cluster.
+00323                 CQuadGridClipCluster    *cluster= (CQuadGridClipCluster*)_Scene->createModel(QuadGridClipClusterId);
+00324                 clusterCase.QuadGridClipClusters[i]= cluster;
+00325                 // disable it from HRC
+00326                 CHrcTrav        *hrcTrav= (CHrcTrav*)_Scene->getTrav(HrcTravId);
+00327                 hrcTrav->link(_Scene->getSkipModelRoot(), cluster);
+00328                 // NB: disabled from validation in CQuadGridClipCluster::update()
+00329                 // Hence it will be never traversed but in ClipTrav.
+00330 
+00331                 // link it in RootCluster, so it may be clipped in city etc...
+00332                 CClipTrav       *clipTrav= (CClipTrav*)_Scene->getTrav(ClipTravId);
+00333                 clipTrav->unlink(NULL, cluster);
+00334                 clipTrav->link(clipTrav->RootCluster, cluster);
+00335 
+00336 
+00337                 // init distMax
+00338                 if(i<_MaxDists.size())
+00339                         clusterCase.QuadGridClipClusters[i]->setDistMax(_MaxDists[i]);
+00340                 else
+00341                         clusterCase.QuadGridClipClusters[i]->setDistMax(-1);
+00342         }
+00343 }
+00344 
+00345 
+00346 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1