#include <tess_face_priority_list.h>
NB: it works quite well if you have (as example) a distStep of 1, and you shift only with value of 0.01 etc.., because it manages a "Remainder system", which do the good stuff. How does it works? in essence, it is a Rolling table, with 1+ shift back when necessary (maybe not at each shift()).
Additionally, it includes a "2D quadrant" notion. If you use this class to know when the "camera" enters a specific area, then Quadrants help you because the notion of direction is kept. Only the XY plane is used here.
Instead, if you use this class to know when the "camera" leaves a specific area, then the quadrant notion is not interesting since the camera can leave the area in any direction...
Nevrax France
Definition at line 112 of file tess_face_priority_list.h.
Public Member Functions | |
void | clear () |
CTessFacePriorityList () | |
Constructor. | |
const NLMISC::CVector & | getQuadrantDirection (uint quadrantId) const |
void | init (float distStep, uint numEntries, float distMaxMod, uint numQuadrant) |
void | insert (uint quadrantId, float distance, CTessFace *value) |
uint | selectQuadrant (const NLMISC::CVector &direction) |
void | shift (const NLMISC::CVector &direction, CTessFacePListNode &pulledElements) |
void | shiftAll (CTessFacePListNode &pulledElements) |
~CTessFacePriorityList () | |
Private Attributes | |
uint | _EntryModStart |
uint | _MaskEntries |
uint | _MaskQuadrant |
uint | _NEntries |
uint | _NumQuadrant |
float | _OODistStep |
uint | _QuarterQuadrantEnd [4] |
uint | _QuarterQuadrantStart [4] |
float | _Remainder |
The rolling tables | |
std::vector< CRollingTable > | _RollingTables |
|
Constructor.
Definition at line 134 of file tess_face_priority_list.cpp. References _EntryModStart, _MaskEntries, _NEntries, _NumQuadrant, and _OODistStep.
00135 { 00136 _OODistStep= 1; 00137 _NEntries= 0; 00138 _MaskEntries= 0; 00139 _EntryModStart= 0; 00140 _NumQuadrant= 0; 00141 } |
|
Definition at line 144 of file tess_face_priority_list.cpp. References clear().
00145 { 00146 clear(); 00147 } |
|
Clear the priority list. All elements are removed. NB: for convenience, the remainder is reset. Definition at line 201 of file tess_face_priority_list.cpp. References _RollingTables. Referenced by init(), and ~CTessFacePriorityList().
00202 { 00203 // just clear all the rolling tables. 00204 _RollingTables.clear(); 00205 } |
|
get the quadrant dir associated to the Id. Undefined if 0. Definition at line 145 of file tess_face_priority_list.h. References _RollingTables, and uint. Referenced by NL3D::CTessFace::updateRefineSplit().
00145 {return _RollingTables[quadrantId].QuadrantDirection;} |
|
Clear and Init the priority list. It reserve (numQuadrants+1) Rolling table of numEntries entries.
Definition at line 150 of file tess_face_priority_list.cpp. References _EntryModStart, _MaskEntries, _MaskQuadrant, _NEntries, _NumQuadrant, _OODistStep, _QuarterQuadrantEnd, _QuarterQuadrantStart, _RollingTables, NLMISC::clamp(), clear(), NLMISC::CMatrix::getJ(), NLMISC::isPowerOf2(), nlassert, NLMISC::Pi, NLMISC::CMatrix::rotateZ(), and uint. Referenced by NL3D::CLandscape::CLandscape().
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 } |
|
Insert an element at a given distance, and in a given quadrant. Insert at the closest step. eg insert(1.2, elt) will insert elt at entry 1 (assuming distStep==1 here). Special case: if distance<=0, it is ensured that at each shift(), the element will be pulled. NB: manage correctly the entry where it is inserted, according to the Remainder system. USE OptFastFloor if distance>0 => MUST be enclosed in OptFastFloorBegin/OptFastFloorEnd()
Definition at line 273 of file tess_face_priority_list.cpp. References _EntryModStart, _MaskEntries, _NEntries, _OODistStep, _RollingTables, NL3D::CTessFacePriorityList::CRollingTable::insertInRollTable(), nlassert, NLMISC::OptFastFloor(), NL3D::CTessFacePriorityList::CRollingTable::Remainder, sint, uint, and value. Referenced by NL3D::CTessFace::doMerge(), NL3D::CTessFace::split(), NL3D::CTessFace::splitRectangular(), NL3D::CTessFace::updateRefineMerge(), and NL3D::CTessFace::updateRefineSplit().
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= NLMISC::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 } |
|
prior to insert an element with a direction notion, select which quadrant according to the direction Camera -> center of interest.
Definition at line 209 of file tess_face_priority_list.cpp. References _MaskQuadrant, _NumQuadrant, _QuarterQuadrantEnd, _QuarterQuadrantStart, _RollingTables, uint, NLMISC::CVector::x, and NLMISC::CVector::y. Referenced by NL3D::CTessFace::updateRefineSplit().
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 } |
|
Shift the Priority list in a given direction. NB: for each rolling table, even if shiftDistance==0, all elements in the entry 0 are pulled out. pulledElements is the root of the list which will contains elements pulled from the list. Definition at line 314 of file tess_face_priority_list.cpp. References _NEntries, _OODistStep, _RollingTables, NL3D::CTessFacePListNode::appendPList(), NL3D::CTessFacePriorityList::CRollingTable::getRollTableEntry(), nlassert, NLMISC::CVector::norm(), NL3D::CTessFacePriorityList::CRollingTable::QuadrantDirection, NL3D::CTessFacePriorityList::CRollingTable::Remainder, NL3D::CTessFacePriorityList::CRollingTable::shiftEntries(), uint, and NL3D::CTessFacePListNode::unlinkInPList(). Referenced by NL3D::CLandscape::refine().
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 } |
|
Same as shift(), but shift all the array. Definition at line 368 of file tess_face_priority_list.cpp. References _NEntries, _RollingTables, nlassert, uint, and NL3D::CTessFacePListNode::unlinkInPList(). Referenced by NL3D::CLandscape::refine().
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 } |
|
Definition at line 187 of file tess_face_priority_list.h. Referenced by CTessFacePriorityList(), init(), and insert(). |
|
Definition at line 186 of file tess_face_priority_list.h. Referenced by CTessFacePriorityList(), init(), and insert(). |
|
Definition at line 190 of file tess_face_priority_list.h. Referenced by init(), and selectQuadrant(). |
|
Definition at line 185 of file tess_face_priority_list.h. Referenced by CTessFacePriorityList(), init(), insert(), shift(), and shiftAll(). |
|
Definition at line 188 of file tess_face_priority_list.h. Referenced by CTessFacePriorityList(), init(), and selectQuadrant(). |
|
Definition at line 184 of file tess_face_priority_list.h. Referenced by CTessFacePriorityList(), init(), insert(), and shift(). |
|
Definition at line 192 of file tess_face_priority_list.h. Referenced by init(), and selectQuadrant(). |
|
Definition at line 191 of file tess_face_priority_list.h. Referenced by init(), and selectQuadrant(). |
|
Definition at line 183 of file tess_face_priority_list.h. |
|
Definition at line 243 of file tess_face_priority_list.h. Referenced by clear(), getQuadrantDirection(), init(), insert(), selectQuadrant(), shift(), and shiftAll(). |