![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsOpenGLModelStrand.cpp 00003 00004 Class OpenGLModelStrand is for creating an OpenGL Strand Model. 00005 00006 See class ModelStrand (in "../Model/TAPsModelStrand.hpp") and 00007 class OpenGLSupport ("../OpenGL/TAPsOpenGLSupport.hpp") for detail. 00008 00009 SUKITTI PUNAK (07/10/2005) 00010 UPDATE (06/15/2006) 00011 ******************************************************************************/ 00012 #include "TAPsOpenGLModelStrand.hpp" 00013 // Using Inclusion Model (i.e. definitions are included in declarations) 00014 // (this name.cpp is included in name.hpp) 00015 // Each friend is defined directly inside its declaration. 00016 00017 BEGIN_NAMESPACE_TAPs__OpenGL 00018 //============================================================================= 00019 //----------------------------------------------------------------------------- 00020 // Default Constructor 00021 template <typename T> 00022 OpenGLModelStrand<T>::OpenGLModelStrand () 00023 : ModelStrand<T>(), 00024 m_iNumSlices( 12 ), 00025 m_iNumStacks( 3 ) 00026 , m_uiDisplayList( 0 ) 00027 { 00028 SetUpOpenGLDisplayList(); 00029 SetMaterial( Enum::BLUE_NAVY ); 00030 00031 #ifdef TAPs_ENABLE_DEBUG 00032 std::cout << "OpenGLModelStrand<" << typeid(T).name() << "> Default Constructor\n"; 00033 #endif//TAPs_DEBUG_MODE 00034 } 00035 //----------------------------------------------------------------------------- 00036 // Non-Default Constructor 00037 template <typename T> 00038 OpenGLModelStrand<T>::OpenGLModelStrand ( int iNoLinks, T tLength, T tWeight, 00039 Vector3<T> & posOfVertex0, 00040 T radius, int numSlices, int numStacks ) 00041 00042 : ModelStrand<T>( iNoLinks, tLength, tWeight, posOfVertex0, radius ), 00043 m_iNumSlices( numSlices ), 00044 m_iNumStacks( numStacks ) 00045 , m_uiDisplayList( 0 ) 00046 { 00047 SetUpOpenGLDisplayList(); 00048 SetMaterial( Enum::BLUE_NAVY ); 00049 00050 #ifdef TAPs_ENABLE_DEBUG 00051 std::cout << "OpenGLModelStrand<" << typeid(T).name() << "> Non-Default Constructor\n"; 00052 #endif//TAPs_DEBUG_MODE 00053 } 00054 //----------------------------------------------------------------------------- 00055 // Destructor 00056 template <typename T> 00057 OpenGLModelStrand<T>::~OpenGLModelStrand () 00058 { 00059 #ifdef TAPs_ENABLE_DEBUG 00060 std::cout << "OpenGLModelStrand<" << typeid(T).name() << "> Destructor\n"; 00061 #endif//TAPs_DEBUG_MODE 00062 } 00063 //----------------------------------------------------------------------------- 00064 // Helper Fn 00065 // void DrawGL () 00066 template <typename T> 00067 void OpenGLModelStrand<T>::DrawGL ( GLenum drawMode ) 00068 { 00069 glPushAttrib( GL_LIGHTING_BIT ); 00070 //---------------------------------------------------------------- 00071 //glPushAttrib( GL_ALL_ATTRIB_BITS ); 00072 //ApplyMaterial( Enum::FRONT ); 00073 // Math<T>::PI; // Initialize Math<T>::PI 00074 Vector3<T> unitZ( 0, 0, 1 ); 00075 Vector3<T> direction; 00076 T currentLinkLength; 00077 Vector3<T> rotDir; 00078 T angle; 00079 //* 00080 if ( drawMode == OpenGL::Enum::WIRE_FRAME ) { 00081 //---------------------------------------------------------------- 00082 // Draw Original Line with Cylinder 00083 SetMaterial( Enum::METAL_SILVER ); 00084 ApplyMaterial( Enum::FRONT ); 00085 for ( int i = 0; i < m_iNoLinks; ++i ) { 00086 direction = m_prVertex[i+1] - m_prVertex[i]; 00087 currentLinkLength = direction.Length(); 00088 direction.Normalized(); 00089 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00090 rotDir = unitZ ^ direction; 00091 glPushMatrix(); 00092 glTranslatef( 00093 static_cast<float>( m_prVertex[i][0] ), 00094 static_cast<float>( m_prVertex[i][1] ), 00095 static_cast<float>( m_prVertex[i][2] ) 00096 ); 00097 glRotatef( 00098 angle, 00099 static_cast<float>( rotDir[0] ), 00100 static_cast<float>( rotDir[1] ), 00101 static_cast<float>( rotDir[2] ) 00102 ); 00103 if ( !m_prIsFixed[i] ) { 00104 SetMaterial( Enum::METAL_GOLD ); 00105 ApplyMaterial( Enum::FRONT ); 00106 glCallList( m_uiDisplayList ); 00107 SetMaterial( Enum::METAL_SILVER ); 00108 ApplyMaterial( Enum::FRONT ); 00109 glScalef( 1, 1, currentLinkLength ); 00110 glCallList( m_uiDisplayList+1 ); 00111 } 00112 else { 00113 SetMaterial( Enum::METAL_GOLD ); 00114 ApplyMaterial( Enum::FRONT ); 00115 glScalef( 4, 4, 4 ); 00116 glCallList( m_uiDisplayList ); 00117 SetMaterial( Enum::METAL_SILVER ); 00118 ApplyMaterial( Enum::FRONT ); 00119 glScalef( 0.25, 0.25, currentLinkLength*0.25 ); 00120 //glScalef( 1, 1, currentLinkLength ); 00121 glCallList( m_uiDisplayList+1 ); 00122 } 00123 glPopMatrix(); 00124 } 00125 // DrawTorsions(); 00126 } 00127 //*/ 00128 if ( true ) { 00129 //else { 00130 //---------------------------------------------------------------- 00131 // Draw Subdivision Line with Cylinder 00132 SetMaterial( Enum::BLUE_NAVY ); 00133 ApplyMaterial( Enum::FRONT ); 00134 if ( drawMode == OpenGL::Enum::POINT ) { 00135 #ifdef TAPs_STRAND_LOCK_SEGMENTS 00136 for ( unsigned int s = 0; s < m_Segments.size(); ++s ) { 00137 if ( !m_Segments[s].isLocked ) { 00138 for ( unsigned int i = m_Segments[s].start*2; i < 2*m_Segments[s].end; ++i ) 00139 #else //TAPs_STRAND_LOCK_SEGMENTS 00140 { 00141 { 00142 for ( int i = 0; i < 2*m_iNoLinks; ++i ) 00143 #endif//TAPs_STRAND_LOCK_SEGMENTS 00144 { 00145 glPushMatrix(); 00146 glTranslatef( 00147 static_cast<float>( m_prDispVertex[i][0] ), 00148 static_cast<float>( m_prDispVertex[i][1] ), 00149 static_cast<float>( m_prDispVertex[i][2] ) 00150 ); 00151 glCallList( m_uiDisplayList ); 00152 glPopMatrix(); 00153 } 00154 } 00155 } 00156 } 00157 else { 00158 #ifdef TAPs_STRAND_LOCK_SEGMENTS 00159 for ( unsigned int s = 0; s < m_Segments.size(); ++s ) { 00160 if ( !m_Segments[s].isLocked ) { 00161 for ( unsigned int i = m_Segments[s].start*2; i < 2*m_Segments[s].end-1; ++i ) 00162 #else //TAPs_STRAND_LOCK_SEGMENTS 00163 { 00164 { 00165 for ( int i = 0; i < 2*m_iNoLinks-1; ++i ) 00166 #endif//TAPs_STRAND_LOCK_SEGMENTS 00167 { 00168 direction = m_prDispVertex[i+1] - m_prDispVertex[i]; 00169 currentLinkLength = direction.Length(); 00170 direction.Normalized(); 00171 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00172 rotDir = unitZ ^ direction; 00173 glPushMatrix(); 00174 glTranslatef( 00175 static_cast<float>( m_prDispVertex[i][0] ), 00176 static_cast<float>( m_prDispVertex[i][1] ), 00177 static_cast<float>( m_prDispVertex[i][2] ) 00178 ); 00179 glRotatef( 00180 angle, 00181 static_cast<float>( rotDir[0] ), 00182 static_cast<float>( rotDir[1] ), 00183 static_cast<float>( rotDir[2] ) 00184 ); 00185 glCallList( m_uiDisplayList ); 00186 glScalef( 1, 1, currentLinkLength ); 00187 glCallList( m_uiDisplayList+1 ); 00188 glPopMatrix(); 00189 } 00190 } 00191 } 00192 } 00193 00194 00195 //if ( drawMode == OpenGL::Enum::WIRE_FRAME ) { 00196 // DrawBB(); 00197 //} 00198 00199 00200 //*/ 00201 00202 //* 00203 //------------------------------------------------------------ 00204 // Draw Fixed Point(s) 00205 if ( m_setOfFixedPts.size() != 0 ) { 00206 SetMaterial( Enum::METAL_BRONZE ); 00207 ApplyMaterial( Enum::FRONT ); 00208 int p; 00209 std::set<int>::const_iterator pos = m_setOfFixedPts.begin(); 00210 for ( int i = 0; i < static_cast<int>( m_setOfFixedPts.size() ); ++i, ++pos ) { 00211 p = *pos; 00212 glPushMatrix(); 00213 glTranslatef( 00214 static_cast<float>( m_prVertex[p][0] ), 00215 static_cast<float>( m_prVertex[p][1] ), 00216 static_cast<float>( m_prVertex[p][2] ) 00217 ); 00218 glScalef( 2, 2, 2 ); 00219 glCallList( m_uiDisplayList ); 00220 glPopMatrix(); 00221 } 00222 } 00223 //*/ 00224 } 00225 /* 00226 //---------------------------------------------------------------- 00227 // Draw Catmull-Rom spline 00228 if ( drawMode == GL_POINTS ) { 00229 SetMaterial( Enum::METAL_BRONZE ); 00230 ApplyMaterial( Enum::FRONT ); 00231 static Vector3<T> p; 00232 //std::set<int>::iterator p0 = m_setiD3BezierCurShape.begin(); 00233 std::set<int>::iterator p1 = p0; ++p1; 00234 std::set<int>::iterator p2 = p1; ++p2; 00235 std::set<int>::iterator p3 = p2; ++p3; 00236 for ( int i = 0; i < static_cast<int>( m_setiD3BezierCurShape.size()-3 ); ++i ) { 00237 for ( float t = 0.0f; t <= 1.0f; t+=0.025f ) { 00238 p = CGMath<T>::CatmullRomSplinePt( 00239 m_prVertex[*p0], 00240 m_prVertex[*p1], 00241 m_prVertex[*p2], 00242 m_prVertex[*p3], t ); 00243 glPushMatrix(); 00244 glTranslatef( 00245 static_cast<float>( p[0] ), 00246 static_cast<float>( p[1] ), 00247 static_cast<float>( p[2] ) 00248 ); 00249 if ( t == 0.0f ) glScalef( 1, 1, 1 ); 00250 else glScalef( 0.5, 0.5, 0.5 ); 00251 glCallList( m_uiDisplayList ); 00252 glPopMatrix(); 00253 } 00254 ++p0; ++p1; ++p2; ++p3; 00255 } 00256 } 00257 //*/ 00258 //---------------------------------------------------------------- 00259 glPopAttrib(); 00260 //---------------------------------------------------------------- 00261 //DrawTorsions(); 00262 //DrawOrigShape(); 00263 //---------------------------------------------------------------- 00264 // if ( drawMode == GL_POINTS ) { 00265 // DrawBezierCurve(); 00266 // } 00267 } 00268 /* 00269 //----------------------------------------------------------------------------- 00270 // Helper Fn 00271 // DrawTorsions Fn 00272 template <typename T> 00273 void OpenGLModelStrand<T>::DrawTorsions () 00274 { 00275 Vector3<T> unitZ( 0, 0, 1 ); 00276 Vector3<T> direction; 00277 T currentLinkLength; 00278 Vector3<T> rotDir; 00279 T angle; 00280 // Math<T>::PI; // Initialize Math<T>::PI 00281 //---------------------------------------------------------------- 00282 SetMaterial( Enum::RED ); 00283 ApplyMaterial( Enum::FRONT ); 00284 for ( int i = 0; i <= m_iNoLinks; ++i ) { 00285 direction = m_prVertex[i+1] - m_prVertex[i]; 00286 currentLinkLength = direction.Length(); 00287 direction.Normalized(); 00288 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00289 rotDir = unitZ ^ direction; 00290 //------------------------------------------------------ 00291 glPushMatrix(); 00292 glTranslatef( 00293 static_cast<float>( m_prVertex[i][0] ), 00294 static_cast<float>( m_prVertex[i][1] ), 00295 static_cast<float>( m_prVertex[i][2] ) ); 00296 glRotatef( 00297 m_prDegRot[i], 00298 static_cast<float>( m_prVertex[i][0] ), 00299 static_cast<float>( m_prVertex[i][1] ), 00300 static_cast<float>( m_prVertex[i][2] ) 00301 ); 00302 glScalef( 0.03, 0.03, 0.03 ); 00303 Obj::DrawOneHeadArrow(); 00304 glPopMatrix(); 00305 } 00306 } 00307 //*/ 00308 //----------------------------------------------------------------------------- 00309 // Helper Fn 00310 // void SetUpOpenGLDisplayList () 00311 template <typename T> 00312 void OpenGLModelStrand<T>::SetUpOpenGLDisplayList () 00313 { 00314 if ( !m_uiDisplayList ) { 00315 m_uiDisplayList = glGenLists( 2 ); 00316 GLUquadricObj *qObj = gluNewQuadric(); 00317 //------------------------------------------------------------ 00318 // Sphere with strand radius 00319 glNewList( m_uiDisplayList, GL_COMPILE ); 00320 gluSphere( qObj, m_tRadius, m_iNumSlices, m_iNumStacks ); 00321 glEndList(); 00322 //------------------------------------------------------------ 00323 // Cylinder with strand radius and length one which must be 00324 // scaled by the current link length of each link in 00325 // z-coordinate 00326 glNewList( m_uiDisplayList+1, GL_COMPILE ); 00327 gluCylinder( qObj, m_tRadius, m_tRadius, 00328 1.0, m_iNumSlices, m_iNumStacks ); 00329 glEndList(); 00330 gluDeleteQuadric( qObj ); 00331 } 00332 } 00333 /* 00334 //----------------------------------------------------------------------------- 00335 // Helper Fn 00336 // DrawBezierCurve Fn 00337 template <typename T> 00338 void OpenGLModelStrand<T>::DrawBezierCurve () 00339 { 00340 static Vector3<T> P[4], T0, T3; 00341 //T LENGTH = (m_iLoopSize-1) / 1.95 * m_tLinkLength; 00342 // e.g. 12 segments <==> 2 subdivisions of cublic Bezier curve 00343 T tLength; 00344 T A; 00345 static const int iNumSub = 3; 00346 static const int iNumCurvePts = 25; // depends on # of subdivisions 00347 // 1 -> 7, 2 -> 13, 3 -> 25, 4 -> 49 00348 static T offset = 0; 00349 static Vector3<T> pt[iNumCurvePts]; 00350 //---------------------------------------------------------------- 00351 // Draw Bezier Ctrl Pts and Curves 00352 Vector3<T> unitZ( 0, 0, 1 ); 00353 Vector3<T> direction; 00354 T currentLinkLength; 00355 Vector3<T> rotDir; 00356 T angle; 00357 int p; 00358 std::set<int>::iterator p0 = m_setiD3BezierCurShape.begin(); 00359 std::set<int>::iterator p1 = p0; ++p1; 00360 std::set<int>::iterator p2 = p1; ++p2; 00361 std::set<int>::iterator p3 = p2; ++p3; 00362 T3 = ( m_prVertex[*p0] - m_prVertex[*p1] ).Normalized(); 00363 for ( int i = 0; i < static_cast<int>( m_setiD3BezierCurShape.size() ) - 3; ++i ) { 00364 //------------------------------------------------------ 00365 // Draw Bezier Ctrl Pts 00366 p = *p0; 00367 SetMaterial( Enum::RED ); 00368 ApplyMaterial( Enum::FRONT ); 00369 glPushMatrix(); 00370 glTranslatef( 00371 static_cast<float>( m_prVertex[p][0] ), 00372 static_cast<float>( m_prVertex[p][1] + offset ), 00373 static_cast<float>( m_prVertex[p][2] ) 00374 ); 00375 glScalef( 2, 2, 2 ); 00376 glCallList( m_uiDisplayList ); 00377 glPopMatrix(); 00378 //------------------------------------------------------ 00379 // Draw Bezier Curves 00380 SetMaterial( Enum::BLUE ); 00381 ApplyMaterial( Enum::FRONT ); 00382 P[0] = m_prVertex[*p1]; 00383 P[3] = m_prVertex[*p2]; 00384 T0 = -T3; 00385 T3 = ( P[3] - m_prVertex[*p3] ).Normalized(); 00386 tLength = (*p2 - *p1) * m_tLinkLength * 1.0000001; 00387 A = CGMath<T>::SolveAForConstCubicBezierCurveLength( P[0], P[3], T0, T3, iNumSub, tLength, 0.00000001, pt ); 00388 ++p0; ++p1; ++p2; ++p3; 00389 //------------------------------------------------------ 00390 // Draw cubic Bezier ctrl pts 00391 P[1] = P[0] + A*T0; 00392 P[2] = P[3] + A*T3; 00393 for ( int p = 0; p < 3; ++p ) { 00394 direction = P[p+1] - P[p]; 00395 currentLinkLength = direction.Length(); 00396 direction.Normalized(); 00397 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00398 rotDir = unitZ ^ direction; 00399 glPushMatrix(); 00400 glTranslatef( 00401 static_cast<float>( P[p][0] ), 00402 static_cast<float>( P[p][1] + offset ), 00403 static_cast<float>( P[p][2] ) 00404 ); 00405 glRotatef( 00406 angle, 00407 static_cast<float>( rotDir[0] ), 00408 static_cast<float>( rotDir[1] ), 00409 static_cast<float>( rotDir[2] ) 00410 ); 00411 //glCallList( m_uiDisplayList ); 00412 glScalef( 0.25, 0.25, currentLinkLength ); 00413 glCallList( m_uiDisplayList+1 ); 00414 glPopMatrix(); 00415 } 00416 //------------------------------------------------------ 00417 for ( int p = 0; p < iNumCurvePts-1; ++p ) { 00418 direction = pt[p+1] - pt[p]; 00419 currentLinkLength = direction.Length(); 00420 direction.Normalized(); 00421 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00422 rotDir = unitZ ^ direction; 00423 glPushMatrix(); 00424 glTranslatef( 00425 static_cast<float>( pt[p][0] ), 00426 static_cast<float>( pt[p][1] + offset ), 00427 static_cast<float>( pt[p][2] ) 00428 ); 00429 glRotatef( 00430 angle, 00431 static_cast<float>( rotDir[0] ), 00432 static_cast<float>( rotDir[1] ), 00433 static_cast<float>( rotDir[2] ) 00434 ); 00435 //glCallList( m_uiDisplayList ); 00436 glScalef( 1, 1, currentLinkLength ); 00437 glCallList( m_uiDisplayList+1 ); 00438 glPopMatrix(); 00439 } 00440 } 00441 } 00442 //*/ 00443 00444 00445 /* 00446 //----------------------------------------------------------------------------- 00447 template <typename T> 00448 void OpenGLModelStrand<T>::DrawBB () 00449 { 00450 Vector3<T> unitZ( 0, 0, 1 ); 00451 Vector3<T> direction; 00452 T currentLinkLength; 00453 Vector3<T> rotDir; 00454 T angle; 00455 T offset = 0; 00456 for ( int i = 0; i < 512; ++i ) { 00457 //------------------------------------------------------ 00458 // Draw Bezier Ctrl Pts 00459 SetMaterial( Enum::GREEN ); 00460 ApplyMaterial( Enum::FRONT ); 00461 glPushMatrix(); 00462 glTranslatef( 00463 static_cast<float>( QQQ[i][0] ), 00464 static_cast<float>( QQQ[i][1] + offset ), 00465 static_cast<float>( QQQ[i][2] ) 00466 ); 00467 glScalef( 1, 1, 1 ); 00468 glCallList( m_uiDisplayList ); 00469 glPopMatrix(); 00470 } 00471 for ( int p = 0; p < 128; ++p ) { 00472 direction = CCC[p+1] - CCC[p]; 00473 currentLinkLength = direction.Length(); 00474 direction.Normalized(); 00475 angle = acos( unitZ * direction ) * Math<T>::RAD_TO_DEG; 00476 rotDir = unitZ ^ direction; 00477 glPushMatrix(); 00478 glTranslatef( 00479 static_cast<float>( CCC[p][0] ), 00480 static_cast<float>( CCC[p][1] + offset ), 00481 static_cast<float>( CCC[p][2] ) 00482 ); 00483 glRotatef( 00484 angle, 00485 static_cast<float>( rotDir[0] ), 00486 static_cast<float>( rotDir[1] ), 00487 static_cast<float>( rotDir[2] ) 00488 ); 00489 //glCallList( m_uiDisplayList ); 00490 glScalef( 0.15, 0.15, currentLinkLength ); 00491 //glScalef( 5, 5, 5 ); 00492 glCallList( m_uiDisplayList+1 ); 00493 glPopMatrix(); 00494 } 00495 00496 glDisable( GL_LIGHTING ); 00497 for ( int p = 0; p < 128; ++p ) { 00498 int rem = p % 4; 00499 T scale; 00500 switch ( rem ) { 00501 case 0: 00502 glColor3f( 1, 0, 0 ); 00503 scale = 3; 00504 break; 00505 case 1: 00506 glColor3f( 0, 1, 0 ); 00507 scale = 2; 00508 break; 00509 case 2: 00510 glColor3f( 0, 0, 1 ); 00511 scale = 2; 00512 break; 00513 case 3: 00514 glColor3f( 1, 1, 0 ); 00515 scale = 2.5; 00516 break; 00517 } 00518 glPushMatrix(); 00519 glTranslatef( 00520 static_cast<float>( CCC[p][0] ), 00521 static_cast<float>( CCC[p][1] + offset ), 00522 static_cast<float>( CCC[p][2] ) 00523 ); 00524 glScalef( scale, scale, scale ); 00525 glCallList( m_uiDisplayList ); 00526 glPopMatrix(); 00527 } 00528 glEnable( GL_LIGHTING ); 00529 00530 std::set<int>::iterator p0 = m_setiD3BezierCurShape.begin(); 00531 for ( int i = 0; i < static_cast<int>( m_setiD3BezierCurShape.size() ); ++i ) { 00532 //------------------------------------------------------ 00533 // Draw Bezier Ctrl Pts 00534 p = *p0; 00535 SetMaterial( Enum::RED ); 00536 ApplyMaterial( Enum::FRONT ); 00537 glPushMatrix(); 00538 glTranslatef( 00539 static_cast<float>( m_prVertex[p][0] ), 00540 static_cast<float>( m_prVertex[p][1] + offset ), 00541 static_cast<float>( m_prVertex[p][2] ) 00542 ); 00543 glScalef( 2, 2, 2 ); 00544 glCallList( m_uiDisplayList ); 00545 glPopMatrix(); 00546 ++p0; 00547 } 00548 } 00549 //*/ 00550 //----------------------------------------------------------------------------- 00551 //============================================================================= 00552 END_NAMESPACE_TAPs__OpenGL 00553 //----------------------------------------------------------------------------- 00554 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00555 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8