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