#include <stripifier.h>
Nevrax France
Definition at line 43 of file stripifier.h.
Public Member Functions | |
CStripifier () | |
Constructor. | |
void | optimizeTriangles (const CPrimitiveBlock &in, CPrimitiveBlock &out, uint cacheSize=10) |
|
Constructor.
Definition at line 42 of file stripifier.cpp.
00043 { 00044 } |
|
reorganize triangles to get efficiency of GPU vertex-cache. Default vertex cache is 10. out get the same list of triangles, but in different order. any list of lines / quads in out are not modified. NB: &in == &out is possible. Definition at line 196 of file stripifier.cpp. References NL3D::CCornerNode::FaceId, NL3D::CVertexCache::getVertexInCache(), in, NL3D::CCornerNode::Next, NL3D::CPrimitiveBlock::reserveTri(), NL3D::CPrimitiveBlock::setNumTri(), sint, NL3D::CVertexCache::tempTouchVertex(), uint, NL3D::COrderFace::v, v, and NL3D::CCornerNode::VertexId. Referenced by NL3D::CMeshMRMSkinnedGeom::CLod::optimizeTriangleOrder(), NL3D::CMeshMRMGeom::CLod::optimizeTriangleOrder(), and NL3D::CMeshGeom::optimizeTriangleOrder().
00197 { 00198 vector<COrderFace> inFaces; 00199 sint i; 00200 sint numTris= in.getNumTri(); 00201 00202 // TestYoyo: All the same tri => perfect vertex caching... 00203 /*out.setNumTri(numTris); 00204 for(i=0;i< numTris; i++) 00205 { 00206 uint32 v0= *(in.getTriPointer()+0); 00207 uint32 v1= *(in.getTriPointer()+1); 00208 uint32 v2= *(in.getTriPointer()+2); 00209 out.setTri(i, v0, v1, v2); 00210 } 00211 return;*/ 00212 00213 00214 // prepare inIndices. 00215 //-------------------- 00216 inFaces.resize(numTris); 00217 for(i=0;i< numTris; i++) 00218 { 00219 inFaces[i].v[0]= in.getTriPointer()[i*3 + 0]; 00220 inFaces[i].v[1]= in.getTriPointer()[i*3 + 1]; 00221 inFaces[i].v[2]= in.getTriPointer()[i*3 + 2]; 00222 inFaces[i].Inserted= false; 00223 } 00224 00225 00226 // build our cache, and compute max number of vertices. 00227 //-------------------- 00228 int numVerts=0; 00229 for (i = 0; i < numTris; i++) 00230 { 00231 numVerts= max(numVerts, (int)inFaces[i].v[0]); 00232 numVerts= max(numVerts, (int)inFaces[i].v[1]); 00233 numVerts= max(numVerts, (int)inFaces[i].v[2]); 00234 } 00235 numVerts++; 00236 CVertexCache vertexCache(cacheSize, numVerts); 00237 00238 00239 // Compute vertex connectivity. 00240 //-------------------- 00241 vector<CCornerNode*> vertexConnectivity; 00242 vector<CCornerNode> cornerAllocator; 00243 cornerAllocator.resize(numTris * 3); 00244 vertexConnectivity.resize(numVerts, NULL); 00245 // For all triangles. 00246 for (i = 0; i < numTris; i++) 00247 { 00248 COrderFace *ordFace= &inFaces[i]; 00249 // For each corner, allocate and fill 00250 for(sint j=0; j<3;j++) 00251 { 00252 sint vertexId= ordFace->v[j]; 00253 00254 // allocate a corner 00255 CCornerNode *corner= &cornerAllocator[i*3 + j]; 00256 00257 // fill it. 00258 corner->FaceId= i; 00259 corner->VertexId= vertexId; 00260 // Link it to the vertex list of faces. 00261 corner->Next= vertexConnectivity[vertexId]; 00262 vertexConnectivity[vertexId]= corner; 00263 } 00264 } 00265 00266 00267 // build output optimized triangles 00268 //-------------------- 00269 out.setNumTri(0); 00270 out.reserveTri(numTris); 00271 00272 for(i=0; i<numTris; i++) 00273 { 00274 // force insertion of the ith face. 00275 sint nextToInsert= i; 00276 bool nextToInsertFound= true; 00277 while( nextToInsertFound ) 00278 { 00279 nextToInsertFound= false; 00280 00281 // if the face is not yet inserted. 00282 if(!inFaces[nextToInsert].Inserted) 00283 { 00284 // must insert this face. 00285 inFaces[nextToInsert].insertInPB(out, vertexCache); 00286 00287 sint minC= 3; 00288 00289 // look only for faces which use vertices in VertexCache, to get a face with at least one vertex. 00290 for(uint j=0; j<cacheSize; j++) 00291 { 00292 // get a vertex from the vertex cache. 00293 uint vertexId= vertexCache.getVertexInCache(j); 00294 // if empty entry 00295 if(vertexId==0xFFFFFFFF) 00296 continue; 00297 00298 // parse list of faces which use this vertex. 00299 CCornerNode *corner= vertexConnectivity[vertexId]; 00300 while(corner) 00301 { 00302 uint faceId= corner->FaceId; 00303 00304 // if the face is not yet inserted. 00305 if(!inFaces[faceId].Inserted) 00306 { 00307 sint c= inFaces[faceId].countCacheMiss(vertexCache); 00308 // insert first any face which don't add any vertex in the cache. 00309 if(c==0) 00310 { 00311 inFaces[faceId].insertInPB(out, vertexCache); 00312 } 00313 // else the one which add the minimum of vertex possible: nextToInsert 00314 else 00315 { 00316 // Add cost of faces that use vertices pushed out (better results...) 00317 uint numVOut= c; 00318 uint k; 00319 for(k=cacheSize-numVOut; k<cacheSize; k++) 00320 { 00321 uint vertexOutId= vertexCache.getVertexInCache(k); 00322 if(vertexOutId==0xFFFFFFFF) 00323 continue; 00324 // TempRemove the vertex from the cache 00325 vertexCache.tempTouchVertex(vertexOutId, false); 00326 } 00327 // parse all faces that still use those out vertices. 00328 for(k=cacheSize-numVOut; k<cacheSize; k++) 00329 { 00330 uint vertexOutId= vertexCache.getVertexInCache(k); 00331 if(vertexOutId==0xFFFFFFFF) 00332 continue; 00333 CCornerNode *cornerOut= vertexConnectivity[vertexOutId]; 00334 while(cornerOut) 00335 { 00336 uint faceOutId= cornerOut->FaceId; 00337 00338 // if the face is not yet inserted AND not the one treated 00339 if(!inFaces[faceOutId].Inserted && faceOutId!=faceId) 00340 { 00341 // Add cache miss of this face 00342 c+= inFaces[faceOutId].countCacheMiss(vertexCache); 00343 } 00344 00345 // next corner 00346 cornerOut= cornerOut->Next; 00347 } 00348 } 00349 // reset touch 00350 for(k=cacheSize-numVOut; k<cacheSize; k++) 00351 { 00352 uint vertexOutId= vertexCache.getVertexInCache(k); 00353 if(vertexOutId==0xFFFFFFFF) 00354 continue; 00355 // restore TempTouch the vertex from the cache 00356 vertexCache.tempTouchVertex(vertexOutId, true); 00357 } 00358 00359 00360 // take the minimum cost 00361 if(c<minC) 00362 { 00363 nextToInsert= faceId; 00364 nextToInsertFound= true; 00365 minC= c; 00366 } 00367 } 00368 } 00369 00370 // next corner 00371 corner= corner->Next; 00372 } 00373 00374 } 00375 00376 // if nextToInsertFound, then nextToInsert has the face which add the minimum of vertex possible in the cache 00377 } 00378 } 00379 00380 } 00381 00382 } |