Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef TriangleIterator_INCLUDE_ONCE 00033 #define TriangleIterator_INCLUDE_ONCE 00034 00035 #include <vlGraphics/Array.hpp> 00036 #include <vlCore/vlnamespace.hpp> 00037 00038 namespace vl 00039 { 00040 //----------------------------------------------------------------------------- 00041 // TriangleIteratorAbstract 00042 //----------------------------------------------------------------------------- 00044 class TriangleIteratorAbstract: public Object 00045 { 00046 VL_INSTRUMENT_ABSTRACT_CLASS(vl::TriangleIteratorAbstract, Object) 00047 00048 public: 00049 virtual bool next() = 0; 00050 virtual bool hasNext() const = 0; 00051 virtual int a() const = 0; 00052 virtual int b() const = 0; 00053 virtual int c() const = 0; 00054 }; 00055 //----------------------------------------------------------------------------- 00056 // TriangleIteratorIndexed 00057 //----------------------------------------------------------------------------- 00059 template<class TArray> 00060 class TriangleIteratorIndexed: public TriangleIteratorAbstract 00061 { 00062 VL_INSTRUMENT_CLASS(vl::TriangleIteratorIndexed<TArray>, TriangleIteratorAbstract) 00063 00064 public: 00065 00066 TriangleIteratorIndexed() 00067 { 00068 VL_DEBUG_SET_OBJECT_NAME() 00069 mCurrentIndex = 0; 00070 mEnd = 0; 00071 mA = mB = mC = -1; 00072 mEven = true; 00073 mIndex0 = 0; 00074 mArray = NULL; 00075 mPrimRestartIndex = (unsigned int)-1; 00076 mPrimRestartOn = false; 00077 mBaseVertex = 0; 00078 mPrimType = PT_UNKNOWN; 00079 } 00080 00081 TriangleIteratorIndexed(const TArray* idx_array, EPrimitiveType prim_type, int base_vert, bool prim_restart_on, unsigned int prim_restart_idx) 00082 { 00083 VL_DEBUG_SET_OBJECT_NAME() 00084 mCurrentIndex = 0; 00085 mEnd = 0; 00086 mA = mB = mC = -1; 00087 mEven = true; 00088 mIndex0 = 0; 00089 mArray = idx_array; 00090 mPrimRestartIndex = prim_restart_idx; 00091 mPrimRestartOn = prim_restart_on; 00092 mBaseVertex = base_vert; 00093 mPrimType = prim_type; 00094 } 00095 00096 bool hasNext() const { return mCurrentIndex != mEnd; } 00097 00098 virtual int a() const { return mA; } 00099 virtual int b() const { return mB; } 00100 virtual int c() const { return mC; } 00101 00102 void initialize(int start=0, int end=-1) 00103 { 00104 VL_CHECK( start >= 0 ) 00105 VL_CHECK( end <= (int)mArray->size() ) 00106 00107 if (end == -1) 00108 end = (int)mArray->size(); 00109 00110 mCurrentIndex = end; // end 00111 mA = mB = mC = -1; 00112 mEven = true; 00113 mIndex0 = start; 00114 mEnd = end; 00115 if (mArray->size()) 00116 { 00117 switch(mPrimType) 00118 { 00119 case PT_TRIANGLES: 00120 // VL_CHECK( (end-start) % 3 == 0 ) /* primitive restart might screw up this */ 00121 mCurrentIndex = start; 00122 mA = mArray->at(start+0); 00123 mB = mArray->at(start+1); 00124 mC = mArray->at(start+2); 00125 break; 00126 case PT_TRIANGLE_STRIP: 00127 mCurrentIndex = start; 00128 mA = mArray->at(start+0); 00129 mB = mArray->at(start+1); 00130 mC = mArray->at(start+2); 00131 break; 00132 case PT_TRIANGLE_FAN: 00133 case PT_POLYGON: 00134 mCurrentIndex = start + 1; 00135 mA = mArray->at(start+0); 00136 mB = mArray->at(start+1); 00137 mC = mArray->at(start+2); 00138 break; 00139 case PT_QUADS: 00140 // VL_CHECK( (end-start) % 4 == 0 ) /* primitive restart might screw up this */ 00141 mCurrentIndex = start; 00142 mA = mArray->at(start+0); 00143 mB = mArray->at(start+1); 00144 mC = mArray->at(start+2); 00145 break; 00146 case PT_QUAD_STRIP: 00147 // VL_CHECK( (end-start) % 2 == 0 ) /* primitive restart might screw up this */ 00148 mCurrentIndex = start; 00149 mA = mArray->at(start+0); 00150 mB = mArray->at(start+1); 00151 mC = mArray->at(start+2); 00152 break; 00153 default: 00154 break; 00155 } 00156 } 00157 00158 // if we are not at the end then add base vertices 00159 if ( mCurrentIndex != mEnd ) 00160 { 00161 mA += mBaseVertex; 00162 mB += mBaseVertex; 00163 mC += mBaseVertex; 00164 } 00165 else 00166 { 00167 mA = mB = mC = -1; 00168 } 00169 } 00170 00171 bool next() 00172 { 00173 // reached the end 00174 if ( mCurrentIndex == mEnd ) 00175 return false; 00176 00177 switch(mPrimType) 00178 { 00179 00180 case PT_TRIANGLES: 00181 mCurrentIndex += 3; 00182 // check for the end 00183 if ( mCurrentIndex >= mEnd ) 00184 mCurrentIndex = mEnd; 00185 else 00186 if ( isPrimRestart(mCurrentIndex) ) 00187 { 00188 mCurrentIndex += 1; 00189 mA = mArray->at(mCurrentIndex + 0); 00190 mB = mArray->at(mCurrentIndex + 1); 00191 mC = mArray->at(mCurrentIndex + 2); 00192 } 00193 else 00194 { 00195 mA = mArray->at(mCurrentIndex + 0); 00196 mB = mArray->at(mCurrentIndex + 1); 00197 mC = mArray->at(mCurrentIndex + 2); 00198 } 00199 break; 00200 00201 case PT_QUAD_STRIP: 00202 case PT_TRIANGLE_STRIP: 00203 mCurrentIndex += 1; 00204 if ( mCurrentIndex + 2 >= mEnd ) 00205 mCurrentIndex = mEnd; 00206 else 00207 if ( isPrimRestart(mCurrentIndex + 2) ) 00208 { 00209 mCurrentIndex += 3; 00210 mEven = true; 00211 mA = mArray->at(mCurrentIndex + 0); 00212 mB = mArray->at(mCurrentIndex + 1); 00213 mC = mArray->at(mCurrentIndex + 2); 00214 } 00215 else 00216 { 00217 mEven = !mEven; 00218 if (mEven) 00219 { 00220 mA = mArray->at(mCurrentIndex + 0); 00221 mB = mArray->at(mCurrentIndex + 1); 00222 mC = mArray->at(mCurrentIndex + 2); 00223 } 00224 else 00225 { 00226 mA = mArray->at(mCurrentIndex + 0); 00227 mB = mArray->at(mCurrentIndex + 2); 00228 mC = mArray->at(mCurrentIndex + 1); 00229 } 00230 } 00231 break; 00232 00233 case PT_TRIANGLE_FAN: 00234 case PT_POLYGON: 00235 mCurrentIndex += 1; 00236 if ( mCurrentIndex + 1 >= mEnd ) 00237 { 00238 mCurrentIndex = mEnd; 00239 } 00240 else 00241 if ( isPrimRestart(mCurrentIndex + 1) ) 00242 { 00243 mIndex0 = mCurrentIndex + 2; 00244 mCurrentIndex = mIndex0 + 1; 00245 mA = mArray->at(mIndex0); 00246 mB = mArray->at(mCurrentIndex + 0); 00247 mC = mArray->at(mCurrentIndex + 1); 00248 } 00249 else 00250 { 00251 mA = mArray->at(mIndex0); 00252 mB = mArray->at(mCurrentIndex + 0); 00253 mC = mArray->at(mCurrentIndex + 1); 00254 } 00255 break; 00256 00257 case PT_QUADS: 00258 mCurrentIndex += 2; 00259 if ( mCurrentIndex >= mEnd ) 00260 { 00261 mCurrentIndex = mEnd; 00262 } 00263 else 00264 if ( isPrimRestart(mCurrentIndex) ) 00265 { 00266 mCurrentIndex += 1; 00267 mEven = true; 00268 mA = mArray->at(mCurrentIndex+0); 00269 mB = mArray->at(mCurrentIndex+1); 00270 mC = mArray->at(mCurrentIndex+2); 00271 } 00272 else 00273 { 00274 mEven = !mEven; 00275 if ( mEven ) 00276 { 00277 mA = mArray->at(mCurrentIndex+0); 00278 mB = mArray->at(mCurrentIndex+1); 00279 mC = mArray->at(mCurrentIndex+2); 00280 } 00281 else 00282 { 00283 mA = mArray->at(mCurrentIndex+0); 00284 mB = mArray->at(mCurrentIndex+1); 00285 mC = mArray->at(mCurrentIndex-2); 00286 } 00287 } 00288 break; 00289 00290 default: 00291 VL_TRAP(); 00292 break; 00293 } 00294 00295 // if we are not at the end then add base vertices 00296 if (mCurrentIndex != mEnd) 00297 { 00298 mA += mBaseVertex; 00299 mB += mBaseVertex; 00300 mC += mBaseVertex; 00301 return true; 00302 } 00303 else 00304 { 00305 mA = mB = mC = -1; 00306 return false; 00307 } 00308 } 00309 00310 void setBaseVertex(int base_vert) { mBaseVertex = base_vert; } 00311 int baseVertex() const { return mBaseVertex; } 00312 00313 private: 00314 bool isPrimRestart(int i) const { return mPrimRestartOn && mArray->at(i) == mPrimRestartIndex; } 00315 00316 private: 00317 const TArray* mArray; 00318 EPrimitiveType mPrimType; 00319 int mA, mB, mC; 00320 int mCurrentIndex; 00321 int mIndex0; 00322 int mEnd; 00323 int mBaseVertex; 00324 unsigned int mPrimRestartIndex; 00325 bool mPrimRestartOn; 00326 bool mEven; 00327 }; 00328 //----------------------------------------------------------------------------- 00329 // TriangleIteratorDirect 00330 //----------------------------------------------------------------------------- 00332 class TriangleIteratorDirect: public TriangleIteratorAbstract 00333 { 00334 VL_INSTRUMENT_CLASS(vl::TriangleIteratorDirect, TriangleIteratorAbstract) 00335 00336 public: 00337 TriangleIteratorDirect(EPrimitiveType prim_type=PT_UNKNOWN) 00338 { 00339 VL_DEBUG_SET_OBJECT_NAME() 00340 mCurrentIndex = mStart = mEnd = 0; 00341 mA = mB = mC = -1; 00342 mPrimType = prim_type; 00343 mEven = true; 00344 } 00345 00346 bool hasNext() const { return mCurrentIndex != mEnd; } 00347 00348 virtual int a() const { return mA; } 00349 virtual int b() const { return mB; } 00350 virtual int c() const { return mC; } 00351 00352 void initialize(int start, int end) 00353 { 00354 VL_CHECK(end >= start) 00355 mStart = start; 00356 mCurrentIndex = mEnd = end; 00357 mA = mB = mC = -1; 00358 mEven = true; 00359 switch(mPrimType) 00360 { 00361 case PT_TRIANGLES: 00362 // VL_CHECK( (end - start) % 3 == 0 ) /* primitive restart might screw up this */ 00363 mCurrentIndex = start; 00364 mA = start + 0; 00365 mB = start + 1; 00366 mC = start + 2; 00367 break; 00368 case PT_TRIANGLE_STRIP: 00369 mCurrentIndex = start; 00370 mA = start + 0; 00371 mB = start + 1; 00372 mC = start + 2; 00373 break; 00374 case PT_TRIANGLE_FAN: 00375 case PT_POLYGON: 00376 mCurrentIndex = start + 1; 00377 mA = start + 0; 00378 mB = start + 1; 00379 mC = start + 2; 00380 break; 00381 case PT_QUADS: 00382 // VL_CHECK( (end - start) % 4 == 0 ) /* primitive restart might screw up this */ 00383 mCurrentIndex = start; 00384 mA = start + 0; 00385 mB = start + 1; 00386 mC = start + 2; 00387 break; 00388 case PT_QUAD_STRIP: 00389 // VL_CHECK( (end - start) % 2 == 0 ) /* primitive restart might screw up this */ 00390 mCurrentIndex = start; 00391 mA = start + 0; 00392 mB = start + 1; 00393 mC = start + 2; 00394 break; 00395 default: 00396 break; 00397 } 00398 } 00399 00400 bool next() 00401 { 00402 // reached the end 00403 if ( mCurrentIndex == mEnd ) 00404 return false; 00405 00406 switch(mPrimType) 00407 { 00408 00409 case PT_TRIANGLES: 00410 mCurrentIndex += 3; 00411 // check for the end 00412 if ( mCurrentIndex >= mEnd ) 00413 mCurrentIndex = mEnd; 00414 else 00415 { 00416 mA = mCurrentIndex + 0; 00417 mB = mCurrentIndex + 1; 00418 mC = mCurrentIndex + 2; 00419 } 00420 break; 00421 00422 case PT_QUAD_STRIP: 00423 case PT_TRIANGLE_STRIP: 00424 mCurrentIndex += 1; 00425 if ( mCurrentIndex + 2 >= mEnd ) 00426 mCurrentIndex = mEnd; 00427 else 00428 { 00429 mEven = !mEven; 00430 if (mEven) 00431 { 00432 mA = mCurrentIndex + 0; 00433 mB = mCurrentIndex + 1; 00434 mC = mCurrentIndex + 2; 00435 } 00436 else 00437 { 00438 mA = mCurrentIndex + 0; 00439 mB = mCurrentIndex + 2; 00440 mC = mCurrentIndex + 1; 00441 } 00442 } 00443 break; 00444 00445 case PT_TRIANGLE_FAN: 00446 case PT_POLYGON: 00447 mCurrentIndex += 1; 00448 if ( mCurrentIndex + 1 >= mEnd ) 00449 { 00450 mCurrentIndex = mEnd; 00451 } 00452 else 00453 { 00454 mA = mStart; 00455 mB = mCurrentIndex+0; 00456 mC = mCurrentIndex+1; 00457 } 00458 break; 00459 00460 case PT_QUADS: 00461 mCurrentIndex += 2; 00462 if ( mCurrentIndex >= mEnd ) 00463 { 00464 mCurrentIndex = mEnd; 00465 } 00466 else 00467 { 00468 mEven = !mEven; 00469 if ( mEven ) 00470 { 00471 mA = mCurrentIndex+0; 00472 mB = mCurrentIndex+1; 00473 mC = mCurrentIndex+2; 00474 } 00475 else 00476 { 00477 mA = mCurrentIndex+0; 00478 mB = mCurrentIndex+1; 00479 mC = mCurrentIndex-2; 00480 } 00481 } 00482 break; 00483 00484 default: 00485 VL_TRAP(); 00486 break; 00487 } 00488 00489 // if we are not at the end then add base vertices 00490 if (mCurrentIndex == mEnd) 00491 { 00492 mA = mB = mC = -1; 00493 return false; 00494 } 00495 else 00496 return true; 00497 } 00498 00499 private: 00500 EPrimitiveType mPrimType; 00501 int mA, mB, mC; 00502 int mCurrentIndex; 00503 int mStart; 00504 int mEnd; 00505 bool mEven; 00506 }; 00507 //----------------------------------------------------------------------------- 00508 // TriangleIteratorMulti 00509 //----------------------------------------------------------------------------- 00511 template<class TArray> 00512 class TriangleIteratorMulti: public TriangleIteratorIndexed<TArray> 00513 { 00514 VL_INSTRUMENT_CLASS(vl::TriangleIteratorMulti<class TArray>, TriangleIteratorIndexed<TArray>) 00515 00516 public: 00517 TriangleIteratorMulti( const std::vector<GLint>* p_base_vertices, const std::vector<GLsizei>* p_count_vector, const TArray* idx_array, EPrimitiveType prim_type, bool prim_restart_on, int prim_restart_idx) 00518 :TriangleIteratorIndexed<TArray>( idx_array, prim_type, 0, prim_restart_on, prim_restart_idx) 00519 { 00520 VL_DEBUG_SET_OBJECT_NAME() 00521 mpBaseVertices = p_base_vertices; 00522 mpCountVector = p_count_vector; 00523 mStart = 0; 00524 mCurPrim = 0; 00525 } 00526 00527 void initialize() 00528 { 00529 VL_CHECK( mpBaseVertices->size() == mpCountVector->size() ) 00530 if ( (*mpBaseVertices).size() ) 00531 TriangleIteratorIndexed<TArray>::setBaseVertex( (*mpBaseVertices)[mCurPrim] ); 00532 int end = mStart + (*mpCountVector)[mCurPrim]; 00533 TriangleIteratorIndexed<TArray>::initialize( mStart, end ); 00534 // abort if could not initialize (primitive not supported) 00535 if ( !TriangleIteratorIndexed<TArray>::hasNext() ) 00536 mCurPrim = (int)(*mpCountVector).size()-1; 00537 } 00538 00539 bool next() 00540 { 00541 if ( TriangleIteratorIndexed<TArray>::next() ) 00542 return true; 00543 else 00544 if ( mCurPrim < (int)(*mpCountVector).size()-1 ) 00545 { 00546 mStart += (*mpCountVector)[mCurPrim]; 00547 mCurPrim++; 00548 initialize(); 00549 return true; 00550 } 00551 else 00552 return false; 00553 } 00554 00555 bool hasNext() const 00556 { 00557 if ( !TriangleIteratorIndexed<TArray>::hasNext() && mCurPrim == (int)(*mpCountVector).size()-1 ) 00558 return false; 00559 else 00560 return true; 00561 } 00562 00563 protected: 00564 const std::vector<GLint>* mpBaseVertices; 00565 const std::vector<GLsizei>* mpCountVector; 00566 int mCurPrim; 00567 int mStart; 00568 }; 00569 //----------------------------------------------------------------------------- 00570 // TriangleIterator 00571 //----------------------------------------------------------------------------- 00575 class TriangleIterator 00576 { 00577 public: 00578 TriangleIterator(TriangleIteratorAbstract* it): mIterator(it) { } 00579 00581 bool next() { return mIterator->next(); } 00582 00583 bool operator++() { return next(); } 00584 00586 bool hasNext() { return mIterator->hasNext(); } 00587 00589 int a() const { return mIterator->a(); } 00590 00592 int b() const { return mIterator->b(); } 00593 00595 int c() const { return mIterator->c(); } 00596 00597 protected: 00598 ref<TriangleIteratorAbstract> mIterator; 00599 }; 00600 //----------------------------------------------------------------------------- 00601 } 00602 00603 #endif