TAPs 0.7.7.3
TAPsOpenGLModelStrandMath.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines