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

tess_face_priority_list.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/tess_face_priority_list.h"
+00029 #include "nel/misc/debug.h"
+00030 #include <math.h>
+00031 #include "3d/tessellation.h"
+00032 #include "3d/fast_floor.h"
+00033 
+00034 
+00035 using   namespace NLMISC;
+00036 using   namespace std;
+00037 
+00038 namespace NL3D 
+00039 {
+00040 
+00041 // ***************************************************************************
+00042 // ***************************************************************************
+00043 //      CTessFacePListNode
+00044 // ***************************************************************************
+00045 // ***************************************************************************
+00046 
+00047 
+00048 // ***************************************************************************
+00049 void            CTessFacePListNode::linkInPList(CTessFacePListNode      &root)
+00050 {
+00051         // unlink old list from me.
+00052         _PrecTessFaceInPList->_NextTessFaceInPList= _NextTessFaceInPList;
+00053         _NextTessFaceInPList->_PrecTessFaceInPList= _PrecTessFaceInPList;
+00054 
+00055         // link me to the list.
+00056         _PrecTessFaceInPList= &root;
+00057         _NextTessFaceInPList= root._NextTessFaceInPList;
+00058         // link the list to me.
+00059         root._NextTessFaceInPList->_PrecTessFaceInPList= this;
+00060         root._NextTessFaceInPList= this;
+00061         /*
+00062                 NB if list was empty (this, this), then
+00063                         _PrecTessFaceInPList= &root
+00064                         _NextTessFaceInPList= root._NextTessFaceInPList= &root !
+00065                         root._NextTessFaceInPList->_PrecTessFaceInPList= this;  => root._PrecTessFaceInPList= this
+00066                         root._NextTessFaceInPList= this
+00067         */
+00068 }
+00069 
+00070 // ***************************************************************************
+00071 void            CTessFacePListNode::unlinkInPList()
+00072 {
+00073         /*
+00074                 NB: if this node was empty (this, this), this is a No-Op.
+00075                 If this node was the last of a list, then the root correctly get (&root, &root) after this.
+00076         */
+00077         // unlink old list from me.
+00078         _PrecTessFaceInPList->_NextTessFaceInPList= _NextTessFaceInPList;
+00079         _NextTessFaceInPList->_PrecTessFaceInPList= _PrecTessFaceInPList;
+00080 
+00081         // reset to empty node.
+00082         _PrecTessFaceInPList= this;
+00083         _NextTessFaceInPList= this;
+00084 }
+00085 
+00086 
+00087 // ***************************************************************************
+00088 void            CTessFacePListNode::appendPList(CTessFacePListNode      &root)
+00089 {
+00090         // If list to append is not empty.
+00091         if( root._NextTessFaceInPList != &root )
+00092         {
+00093                 // If we are empty.
+00094                 if( _NextTessFaceInPList==this )
+00095                 {
+00096                         // link the appendList to the root.
+00097                         _PrecTessFaceInPList= root._PrecTessFaceInPList;
+00098                         _NextTessFaceInPList= root._NextTessFaceInPList;
+00099                         // link the root to the appendList.
+00100                         _PrecTessFaceInPList->_NextTessFaceInPList= this;
+00101                         _NextTessFaceInPList->_PrecTessFaceInPList= this;
+00102                 }
+00103                 // else bind first-last in the interval prec-next.
+00104                 else
+00105                 {
+00106                         CTessFacePListNode              *first= root._NextTessFaceInPList;
+00107                         CTessFacePListNode              *last= root._PrecTessFaceInPList;
+00108                         CTessFacePListNode              *prec= this;
+00109                         CTessFacePListNode              *next= _NextTessFaceInPList;
+00110                         // insert the appendList in our list.
+00111                         next->_PrecTessFaceInPList= last;
+00112                         prec->_NextTessFaceInPList= first;
+00113                         // insert our list in the appendList.
+00114                         last->_NextTessFaceInPList= next;
+00115                         first->_PrecTessFaceInPList= prec;
+00116                 }
+00117 
+00118                 // clear input list.
+00119                 root._PrecTessFaceInPList= &root;
+00120                 root._NextTessFaceInPList= &root;
+00121         }
+00122 }
+00123 
+00124 
+00125 
+00126 // ***************************************************************************
+00127 // ***************************************************************************
+00128 //      CTessFacePriorityList
+00129 // ***************************************************************************
+00130 // ***************************************************************************
+00131 
+00132         
+00133 // ***************************************************************************
+00134 CTessFacePriorityList::CTessFacePriorityList()
+00135 {
+00136         _OODistStep= 1;
+00137         _NEntries= 0;
+00138         _MaskEntries= 0;
+00139         _EntryModStart= 0;
+00140         _NumQuadrant= 0;
+00141 }
+00142 
+00143 // ***************************************************************************
+00144 CTessFacePriorityList::~CTessFacePriorityList()
+00145 {
+00146         clear();
+00147 }
+00148 
+00149 // ***************************************************************************
+00150 void            CTessFacePriorityList::init(float distStep, uint numEntries, float distMaxMod, uint numQuadrant)
+00151 {
+00152         uint i;
+00153         nlassert(distStep>0);
+00154         nlassert(numEntries>0 && isPowerOf2(numEntries));
+00155         nlassert(distMaxMod<1);
+00156         nlassert(numQuadrant==0 || (numQuadrant>=4 && isPowerOf2(numQuadrant)) );
+00157 
+00158         // clear the prioriy list before.
+00159         clear();
+00160 
+00161         // setup
+00162         _OODistStep= 1.0f / distStep;
+00163         _NEntries= numEntries;
+00164         _MaskEntries= _NEntries-1;
+00165         _EntryModStart= (uint)ceil(distMaxMod * _NEntries);
+00166         NLMISC::clamp(_EntryModStart, 0U, _NEntries-1);
+00167         _NumQuadrant= numQuadrant;
+00168 
+00169         // Build the Rolling tables.
+00170         _RollingTables.resize(1+_NumQuadrant);
+00171         for(i=0;i<_RollingTables.size();i++)
+00172         {
+00173                 _RollingTables[i].init(_NEntries);
+00174                 // setup the quadrant direction. NB: 0 not used since "Direction less rolling table"
+00175                 if(i>=1)
+00176                 {
+00177                         uint    idx= i-1;
+00178                         // split evenly the plane with direction.
+00179                         float   angle= float(2*Pi*idx)/_NumQuadrant;
+00180                         CMatrix mat;
+00181                         mat.rotateZ(angle);
+00182                         // setup the vector
+00183                         _RollingTables[i].QuadrantDirection= mat.getJ();
+00184                 }
+00185         }
+00186 
+00187         // Build Quarter Selection. In is in CCW order. Out: see selectQuadrant()
+00188         const   uint    quarterLut[4]= {1,3,2,0};
+00189         _MaskQuadrant= _NumQuadrant-1;
+00190         for(i=0;i<4;i++)
+00191         {
+00192                 // Re-Order for faster ASM acces. see selectQuadrant()
+00193                 uint    idx= quarterLut[i];
+00194                 _QuarterQuadrantStart[idx]= i*_NumQuadrant/4;
+00195                 _QuarterQuadrantEnd[idx]= 1+ (i+1)*_NumQuadrant/4;
+00196         }
+00197 
+00198 }
+00199 
+00200 // ***************************************************************************
+00201 void            CTessFacePriorityList::clear()
+00202 {
+00203         // just clear all the rolling tables.
+00204         _RollingTables.clear();
+00205 }
+00206 
+00207 
+00208 // ***************************************************************************
+00209 uint            CTessFacePriorityList::selectQuadrant(const CVector &direction)
+00210 {
+00211         // if numQuadrants=0, ret 0.
+00212         if(_NumQuadrant==0)
+00213                 return 0;
+00214 
+00215 
+00216         // select the quarter.
+00217         uint    quarterId;
+00218 #ifdef  NL_OS_WINDOWS
+00219         __asm
+00220         {
+00221                 mov             esi, direction
+00222                 mov             eax, [esi]direction.y
+00223                 mov             ebx, [esi]direction.x
+00224                 // read the sign
+00225                 and             eax, 0x80000000
+00226                 and             ebx, 0x80000000
+00227                 // set the bit
+00228                 shr             eax, 30
+00229                 shr             ebx, 31
+00230                 // assemble
+00231                 or              eax, ebx
+00232                 mov             quarterId, eax
+00233         }
+00234 #else
+00235         if(direction.y>0)
+00236         {
+00237                 if(direction.x>0)       quarterId= 0;
+00238                 else                            quarterId= 1;
+00239         }
+00240         else
+00241         {
+00242                 if(direction.x>0)       quarterId= 2;
+00243                 else                            quarterId= 3;
+00244         }
+00245 #endif
+00246 
+00247         // Run only the quadrants of the associated quarter.
+00248         uint    quadrantStart= _QuarterQuadrantStart[quarterId];
+00249         uint    quadrantEnd= _QuarterQuadrantEnd[quarterId];
+00250 
+00251 
+00252         // For all quadrants of the quarter, return the best direction
+00253         float   bestDirPs= -FLT_MAX;
+00254         uint    bestQuadrant= 0;
+00255         for(uint i=quadrantStart;i<quadrantEnd;i++)
+00256         {
+00257                 // get the quadrant Id. Must mask for last (0). And Start at 1 in the _RollingTables.
+00258                 uint    quadrantId= (i&_MaskQuadrant)+1;
+00259                 // Test with this quadrant
+00260                 float   ps= direction*_RollingTables[i].QuadrantDirection;
+00261                 if(ps>bestDirPs)
+00262                 {
+00263                         bestDirPs= ps;
+00264                         bestQuadrant= i;
+00265                 }
+00266         }
+00267 
+00268         return bestQuadrant;
+00269 }
+00270 
+00271 
+00272 // ***************************************************************************
+00273 void            CTessFacePriorityList::insert(uint quadrantId, float distance, CTessFace *value)
+00274 {
+00275         // plist must be inited.
+00276         nlassert(_NEntries>0 && quadrantId<_RollingTables.size());
+00277 
+00278         // First, setup in our basis.
+00279         distance*= _OODistStep;
+00280 
+00281         // Insert int the good quadrant
+00282         CRollingTable   &rollTable= _RollingTables[quadrantId];
+00283 
+00284         // Then, look where we must insert it.
+00285         sint    idInsert;
+00286         if(distance<=0)
+00287                 idInsert= 0;
+00288         else
+00289         {
+00290                 // Must insert so we can't miss it when a shift occurs (=> floor).
+00291                 idInsert= OptFastFloor(distance + rollTable.Remainder);
+00292         }
+00293         idInsert= std::max(0, idInsert);
+00294 
+00295         // Manage Mod.
+00296         // If the element to insert must be inserted at  distance > distMax.
+00297         if(idInsert>(sint)_MaskEntries)
+00298         {
+00299                 // Compute number of entries to apply the mod.
+00300                 uint    nMod= _NEntries - _EntryModStart;
+00301                 // Of how many entries are we too far.
+00302                 idInsert= idInsert - _MaskEntries;
+00303                 // Then loop in the interval [_EntryModStart, _NEntries[.
+00304                 idInsert= idInsert % nMod;
+00305                 idInsert= _EntryModStart + idInsert;
+00306         }
+00307 
+00308         // insert in the Roll Table.
+00309         rollTable.insertInRollTable(idInsert, value);
+00310 }
+00311 
+00312 
+00313 // ***************************************************************************
+00314 void            CTessFacePriorityList::shift(const CVector &direction, CTessFacePListNode       &pulledElements)
+00315 {
+00316         // plist must be inited.
+00317         nlassert(_NEntries>0);
+00318 
+00319         pulledElements.unlinkInPList();
+00320 
+00321         // Shift all the rolling tables
+00322         for(uint i=0;i<_RollingTables.size();i++)
+00323         {
+00324                 CRollingTable   &rollTable= _RollingTables[i];
+00325                 float   shiftDistance;
+00326 
+00327                 // if quadrant 0, Direction less => get distance with Euler norm.
+00328                 if(i==0)
+00329                 {
+00330                         shiftDistance= direction.norm();
+00331                 }
+00332                 // Else compute the effective distance we run to the plane.
+00333                 else
+00334                 {
+00335                         shiftDistance= direction*rollTable.QuadrantDirection;
+00336                         // For now, just clamp, but may be interesting to shift Back the rolling table !!
+00337                         shiftDistance= max(0.f, shiftDistance);
+00338                 }
+00339 
+00340                 // First, setup in our basis.
+00341                 shiftDistance*= _OODistStep;
+00342 
+00343                 // at least, fill OUT with elements of entry 0.
+00344                 // For all elements of the entry 0 of , pull them, and insert in result list.
+00345                 pulledElements.appendPList(rollTable.getRollTableEntry(0));
+00346 
+00347                 // shift.
+00348                 rollTable.Remainder+= shiftDistance;
+00349                 // If Remainder>=1, it means that we must shift the rolling table, and get elements deleted.
+00350                 uint    entryShift= (uint)floor(rollTable.Remainder);
+00351                 rollTable.Remainder= rollTable.Remainder - entryShift;
+00352 
+00353                 // shift full array??
+00354                 if( entryShift >= _NEntries)
+00355                 {
+00356                         entryShift= _NEntries;
+00357                         // The entire array is pulled, _Remainder should get a good value.
+00358                         rollTable.Remainder= 0;
+00359                 }
+00360 
+00361                 // If some real shift, do it.
+00362                 rollTable.shiftEntries(entryShift, pulledElements);
+00363         }
+00364 }
+00365 
+00366 
+00367 // ***************************************************************************
+00368 void            CTessFacePriorityList::shiftAll(CTessFacePListNode      &pulledElements)
+00369 {
+00370         // plist must be inited.
+00371         nlassert(_NEntries>0);
+00372 
+00373         pulledElements.unlinkInPList();
+00374 
+00375         // Do it for all rolling tables.
+00376         for(uint i=0;i<_RollingTables.size();i++)
+00377         {
+00378                 // The entire array is pulled, _Remainder should get a good value.
+00379                 uint entryShift= _NEntries;
+00380                 _RollingTables[i].Remainder= 0;
+00381 
+00382                 // shift the entire array.
+00383                 _RollingTables[i].shiftEntries(entryShift, pulledElements);
+00384         }
+00385 }
+00386 
+00387 
+00388 // ***************************************************************************
+00389 // ***************************************************************************
+00390 // Rolling table.
+00391 // ***************************************************************************
+00392 // ***************************************************************************
+00393 
+00394 // ***************************************************************************
+00395 CTessFacePriorityList::CRollingTable::CRollingTable()
+00396 {
+00397         _EntryStart= 0;
+00398         _NEntries= 0;
+00399         _MaskEntries= 0;
+00400         Remainder= 0;
+00401 }
+00402 
+00403 // ***************************************************************************
+00404 CTessFacePriorityList::CRollingTable::~CRollingTable()
+00405 {
+00406         clearRollTable();
+00407 }
+00408 
+00409 
+00410 // ***************************************************************************
+00411 void            CTessFacePriorityList::CRollingTable::init(uint numEntries)
+00412 {
+00413         _EntryStart= 0;
+00414         _NEntries= numEntries;
+00415         _MaskEntries= _NEntries-1;
+00416         Remainder= 0;
+00417         _Entries.resize(numEntries);
+00418 }
+00419 
+00420 
+00421 // ***************************************************************************
+00422 void            CTessFacePriorityList::CRollingTable::insertInRollTable(uint entry, CTessFace *value)
+00423 {
+00424         CTessFacePListNode      &root= _Entries[ (entry + _EntryStart) & _MaskEntries ];
+00425 
+00426         // Insert into list.
+00427         value->linkInPList(root);
+00428 }
+00429 
+00430 // ***************************************************************************
+00431 CTessFacePListNode      &CTessFacePriorityList::CRollingTable::getRollTableEntry(uint entry)
+00432 {
+00433         CTessFacePListNode      &root= _Entries[ (entry + _EntryStart) & _MaskEntries ];
+00434         return root;
+00435 }
+00436 
+00437 // ***************************************************************************
+00438 void            CTessFacePriorityList::CRollingTable::clearRollTableEntry(uint entry)
+00439 {
+00440         CTessFacePListNode      &root= _Entries[ (entry + _EntryStart) & _MaskEntries ];
+00441 
+00442         // clear all the list.
+00443         while( root.nextInPList() != &root )
+00444         {
+00445                 // unlink from list
+00446                 CTessFacePListNode      *node= root.nextInPList();
+00447                 node->unlinkInPList();
+00448         }
+00449 }
+00450 
+00451 // ***************************************************************************
+00452 void            CTessFacePriorityList::CRollingTable::shiftRollTable(uint shiftEntry)
+00453 {
+00454         // delete all elements shifted.
+00455         for(uint i=0; i<shiftEntry; i++)
+00456         {
+00457                 clearRollTableEntry(i);
+00458         }
+00459         // shift to right the ptr of entries.
+00460         _EntryStart+= shiftEntry;
+00461         _EntryStart= _EntryStart & _MaskEntries;
+00462 }
+00463 
+00464 // ***************************************************************************
+00465 void            CTessFacePriorityList::CRollingTable::clearRollTable()
+00466 {
+00467         for(uint i=0; i<_NEntries; i++)
+00468         {
+00469                 clearRollTableEntry(i);
+00470         }
+00471         _EntryStart= 0;
+00472         // For convenience only (not really usefull).
+00473         Remainder= 0;
+00474 }
+00475 
+00476 // ***************************************************************************
+00477 void            CTessFacePriorityList::CRollingTable::shiftEntries(uint entryShift, CTessFacePListNode  &pulledElements)
+00478 {
+00479         if(entryShift>0)
+00480         {
+00481                 // before shifting the roll Table, fill pulledElements.
+00482                 for(uint i=0; i<entryShift; i++)
+00483                 {
+00484                         // For all elements of the ith entry, pull them and isnert in result list.
+00485                         pulledElements.appendPList(getRollTableEntry(i));
+00486                 }
+00487 
+00488                 // shift the roll Table. lists are already empty.
+00489                 shiftRollTable(entryShift);
+00490         }
+00491 }
+00492 
+00493 
+00494 
+00495 
+00496 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1