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

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 #ifndef NL_QUAD_GRID_H
+00027 #define NL_QUAD_GRID_H
+00028 
+00029 #include "nel/misc/debug.h"
+00030 #include "nel/misc/vector.h"
+00031 #include "nel/misc/plane.h"
+00032 #include "nel/misc/matrix.h"
+00033 #include "nel/misc/stl_block_list.h"
+00034 #include "nel/misc/common.h"
+00035 #include <vector>
+00036 
+00037 
+00038 namespace NL3D 
+00039 {
+00040 
+00041 
+00042 using NLMISC::CVector;
+00043 
+00044 // ***************************************************************************
+00045 // Default Size of a block for allocation of elements and elements node list in the grid.
+00046 #define NL3D_QUAD_GRID_ALLOC_BLOCKSIZE  16
+00047 
+00048 
+00049 // ***************************************************************************
+00076 template<class T>       class   CQuadGrid
+00077 {
+00078 public:
+00080         class   CIterator;
+00081         friend class    CIterator;
+00082 
+00083 public:
+00084 
+00086         CQuadGrid(uint memoryBlockSize= NL3D_QUAD_GRID_ALLOC_BLOCKSIZE);
+00087 
+00089         ~CQuadGrid();
+00090 
+00092 
+00093 
+00108         void                    changeBase(const NLMISC::CMatrix& base);
+00109 
+00116         void                    create(uint size, float eltSize);
+00117 
+00118         // Get creation parameters.
+00119         const NLMISC::CMatrix   &getBasis() const {return _ChangeBasis;}
+00120         uint                                    getSize() const {return _Size;}
+00121         float                                   getEltSize() const {return _EltSize;}
+00123 
+00125 
+00126 
+00129         void                    clear();
+00130 
+00138         CIterator               erase(CIterator it);
+00139 
+00165         CIterator               insert(const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax, const T &val);
+00167 
+00168 
+00170 
+00171 
+00174         void                    clearSelection();
+00175 
+00179         void                    selectAll();
+00180 
+00187         void                    select(const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax);
+00188 
+00189 
+00193         CIterator               begin();
+00194 
+00198         CIterator               end();
+00200 
+00201 
+00202 // =================
+00203 // =================
+00204 // IMPLEMENTATION.
+00205 // =================
+00206 // =================
+00207 private:// Classes.
+00208 
+00209         class   CBaseNode
+00210         {
+00211         public:
+00212                 CBaseNode       *Prev,*Next;    // For selection.
+00213                 bool            Selected;               // true if owned by _SelectedList, or by _UnSelectedList.
+00214                 CBaseNode() {Prev= Next= NULL;}
+00215         };
+00216 
+00217         class   CNode : public CBaseNode
+00218         {
+00219         public:
+00220                 T               Elt;
+00221                 uint16  x0,x1;                  // The location of the elt in the grid. Used for erase().
+00222                 uint16  y0,y1;
+00223         };
+00224 
+00225         class   CQuadNode
+00226         {
+00227         public:
+00228                 NLMISC::CSTLBlockList<CNode*>   Nodes;
+00229 
+00230                 CQuadNode(NLMISC::CBlockMemory<CNode*, false> *bm) : Nodes(bm) {}
+00231         };
+00232 
+00233 private:// Atttributes.
+00234         std::vector<CQuadNode>  _Grid;
+00235         sint                            _Size;
+00236         sint                            _SizePower;
+00237         float                           _EltSize;
+00238         NLMISC::CMatrix         _ChangeBasis;
+00239         // Selection. Elements are either in _SelectedList or in _UnSelectedList
+00240         CBaseNode                       _SelectedList;          // list of elements selected.
+00241         CBaseNode                       _UnSelectedList;        // circular list of elements not selected
+00242         // The memory for nodes
+00243         NLMISC::CBlockMemory<CNode>                                     _NodeBlockMemory;
+00244         // The memory for node list
+00245         NLMISC::CBlockMemory<CNode*, false>                     _NodeListBlockMemory;
+00246 
+00247 
+00248 private:// Methods.
+00249 
+00250         // link a node to a root: Selected or UnSelected list
+00251         void            linkToRoot(CBaseNode &root, CBaseNode *ptr)
+00252         {
+00253                 ptr->Prev= &root;
+00254                 ptr->Next= root.Next;
+00255                 ptr->Prev->Next= ptr;
+00256                 if(ptr->Next)
+00257                         ptr->Next->Prev= ptr;
+00258         }
+00259 
+00260         // return the coordinates on the grid of what include the bbox.
+00261         void            selectQuads(CVector bmin, CVector bmax, sint &x0, sint &x1, sint &y0, sint &y1)
+00262         {
+00263                 CVector         bminp, bmaxp;
+00264                 bminp= bmin;
+00265                 bmaxp= bmax;
+00266                 bmin.minof(bminp, bmaxp);
+00267                 bmax.maxof(bminp, bmaxp);
+00268                 bmin/= _EltSize;
+00269                 bmax/= _EltSize;
+00270                 x0= (sint)(floor(bmin.x));
+00271                 x1= (sint)(ceil(bmax.x));
+00272                 y0= (sint)(floor(bmin.y));
+00273                 y1= (sint)(ceil(bmax.y));
+00274 
+00275                 // Very special case where the bbox.size==0 AND position is JUST on an edge of a case.
+00276                 if(x0==x1)
+00277                         x1++;
+00278                 if(y0==y1)
+00279                         y1++;
+00280 
+00281                 // Manage tiling.
+00282                 if(x1-x0>=_Size)
+00283                         x0=0, x1= _Size;
+00284                 else
+00285                 {
+00286                         x0&= _Size-1;
+00287                         x1&= _Size-1;
+00288                         if(x1<=x0)
+00289                                 x1+=_Size;
+00290                 }
+00291                 if(y1-y0>=_Size)
+00292                         y0=0, y1= _Size;
+00293                 else
+00294                 {
+00295                         y0&= _Size-1;
+00296                         y1&= _Size-1;
+00297                         if(y1<=y0)
+00298                                 y1+=_Size;
+00299                 }
+00300         }
+00301 
+00302         // If not done, add the node to the selection.
+00303         void            addToSelection(CNode    *ptr)
+00304         {
+00305                 // if not selected
+00306                 if(!ptr->Selected)
+00307                 {
+00308                         // remove from the unselected list.
+00309                         ptr->Prev->Next= ptr->Next;
+00310                         if(ptr->Next)
+00311                                 ptr->Next->Prev= ptr->Prev;
+00312 
+00313                         // Append to front of the _Selected list.
+00314                         linkToRoot(_SelectedList, ptr);
+00315 
+00316                         // mark it
+00317                         ptr->Selected= true;
+00318                 }
+00319         }
+00320 
+00321         // Try to add each node of the quad node list.
+00322         void            addQuadNodeToSelection(CQuadNode        &quad)
+00323         {
+00324                 typename NLMISC::CSTLBlockList<CNode*>::iterator        itNode;
+00325                 for(itNode= quad.Nodes.begin();itNode!=quad.Nodes.end();itNode++)
+00326                 {
+00327                         addToSelection(*itNode);
+00328                 }
+00329         }
+00330 
+00331 
+00332 public:
+00333         // CLASS const_iterator.
+00334         class const_iterator
+00335         {
+00336         public:
+00337                 const_iterator()        {_Ptr=NULL;}
+00338                 const_iterator(CNode *p) : _Ptr(p) {}
+00339                 const_iterator(const CIterator& x) : _Ptr(x._Ptr) {}
+00340 
+00341                 const T&        operator*() const
+00342                         {return _Ptr->Elt; }
+00343                 // Doesn't work...
+00344                 /*const T*      operator->() const
+00345                         {return (&**this); }*/
+00346                 const_iterator& operator++()
+00347                         {_Ptr = (CNode*)(_Ptr->Next); return (*this); }
+00348                 const_iterator operator++(int)
+00349                         {const_iterator tmp = *this; ++*this; return (tmp); }
+00350                 const_iterator& operator--()
+00351                         {_Ptr = (CNode*)(_Ptr->Prev); return (*this); }
+00352                 const_iterator operator--(int)
+00353                         {const_iterator tmp = *this; --*this; return (tmp); }
+00354                 bool operator==(const const_iterator& x) const
+00355                         {return (_Ptr == x._Ptr); }
+00356                 bool operator!=(const const_iterator& x) const
+00357                         {return (!(*this == x)); }
+00358         protected:
+00359                 CNode   *_Ptr;
+00360                 friend class CQuadGrid<T>;
+00361                 friend class CIterator;
+00362         };
+00363 
+00364         // CLASS CIterator
+00365         class CIterator : public const_iterator
+00366         {
+00367         public:
+00368                 CIterator()                     {_Ptr=NULL;}
+00369                 CIterator(CNode *p) : const_iterator(p) {}
+00370                 T&      operator*() const
+00371                         {return _Ptr->Elt; }
+00372                 // Doesn't work...
+00373                 /*T*    operator->() const
+00374                         {return (&**this); }*/
+00375                 CIterator& operator++()
+00376                         {_Ptr = (CNode*)(_Ptr->Next); return (*this); }
+00377                 CIterator operator++(int)
+00378                         {CIterator tmp = *this; ++*this; return (tmp); }
+00379                 CIterator& operator--()
+00380                         {_Ptr = (CNode*)(_Ptr->Prev); return (*this); }
+00381                 CIterator operator--(int)
+00382                         {CIterator tmp = *this; --*this; return (tmp); }
+00383                 bool operator==(const const_iterator& x) const
+00384                         {return (_Ptr == x._Ptr); }
+00385                 bool operator!=(const const_iterator& x) const
+00386                         {return (!(*this == x)); }
+00387         protected:
+00388                 friend class CQuadGrid<T>;
+00389         };
+00390 
+00391 
+00392 };
+00393 
+00394 
+00395 // ***************************************************************************
+00396 // ***************************************************************************
+00397 // ***************************************************************************
+00398 // ***************************************************************************
+00399 // Template CQuadGrid implementation.
+00400 // ***************************************************************************
+00401 // ***************************************************************************
+00402 // ***************************************************************************
+00403 // ***************************************************************************
+00404 
+00405 
+00406 // ***************************************************************************
+00407 // Init.
+00408 // ***************************************************************************
+00409 
+00410 
+00411 // ***************************************************************************
+00412 template<class T>       CQuadGrid<T>::CQuadGrid(uint memoryBlockSize) : 
+00413         _NodeBlockMemory(memoryBlockSize), _NodeListBlockMemory(memoryBlockSize)
+00414 {
+00415         _SizePower=4;
+00416         _Size=1<<_SizePower;
+00417         _EltSize=1;
+00418         _ChangeBasis.identity();
+00419 }
+00420 // ***************************************************************************
+00421 template<class T>       CQuadGrid<T>::~CQuadGrid()
+00422 {
+00423         clear();
+00424         // must clear the array, before _NodeListBlockMemory.purge() is called.
+00425         _Grid.clear();
+00426 }
+00427 // ***************************************************************************
+00428 template<class T>       void            CQuadGrid<T>::changeBase(const NLMISC::CMatrix& base)
+00429 {
+00430         _ChangeBasis= base;
+00431 }
+00432 // ***************************************************************************
+00433 template<class T>       void            CQuadGrid<T>::create(uint size, float eltSize)
+00434 {
+00435         clear();
+00436 
+00437         nlassert(NLMISC::isPowerOf2(size));
+00438         nlassert(size<=32768);
+00439         _SizePower= NLMISC::getPowerOf2(size);
+00440         _Size=1<<_SizePower;
+00441         _Grid.resize(_Size*_Size, CQuadNode(&_NodeListBlockMemory));
+00442 
+00443         nlassert(eltSize>0);
+00444         _EltSize= eltSize;
+00445 }
+00446 
+00447 
+00448 // ***************************************************************************
+00449 // insert/erase.
+00450 // ***************************************************************************
+00451 
+00452 
+00453 // ***************************************************************************
+00454 template<class T>       void            CQuadGrid<T>::clear()
+00455 {
+00456         CIterator       it;
+00457         selectAll();
+00458         while( (it=begin())!=end())
+00459         {
+00460                 erase(it);
+00461         }
+00462 
+00463         // Clear the 2 selection...
+00464         _SelectedList.Next= NULL;
+00465         _UnSelectedList.Next= NULL;
+00466 }
+00467 // ***************************************************************************
+00468 template<class T>       typename CQuadGrid<T>::CIterator        CQuadGrid<T>::erase(typename CQuadGrid<T>::CIterator it)
+00469 {
+00470         sint    x,y;
+00471         CNode   *ptr= it._Ptr;
+00472 
+00473         if(!ptr)
+00474                 return end();
+00475 
+00476         // First erase all references to it.
+00477         //==================================
+00478         for(y= ptr->y0;y<ptr->y1;y++)
+00479         {
+00480                 sint    xe,ye;
+00481                 ye= y &(_Size-1);
+00482                 for(x= ptr->x0;x<ptr->x1;x++)
+00483                 {
+00484                         xe= x &(_Size-1);
+00485                         CQuadNode       &quad= _Grid[(ye<<_SizePower)+xe];
+00486                         typename NLMISC::CSTLBlockList<CNode*>::iterator        itNode;
+00487                         for(itNode= quad.Nodes.begin();itNode!=quad.Nodes.end();itNode++)
+00488                         {
+00489                                 if((*itNode)==ptr)
+00490                                 {
+00491                                         quad.Nodes.erase(itNode);
+00492                                         break;
+00493                                 }
+00494                         }
+00495                 }
+00496         }
+00497 
+00498         // Then delete it..., and update selection linked list.
+00499         //=====================================================
+00500         // remove it from _SelectedList or _UnSelectedList
+00501         CBaseNode       *next= NULL;
+00502         next= ptr->Next;
+00503         if(next)
+00504                 next->Prev=ptr->Prev;
+00505         ptr->Prev->Next= next;
+00506         // if not selected, then must return NULL
+00507         if(!ptr->Selected)
+00508                 next= NULL;
+00509         // delete the object.
+00510         _NodeBlockMemory.free(ptr);
+00511 
+00512 
+00513         return CIterator((CNode*)next);
+00514 }
+00515 // ***************************************************************************
+00516 template<class T>       typename CQuadGrid<T>::CIterator        CQuadGrid<T>::insert(const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax, const T &val)
+00517 {
+00518         CVector         bmin,bmax;
+00519         bmin= _ChangeBasis*bboxmin;
+00520         bmax= _ChangeBasis*bboxmax;
+00521 
+00522         // init the object.
+00523         CNode   *ptr= _NodeBlockMemory.allocate();
+00524         ptr->Elt= val;
+00525         // Link to _Unselected list.
+00526         linkToRoot(_UnSelectedList, ptr);
+00527         // mark as not selected.
+00528         ptr->Selected= false;
+00529 
+00530 
+00531         // Find which quad include the object.
+00532         //===================================
+00533         sint    x0,y0;
+00534         sint    x1,y1;
+00535         selectQuads(bmin, bmax, x0,x1, y0,y1);
+00536 
+00537         ptr->x0= x0;
+00538         ptr->x1= x1;
+00539         ptr->y0= y0;
+00540         ptr->y1= y1;
+00541 
+00542         // Then for all of them, insert the node in their list.
+00543         //=====================================================
+00544         sint    x,y;
+00545         for(y= ptr->y0;y<ptr->y1;y++)
+00546         {
+00547                 sint    xe,ye;
+00548                 ye= y &(_Size-1);
+00549                 for(x= ptr->x0;x<ptr->x1;x++)
+00550                 {
+00551                         xe= x &(_Size-1);
+00552                         CQuadNode       &quad= _Grid[(ye<<_SizePower)+xe];
+00553                         quad.Nodes.push_back(ptr);
+00554                 }
+00555         }
+00556 
+00557         return CIterator(ptr);
+00558 }
+00559 
+00560 
+00561 // ***************************************************************************
+00562 // selection.
+00563 // ***************************************************************************
+00564 
+00565 
+00566 // ***************************************************************************
+00567 template<class T>       void                    CQuadGrid<T>::clearSelection()
+00568 {
+00569         CBaseNode       *ptr= _SelectedList.Next;
+00570         while(ptr)
+00571         {
+00572                 // next selected.
+00573                 CBaseNode       *nextSelected= ptr->Next;
+00574 
+00575                 // Link to _Unselected list.
+00576                 linkToRoot(_UnSelectedList, ptr);
+00577 
+00578                 // mark as not selected.
+00579                 ptr->Selected= false;
+00580 
+00581                 // next.
+00582                 ptr= nextSelected;
+00583         }
+00584 
+00585         // the selected list is now empty.
+00586         _SelectedList.Next= NULL;
+00587 }
+00588 // ***************************************************************************
+00589 template<class T>       void                    CQuadGrid<T>::selectAll()
+00590 {
+00591         // This is the opposite of clearSelection(). get all that are in _UnSelectedList,
+00592         // and put them in _SelectedList
+00593         CBaseNode       *ptr= _UnSelectedList.Next;
+00594         while(ptr)
+00595         {
+00596                 // next selected.
+00597                 CBaseNode       *nextUnSelected= ptr->Next;
+00598 
+00599                 // Link to _Selected list.
+00600                 linkToRoot(_SelectedList, ptr);
+00601 
+00602                 // mark as selected.
+00603                 ptr->Selected= true;
+00604 
+00605                 // next.
+00606                 ptr= nextUnSelected;
+00607         }
+00608 
+00609         // the Unselected list is now empty.
+00610         _UnSelectedList.Next= NULL;
+00611 }
+00612 // ***************************************************************************
+00613 template<class T>       void                    CQuadGrid<T>::select(const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax)
+00614 {
+00615         CVector         bmin,bmax;
+00616         bmin= _ChangeBasis*bboxmin;
+00617         bmax= _ChangeBasis*bboxmax;
+00618 
+00619         clearSelection();
+00620 
+00621         // What are the quads to access?
+00622         sint    x0,y0;
+00623         sint    x1,y1;
+00624         selectQuads(bmin, bmax, x0,x1, y0,y1);
+00625 
+00626         sint    x,y;
+00627         for(y= y0;y<y1;y++)
+00628         {
+00629                 sint    xe,ye;
+00630                 ye= y &(_Size-1);
+00631                 for(x= x0;x<x1;x++)
+00632                 {
+00633                         xe= x &(_Size-1);
+00634                         CQuadNode       &quad= _Grid[(ye<<_SizePower)+xe];
+00635                         addQuadNodeToSelection(quad);
+00636                 }
+00637         }
+00638 
+00639 }
+00640 // ***************************************************************************
+00641 template<class T>       typename CQuadGrid<T>::CIterator                CQuadGrid<T>::begin()
+00642 {
+00643         return CIterator((CNode*)(_SelectedList.Next));
+00644 }
+00645 // ***************************************************************************
+00646 template<class T>       typename CQuadGrid<T>::CIterator                CQuadGrid<T>::end()
+00647 {
+00648         return CIterator(NULL);
+00649 }
+00650 
+00651 
+00652 } // NL3D
+00653 
+00654 
+00655 #endif // NL_QUAD_GRID_H
+00656 
+00657 /* End of quad_grid.h */
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1