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