Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef TriangleIterator_INCLUDE_ONCE
00033 #define TriangleIterator_INCLUDE_ONCE
00034
00035 #include <vlCore/Array.hpp>
00036 #include <vlCore/vlnamespace.hpp>
00037
00038 namespace vl
00039 {
00040
00041
00042
00044 class TriangleIteratorAbstract: public Object
00045 {
00046 public:
00047 virtual const char* className() { return "vl::TriangleIteratorAbstract"; }
00048
00049 virtual bool next() = 0;
00050 virtual bool isEnd() const = 0;
00051 virtual int a() const = 0;
00052 virtual int b() const = 0;
00053 virtual int c() const = 0;
00054 };
00055
00056
00057
00059 template<class TArray>
00060 class TriangleIteratorIndexed: public TriangleIteratorAbstract
00061 {
00062 public:
00063 virtual const char* className() { return "vl::TriangleIteratorIndexed"; }
00064
00065 TriangleIteratorIndexed(TArray* idx_array, EPrimitiveType prim_type, int base_vert, bool prim_restart_on, unsigned int prim_restart_idx)
00066 {
00067 VL_DEBUG_SET_OBJECT_NAME()
00068 mCurrentIndex = 0;
00069 mEnd = 0;
00070 mA = mB = mC = -1;
00071 mEven = true;
00072 mIndex0 = 0;
00073 mArray = idx_array;
00074 mPrimRestartIndex = prim_restart_idx;
00075 mPrimRestartOn = prim_restart_on;
00076 mBaseVertex = base_vert;
00077 mPrimType = prim_type;
00078 }
00079
00080 bool isEnd() const { return mCurrentIndex == mEnd; }
00081
00082 virtual int a() const { return mA; }
00083 virtual int b() const { return mB; }
00084 virtual int c() const { return mC; }
00085
00086 void initialize(int start=0, int end=-1)
00087 {
00088 VL_CHECK( start >= 0 )
00089 VL_CHECK( end <= (int)mArray->size() )
00090
00091 if (end == -1)
00092 end = (int)mArray->size();
00093
00094 mCurrentIndex = end;
00095 mA = mB = mC = -1;
00096 mEven = true;
00097 mIndex0 = start;
00098 mEnd = end;
00099 if (mArray->size())
00100 {
00101 switch(mPrimType)
00102 {
00103 case PT_TRIANGLES:
00104
00105 mCurrentIndex = start;
00106 mA = mArray->at(start+0);
00107 mB = mArray->at(start+1);
00108 mC = mArray->at(start+2);
00109 break;
00110 case PT_TRIANGLE_STRIP:
00111 mCurrentIndex = start;
00112 mA = mArray->at(start+0);
00113 mB = mArray->at(start+1);
00114 mC = mArray->at(start+2);
00115 break;
00116 case PT_TRIANGLE_FAN:
00117 case PT_POLYGON:
00118 mCurrentIndex = start + 1;
00119 mA = mArray->at(start+0);
00120 mB = mArray->at(start+1);
00121 mC = mArray->at(start+2);
00122 break;
00123 case PT_QUADS:
00124
00125 mCurrentIndex = start;
00126 mA = mArray->at(start+0);
00127 mB = mArray->at(start+1);
00128 mC = mArray->at(start+2);
00129 break;
00130 case PT_QUAD_STRIP:
00131
00132 mCurrentIndex = start;
00133 mA = mArray->at(start+0);
00134 mB = mArray->at(start+1);
00135 mC = mArray->at(start+2);
00136 break;
00137 default:
00138 break;
00139 }
00140 }
00141
00142
00143 if ( mCurrentIndex != mEnd )
00144 {
00145 mA += mBaseVertex;
00146 mB += mBaseVertex;
00147 mC += mBaseVertex;
00148 }
00149 else
00150 {
00151 mA = mB = mC = -1;
00152 }
00153 }
00154
00155 bool next()
00156 {
00157
00158 if ( mCurrentIndex == mEnd )
00159 return false;
00160
00161 switch(mPrimType)
00162 {
00163
00164 case PT_TRIANGLES:
00165 mCurrentIndex += 3;
00166
00167 if ( mCurrentIndex >= mEnd )
00168 mCurrentIndex = mEnd;
00169 else
00170 if ( isPrimRestart(mCurrentIndex) )
00171 {
00172 mCurrentIndex += 1;
00173 mA = mArray->at(mCurrentIndex + 0);
00174 mB = mArray->at(mCurrentIndex + 1);
00175 mC = mArray->at(mCurrentIndex + 2);
00176 }
00177 else
00178 {
00179 mA = mArray->at(mCurrentIndex + 0);
00180 mB = mArray->at(mCurrentIndex + 1);
00181 mC = mArray->at(mCurrentIndex + 2);
00182 }
00183 break;
00184
00185 case PT_QUAD_STRIP:
00186 case PT_TRIANGLE_STRIP:
00187 mCurrentIndex += 1;
00188 if ( mCurrentIndex + 2 >= mEnd )
00189 mCurrentIndex = mEnd;
00190 else
00191 if ( isPrimRestart(mCurrentIndex + 2) )
00192 {
00193 mCurrentIndex += 3;
00194 mEven = true;
00195 mA = mArray->at(mCurrentIndex + 0);
00196 mB = mArray->at(mCurrentIndex + 1);
00197 mC = mArray->at(mCurrentIndex + 2);
00198 }
00199 else
00200 {
00201 mEven = !mEven;
00202 if (mEven)
00203 {
00204 mA = mArray->at(mCurrentIndex + 0);
00205 mB = mArray->at(mCurrentIndex + 1);
00206 mC = mArray->at(mCurrentIndex + 2);
00207 }
00208 else
00209 {
00210 mA = mArray->at(mCurrentIndex + 0);
00211 mB = mArray->at(mCurrentIndex + 2);
00212 mC = mArray->at(mCurrentIndex + 1);
00213 }
00214 }
00215 break;
00216
00217 case PT_TRIANGLE_FAN:
00218 case PT_POLYGON:
00219 mCurrentIndex += 1;
00220 if ( mCurrentIndex + 1 >= mEnd )
00221 {
00222 mCurrentIndex = mEnd;
00223 }
00224 else
00225 if ( isPrimRestart(mCurrentIndex + 1) )
00226 {
00227 mIndex0 = mCurrentIndex + 2;
00228 mCurrentIndex = mIndex0 + 1;
00229 mA = mArray->at(mIndex0);
00230 mB = mArray->at(mCurrentIndex + 0);
00231 mC = mArray->at(mCurrentIndex + 1);
00232 }
00233 else
00234 {
00235 mA = mArray->at(mIndex0);
00236 mB = mArray->at(mCurrentIndex + 0);
00237 mC = mArray->at(mCurrentIndex + 1);
00238 }
00239 break;
00240
00241 case PT_QUADS:
00242 mCurrentIndex += 2;
00243 if ( mCurrentIndex >= mEnd )
00244 {
00245 mCurrentIndex = mEnd;
00246 }
00247 else
00248 if ( isPrimRestart(mCurrentIndex) )
00249 {
00250 mCurrentIndex += 1;
00251 mEven = true;
00252 mA = mArray->at(mCurrentIndex+0);
00253 mB = mArray->at(mCurrentIndex+1);
00254 mC = mArray->at(mCurrentIndex+2);
00255 }
00256 else
00257 {
00258 mEven = !mEven;
00259 if ( mEven )
00260 {
00261 mA = mArray->at(mCurrentIndex+0);
00262 mB = mArray->at(mCurrentIndex+1);
00263 mC = mArray->at(mCurrentIndex+2);
00264 }
00265 else
00266 {
00267 mA = mArray->at(mCurrentIndex+0);
00268 mB = mArray->at(mCurrentIndex+1);
00269 mC = mArray->at(mCurrentIndex-2);
00270 }
00271 }
00272 break;
00273
00274 default:
00275 VL_TRAP();
00276 break;
00277 }
00278
00279
00280 if (mCurrentIndex != mEnd)
00281 {
00282 mA += mBaseVertex;
00283 mB += mBaseVertex;
00284 mC += mBaseVertex;
00285 return true;
00286 }
00287 else
00288 {
00289 mA = mB = mC = -1;
00290 return false;
00291 }
00292 }
00293
00294 void setBaseVertex(int base_vert) { mBaseVertex = base_vert; }
00295 int baseVertex() const { return mBaseVertex; }
00296
00297 private:
00298 bool isPrimRestart(int i) const { return mPrimRestartOn && mArray->at(i) == mPrimRestartIndex; }
00299
00300 private:
00301 ref<TArray> mArray;
00302 EPrimitiveType mPrimType;
00303 int mA, mB, mC;
00304 int mCurrentIndex;
00305 int mIndex0;
00306 int mEnd;
00307 int mBaseVertex;
00308 unsigned int mPrimRestartIndex;
00309 bool mPrimRestartOn;
00310 bool mEven;
00311 };
00312
00313
00314
00316 class TriangleIteratorDirect: public TriangleIteratorAbstract
00317 {
00318 public:
00319 virtual const char* className() { return "vl::TriangleIteratorDirect"; }
00320
00321 TriangleIteratorDirect(EPrimitiveType prim_type)
00322 {
00323 VL_DEBUG_SET_OBJECT_NAME()
00324 mCurrentIndex = mStart = mEnd = 0;
00325 mA = mB = mC = -1;
00326 mPrimType = prim_type;
00327 mEven = true;
00328 }
00329
00330 bool isEnd() const { return mCurrentIndex == mEnd; }
00331
00332 virtual int a() const { return mA; }
00333 virtual int b() const { return mB; }
00334 virtual int c() const { return mC; }
00335
00336 void initialize(int start, int end)
00337 {
00338 VL_CHECK(end >= start)
00339 mStart = start;
00340 mCurrentIndex = mEnd = end;
00341 mA = mB = mC = -1;
00342 mEven = true;
00343 switch(mPrimType)
00344 {
00345 case PT_TRIANGLES:
00346
00347 mCurrentIndex = start;
00348 mA = start + 0;
00349 mB = start + 1;
00350 mC = start + 2;
00351 break;
00352 case PT_TRIANGLE_STRIP:
00353 mCurrentIndex = start;
00354 mA = start + 0;
00355 mB = start + 1;
00356 mC = start + 2;
00357 break;
00358 case PT_TRIANGLE_FAN:
00359 case PT_POLYGON:
00360 mCurrentIndex = start + 1;
00361 mA = start + 0;
00362 mB = start + 1;
00363 mC = start + 2;
00364 break;
00365 case PT_QUADS:
00366
00367 mCurrentIndex = start;
00368 mA = start + 0;
00369 mB = start + 1;
00370 mC = start + 2;
00371 break;
00372 case PT_QUAD_STRIP:
00373
00374 mCurrentIndex = start;
00375 mA = start + 0;
00376 mB = start + 1;
00377 mC = start + 2;
00378 break;
00379 default:
00380 break;
00381 }
00382 }
00383
00384 bool next()
00385 {
00386
00387 if ( mCurrentIndex == mEnd )
00388 return false;
00389
00390 switch(mPrimType)
00391 {
00392
00393 case PT_TRIANGLES:
00394 mCurrentIndex += 3;
00395
00396 if ( mCurrentIndex >= mEnd )
00397 mCurrentIndex = mEnd;
00398 else
00399 {
00400 mA = mCurrentIndex + 0;
00401 mB = mCurrentIndex + 1;
00402 mC = mCurrentIndex + 2;
00403 }
00404 break;
00405
00406 case PT_QUAD_STRIP:
00407 case PT_TRIANGLE_STRIP:
00408 mCurrentIndex += 1;
00409 if ( mCurrentIndex + 2 >= mEnd )
00410 mCurrentIndex = mEnd;
00411 else
00412 {
00413 mEven = !mEven;
00414 if (mEven)
00415 {
00416 mA = mCurrentIndex + 0;
00417 mB = mCurrentIndex + 1;
00418 mC = mCurrentIndex + 2;
00419 }
00420 else
00421 {
00422 mA = mCurrentIndex + 0;
00423 mB = mCurrentIndex + 2;
00424 mC = mCurrentIndex + 1;
00425 }
00426 }
00427 break;
00428
00429 case PT_TRIANGLE_FAN:
00430 case PT_POLYGON:
00431 mCurrentIndex += 1;
00432 if ( mCurrentIndex + 1 >= mEnd )
00433 {
00434 mCurrentIndex = mEnd;
00435 }
00436 else
00437 {
00438 mA = mStart;
00439 mB = mCurrentIndex+0;
00440 mC = mCurrentIndex+1;
00441 }
00442 break;
00443
00444 case PT_QUADS:
00445 mCurrentIndex += 2;
00446 if ( mCurrentIndex >= mEnd )
00447 {
00448 mCurrentIndex = mEnd;
00449 }
00450 else
00451 {
00452 mEven = !mEven;
00453 if ( mEven )
00454 {
00455 mA = mCurrentIndex+0;
00456 mB = mCurrentIndex+1;
00457 mC = mCurrentIndex+2;
00458 }
00459 else
00460 {
00461 mA = mCurrentIndex+0;
00462 mB = mCurrentIndex+1;
00463 mC = mCurrentIndex-2;
00464 }
00465 }
00466 break;
00467
00468 default:
00469 VL_TRAP();
00470 break;
00471 }
00472
00473
00474 if (mCurrentIndex == mEnd)
00475 {
00476 mA = mB = mC = -1;
00477 return false;
00478 }
00479 else
00480 return true;
00481 }
00482
00483 private:
00484 EPrimitiveType mPrimType;
00485 int mA, mB, mC;
00486 int mCurrentIndex;
00487 int mStart;
00488 int mEnd;
00489 bool mEven;
00490 };
00491
00492
00493
00495 template<class TArray>
00496 class TriangleIteratorMulti: public TriangleIteratorIndexed<TArray>
00497 {
00498 public:
00499 virtual const char* className() { return "vl::TriangleIteratorMulti"; }
00500
00501 TriangleIteratorMulti( const std::vector<GLint>* p_base_vertices, const std::vector<GLsizei>* p_count_vector, TArray* idx_array, EPrimitiveType prim_type, bool prim_restart_on, int prim_restart_idx)
00502 :TriangleIteratorIndexed<TArray>( idx_array, prim_type, 0, prim_restart_on, prim_restart_idx)
00503 {
00504 VL_DEBUG_SET_OBJECT_NAME()
00505 mpBaseVertices = p_base_vertices;
00506 mpCountVector = p_count_vector;
00507 mStart = 0;
00508 mCurPrim = 0;
00509 }
00510
00511 void initialize()
00512 {
00513 VL_CHECK( mpBaseVertices->size() == mpCountVector->size() )
00514 if ( (*mpBaseVertices).size() )
00515 TriangleIteratorIndexed<TArray>::setBaseVertex( (*mpBaseVertices)[mCurPrim] );
00516 int end = mStart + (*mpCountVector)[mCurPrim];
00517 TriangleIteratorIndexed<TArray>::initialize( mStart, end );
00518
00519 if ( TriangleIteratorIndexed<TArray>::isEnd() )
00520 mCurPrim = (int)(*mpCountVector).size()-1;
00521 }
00522
00523 bool next()
00524 {
00525 if ( TriangleIteratorIndexed<TArray>::next() )
00526 return true;
00527 else
00528 if ( mCurPrim < (int)(*mpCountVector).size()-1 )
00529 {
00530 mStart += (*mpCountVector)[mCurPrim];
00531 mCurPrim++;
00532 initialize();
00533 return true;
00534 }
00535 else
00536 return false;
00537 }
00538
00539 bool isEnd() const
00540 {
00541 if ( TriangleIteratorIndexed<TArray>::isEnd() && mCurPrim == (int)(*mpCountVector).size()-1 )
00542 return true;
00543 else
00544 return false;
00545 }
00546
00547 protected:
00548 const std::vector<GLint>* mpBaseVertices;
00549 const std::vector<GLsizei>* mpCountVector;
00550 int mCurPrim;
00551 int mStart;
00552 };
00553
00554
00555
00559 class TriangleIterator
00560 {
00561 public:
00562 TriangleIterator(TriangleIteratorAbstract* it): mIterator(it) { }
00563
00565 bool next() { return mIterator->next(); }
00566
00568 bool isEnd() { return mIterator->isEnd(); }
00569
00571 int a() const { return mIterator->a(); }
00572
00574 int b() const { return mIterator->b(); }
00575
00577 int c() const { return mIterator->c(); }
00578
00579 protected:
00580 ref<TriangleIteratorAbstract> mIterator;
00581 };
00582
00583 }
00584
00585 #endif