LeapUtilGL.cpp
Go to the documentation of this file.
00001 /******************************************************************************\
00002 * Copyright (C) Leap Motion, Inc. 2011-2013.                                   *
00003 * Leap Motion proprietary and  confidential.  Not for distribution.            *
00004 * Use subject to the terms of the Leap Motion SDK Agreement available at       *
00005 * https://developer.leapmotion.com/sdk_agreement, or another agreement between *
00006 * Leap Motion and you, your company or other organization.                     *
00007 \******************************************************************************/
00008 
00009 #include "LeapUtilGL.h"
00010 
00011 #if !defined(__GLU_H__)
00012   #if defined(WIN32)
00013     #include <windows.h>
00014     #include <GL/glu.h>
00015   #elif defined(__MACH__)
00016     #include <OpenGL/glu.h>
00017   #else
00018     #include <GL/glu.h>
00019   #endif
00020 #endif // !__GL_H__
00021 
00022 namespace LeapUtilGL {
00023 
00024 using namespace Leap;
00025 using namespace LeapUtil;
00026 
00027 // create/destroy single global quadric instance for drawing curved surfaces with GLU
00028 class Quadric
00029 {
00030 public:
00031   Quadric() {}
00032 
00033   ~Quadric()
00034   {
00035     if ( s_pQuadric )
00036     {
00037       gluDeleteQuadric( s_pQuadric );
00038       s_pQuadric = NULL;
00039     }
00040   }
00041 
00042   operator GLUquadric* ()
00043   {
00044     if ( !s_pQuadric )
00045     {
00046       s_pQuadric = gluNewQuadric();
00047     }
00048 
00049     return s_pQuadric;
00050   }
00051 
00052   static GLUquadric* s_pQuadric;
00053 };
00054 
00055 GLUquadric* Quadric::s_pQuadric = NULL;
00056 
00057 static Quadric s_quadric;
00058 
00059 void drawGrid( ePlane plane, unsigned int horizSubdivs, unsigned int vertSubdivs )
00060 {
00061     const float fHalfGridSize   = 0.5f;
00062     const float fHGridStep      = (fHalfGridSize + fHalfGridSize)/static_cast<float>(Max(horizSubdivs, 1u));
00063     const float fVGridStep      = (fHalfGridSize + fHalfGridSize)/static_cast<float>(Max(vertSubdivs, 1u));
00064     const float fHEndStep       = fHalfGridSize + fHGridStep;
00065     const float fVEndStep       = fHalfGridSize + fVGridStep;
00066 
00067     GLAttribScope lightingScope( GL_LIGHTING_BIT );
00068 
00069     glDisable(GL_LIGHTING);
00070 
00071     glBegin( GL_LINES );
00072 
00073     switch ( plane )
00074     {
00075       case kPlane_XY:
00076         for ( float x = -fHalfGridSize; x < fHEndStep; x += fHGridStep )
00077         {
00078           glVertex3f( x, -fHalfGridSize, 0 );
00079           glVertex3f( x, fHalfGridSize, 0 );
00080         }
00081 
00082         for ( float y = -fHalfGridSize; y < fVEndStep; y += fVGridStep )
00083         {
00084           glVertex3f( -fHalfGridSize, y, 0 );
00085           glVertex3f( fHalfGridSize, y, 0 );
00086         }
00087         break;
00088 
00089       case kPlane_YZ:
00090         for ( float y = -fHalfGridSize; y < fHEndStep; y += fHGridStep )
00091         {
00092           glVertex3f( 0, y, -fHalfGridSize );
00093           glVertex3f( 0, y, fHalfGridSize );
00094         }
00095 
00096         for ( float z = -fHalfGridSize; z < fVEndStep; z += fVGridStep )
00097         {
00098           glVertex3f( 0, -fHalfGridSize, z );
00099           glVertex3f( 0, fHalfGridSize, z );
00100         }
00101         break;
00102 
00103       case kPlane_ZX:
00104         for ( float z = -fHalfGridSize; z < fHEndStep; z += fHGridStep )
00105         {
00106           glVertex3f( -fHalfGridSize, 0, z );
00107           glVertex3f( fHalfGridSize,  0, z );
00108         }
00109 
00110         for ( float x = -fHalfGridSize; x < fVEndStep; x += fVGridStep )
00111         {
00112           glVertex3f( x, 0, -fHalfGridSize );
00113           glVertex3f( x,  0, fHalfGridSize );
00114         }
00115         break;
00116     }
00117 
00118     glEnd();
00119 }
00120 
00121 void drawSphere( eStyle style )
00122 {
00123   switch ( style )
00124   {
00125    case kStyle_Outline:
00126     gluQuadricDrawStyle(s_quadric, GLU_SILHOUETTE);
00127     glPushAttrib( GL_LIGHTING_BIT );
00128     glDisable(GL_LIGHTING);
00129     break;
00130 
00131    case kStyle_Solid:
00132     gluQuadricDrawStyle(s_quadric, GLU_FILL);
00133     break;
00134   }
00135 
00136   gluSphere( s_quadric, 1.0, 32, 32 );
00137 
00138   switch ( style )
00139   {
00140    case kStyle_Outline:
00141     glPopAttrib();
00142     break;
00143 
00144    case kStyle_Solid:
00145     break;
00146   }
00147 }
00148 
00149 void drawQuad( eStyle style, ePlane plane )
00150 {
00151   switch ( style )
00152   {
00153    case kStyle_Outline:
00154     glPushAttrib( GL_LIGHTING_BIT );
00155     glDisable(GL_LIGHTING);
00156     break;
00157 
00158    case kStyle_Solid:
00159     break;
00160   }
00161 
00162   switch ( plane )
00163   {
00164   case kPlane_XY:
00165     break;
00166   case kPlane_YZ:
00167     glPushMatrix();
00168     glRotatef( 90.0f, 0, 1, 0 );
00169     break;
00170   case kPlane_ZX:
00171     glPushMatrix();
00172     glRotatef( -90.0f, 1, 0, 0 );
00173     break;
00174   }
00175 
00176   const float kfHalfSize = 0.5f;
00177 
00178   glBegin( style == kStyle_Outline ? GL_LINE_LOOP : GL_TRIANGLES );
00179   glNormal3f( 0, 0, 1 );
00180   glTexCoord2f( 0, 0 );
00181   glVertex3f( -kfHalfSize,  -kfHalfSize, 0 );
00182   glTexCoord2f( 1, 0 );
00183   glVertex3f(  kfHalfSize,  -kfHalfSize, 0 );
00184   glTexCoord2f( 1, 1 );
00185   glVertex3f(  kfHalfSize,   kfHalfSize, 0 );
00186   glEnd();
00187 
00188   glBegin( style == kStyle_Outline ? GL_LINE_LOOP : GL_TRIANGLES );
00189   glTexCoord2f( 1, 1 );
00190   glVertex3f(  kfHalfSize,   kfHalfSize, 0 );
00191   glTexCoord2f( 0, 1 );
00192   glVertex3f( -kfHalfSize,   kfHalfSize, 0 );
00193   glTexCoord2f( 0, 0 );
00194   glVertex3f( -kfHalfSize,  -kfHalfSize, 0 );
00195   glEnd();
00196 
00197   glBegin( style == kStyle_Outline ? GL_LINE_LOOP : GL_TRIANGLES );
00198   glNormal3f( 0, 0, -1 );
00199   glTexCoord2f( 0, 0 );
00200   glVertex3f(  kfHalfSize,  -kfHalfSize, 0 );
00201   glTexCoord2f( 1, 0 );
00202   glVertex3f( -kfHalfSize,  -kfHalfSize, 0 );
00203   glTexCoord2f( 1, 1 );
00204   glVertex3f( -kfHalfSize,   kfHalfSize, 0 );
00205   glEnd();
00206 
00207   glBegin( style == kStyle_Outline ? GL_LINE_LOOP : GL_TRIANGLES );
00208   glTexCoord2f( 1, 1 );
00209   glVertex3f( -kfHalfSize,   kfHalfSize, 0 );
00210   glTexCoord2f( 0, 1 );
00211   glVertex3f(  kfHalfSize,   kfHalfSize, 0 );
00212   glTexCoord2f( 0, 0 );
00213   glVertex3f(  kfHalfSize,  -kfHalfSize, 0 );
00214   glEnd();
00215 
00216   switch ( plane )
00217   {
00218   case kPlane_XY:
00219     break;
00220   case kPlane_YZ:
00221   case kPlane_ZX:
00222     glPopMatrix();
00223     break;
00224   }
00225 
00226   switch ( style )
00227   {
00228   case kStyle_Outline:
00229     glPopAttrib();
00230     break;
00231   case kStyle_Solid:
00232     break;
00233   }
00234 }
00235 
00236 
00237 void drawBox( eStyle style )
00238 {
00239   static const float s_afCorners[8][3] = {
00240                                             // near face - ccw facing origin from face.
00241                                             {-0.5f, -0.5f,  0.5f},
00242                                             { 0.5f, -0.5f,  0.5f},
00243                                             { 0.5f,  0.5f,  0.5f},
00244                                             {-0.5f,  0.5f,  0.5f},
00245 
00246                                             // far face - ccw facing origin from face
00247                                             { 0.5f, -0.5f,  -0.5f},
00248                                             {-0.5f, -0.5f,  -0.5f},
00249                                             {-0.5f,  0.5f,  -0.5f},
00250                                             { 0.5f,  0.5f,  -0.5f},
00251 
00252  };
00253 
00254   switch ( style )
00255   {
00256    case kStyle_Outline:
00257     glPushAttrib( GL_LIGHTING_BIT );
00258     glDisable(GL_LIGHTING);
00259     break;
00260 
00261    case kStyle_Solid:
00262     break;
00263   }
00264 
00265   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00266 
00267   // near
00268   glNormal3f( 0, 0, 1 );
00269   glVertex3fv( s_afCorners[0] );
00270   glVertex3fv( s_afCorners[1] );
00271   glVertex3fv( s_afCorners[2] );
00272 
00273   glEnd();
00274   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00275 
00276   glVertex3fv( s_afCorners[2] );
00277   glVertex3fv( s_afCorners[3] );
00278   glVertex3fv( s_afCorners[0] );
00279 
00280   glEnd();
00281   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00282 
00283   // far
00284   glNormal3f( 0, 0, -1 );
00285   glVertex3fv( s_afCorners[4] );
00286   glVertex3fv( s_afCorners[5] );
00287   glVertex3fv( s_afCorners[6] );
00288 
00289   glEnd();
00290   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00291 
00292   glVertex3fv( s_afCorners[6] );
00293   glVertex3fv( s_afCorners[7] );
00294   glVertex3fv( s_afCorners[4] );
00295 
00296   glEnd();
00297 
00298   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00299 
00300   // right
00301   glNormal3f( 1, 0, 0 );
00302   glVertex3fv( s_afCorners[1] );
00303   glVertex3fv( s_afCorners[4] );
00304   glVertex3fv( s_afCorners[7] );
00305 
00306   glEnd();
00307   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00308 
00309   glVertex3fv( s_afCorners[7] );
00310   glVertex3fv( s_afCorners[2] );
00311   glVertex3fv( s_afCorners[1] );
00312 
00313   glEnd();
00314   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00315 
00316   // left
00317   glNormal3f( -1, 0, 0 );
00318   glVertex3fv( s_afCorners[5] );
00319   glVertex3fv( s_afCorners[0] );
00320   glVertex3fv( s_afCorners[3] );
00321 
00322   glEnd();
00323   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00324 
00325   glVertex3fv( s_afCorners[3] );
00326   glVertex3fv( s_afCorners[6] );
00327   glVertex3fv( s_afCorners[5] );
00328 
00329   glEnd();
00330 
00331   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00332 
00333   // bottom
00334   glNormal3f( 0, -1, 0 );
00335   glVertex3fv( s_afCorners[0] );
00336   glVertex3fv( s_afCorners[5] );
00337   glVertex3fv( s_afCorners[4] );
00338 
00339   glEnd();
00340   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00341 
00342   glVertex3fv( s_afCorners[4] );
00343   glVertex3fv( s_afCorners[1] );
00344   glVertex3fv( s_afCorners[0] );
00345 
00346   glEnd();
00347   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00348 
00349   // top
00350   glNormal3f( 0, 1, 0 );
00351   glVertex3fv( s_afCorners[3] );
00352   glVertex3fv( s_afCorners[2] );
00353   glVertex3fv( s_afCorners[7] );
00354 
00355   glEnd();
00356   glBegin( style == kStyle_Solid ? GL_TRIANGLES : GL_LINE_LOOP );
00357 
00358   glVertex3fv( s_afCorners[7] );
00359   glVertex3fv( s_afCorners[6] );
00360   glVertex3fv( s_afCorners[3] );
00361 
00362   glEnd();
00363 
00364   switch ( style )
00365   {
00366    case kStyle_Outline:
00367     glPopAttrib();
00368     break;
00369 
00370    case kStyle_Solid:
00371     break;
00372   }
00373 }
00374 
00375 void drawCylinder( eStyle style, eAxis axis )
00376 {
00377   GLMatrixScope matrixScope;
00378 
00379   switch ( style )
00380   {
00381    case kStyle_Outline:
00382     gluQuadricDrawStyle(s_quadric, GLU_SILHOUETTE);
00383     glPushAttrib( GL_LIGHTING_BIT );
00384     glDisable(GL_LIGHTING);
00385     break;
00386 
00387    case kStyle_Solid:
00388     gluQuadricDrawStyle(s_quadric, GLU_FILL);
00389     break;
00390   }
00391 
00392   switch ( axis )
00393   {
00394   case kAxis_X:
00395     glRotatef( 90.0f, 0, 1, 0 );
00396     break;
00397   case kAxis_Y:
00398     glRotatef( 90.0f, 1, 0, 0 );
00399     break;
00400   case kAxis_Z:
00401     break;
00402   }
00403 
00404   // draw end caps
00405   if ( style != kStyle_Outline )
00406   {
00407     GLMatrixScope matrixScope;
00408 
00409     glTranslatef( 0, 0, 0.5f );
00410     drawDisk( style, kPlane_XY );
00411 
00412     glTranslatef( 0, 0, -1.0f );
00413     drawDisk( style, kPlane_XY );
00414   }
00415 
00416   glTranslatef( 0, 0, -0.5f );
00417 
00418   gluCylinder( s_quadric, 0.5f, 0.5f, 1.0f, 32, 32 );
00419 
00420   switch ( style )
00421   {
00422    case kStyle_Outline:
00423     glPopAttrib();
00424     break;
00425 
00426    case kStyle_Solid:
00427     break;
00428   }
00429 }
00430 
00431 void drawDisk( eStyle style, ePlane plane )
00432 {
00433   GLMatrixScope matrixScope;
00434 
00435   switch ( style )
00436   {
00437    case kStyle_Outline:
00438     gluQuadricDrawStyle(s_quadric, GLU_SILHOUETTE);
00439     glPushAttrib( GL_LIGHTING_BIT );
00440     glDisable(GL_LIGHTING);
00441     break;
00442 
00443    case kStyle_Solid:
00444     gluQuadricDrawStyle(s_quadric, GLU_FILL);
00445     break;
00446   }
00447 
00448   switch ( plane )
00449   {
00450   case kPlane_XY:
00451     break;
00452   case kPlane_YZ:
00453     glRotatef( 90.0f, 0, 1, 0 );
00454     break;
00455   case kPlane_ZX:
00456     glRotatef( -90.0f, 1, 0, 0 );
00457     break;
00458   }
00459 
00460   gluDisk(s_quadric, 0, 0.5f, 32, 1);
00461   glRotatef( 180.0f, 0, 1, 0 );
00462   gluDisk(s_quadric, 0, 0.5f, 32, 1);
00463 
00464   switch ( style )
00465   {
00466    case kStyle_Outline:
00467     glPopAttrib();
00468     break;
00469 
00470    case kStyle_Solid:
00471     break;
00472   }
00473 }
00474 
00475 void drawArrow( eAxis axis )
00476 {
00477   glBegin( GL_LINES );
00478 
00479   switch ( axis )
00480   {
00481   case kAxis_X:
00482     glVertex3f( 0, 0, 0 );
00483     glVertex3f( 1, 0, 0 );
00484 
00485     glVertex3f( 1, 0, 0 );
00486     glVertex3f( 0.8f, 0.2f, 0 );
00487 
00488     glVertex3f( 1, 0, 0 );
00489     glVertex3f( 0.8f, -0.2f, 0 );
00490     break;
00491 
00492   case kAxis_Y:
00493     glVertex3f( 0, 0, 0 );
00494     glVertex3f( 0, 1, 0 );
00495 
00496     glVertex3f( 0, 1, 0 );
00497     glVertex3f( 0, 0.8f, 0.2f );
00498 
00499     glVertex3f( 0, 1, 0 );
00500     glVertex3f( 0, 0.8f, -0.2f );
00501     break;
00502 
00503   case kAxis_Z:
00504     glVertex3f( 0, 0, 0 );
00505     glVertex3f( 0, 0, 1 );
00506 
00507     glVertex3f( 0, 0, 1 );
00508     glVertex3f( 0.2f, 0, 0.8f );
00509 
00510     glVertex3f( 0, 0, 1 );
00511     glVertex3f( -0.2f, 0, 0.8f );
00512     break;
00513   }
00514 
00515   glEnd();
00516 }
00517 
00518   // draw unit length X, Y, Z axes in red, green and blue.
00519   void drawAxes()
00520   {
00521     GLAttribScope attribScope(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
00522 
00523     glDisable(GL_LIGHTING);
00524     glDisable(GL_DEPTH_TEST);
00525 
00526     glColor3f(1, 0, 0);
00527     drawArrow(kAxis_X);
00528 
00529     glColor3f(0, 1, 0);
00530     drawArrow(kAxis_Y);
00531 
00532     glColor3f(0, 0, 1);
00533     drawArrow(kAxis_Z);
00534   }
00535 
00536   // additional sphere/cylinder drawing utilities
00537   void drawSphere(eStyle style, const Vector& vCenter, float fRadius)
00538   {
00539     GLMatrixScope matrixScope;
00540 
00541     glTranslatef(vCenter.x, vCenter.y, vCenter.z);
00542     glScalef(fRadius, fRadius, fRadius);
00543 
00544     drawSphere(style);
00545   }
00546 
00547   void drawCylinder(eStyle style, const Vector& vBottom, const Vector& vTop, float fRadius)
00548   {
00549     GLMatrixScope matrixScope;
00550 
00551     Vector vCenter = (vBottom + vTop) * 0.5f;
00552 
00553     Vector vDir = (vTop - vBottom).normalized();
00554     Vector vRotAxis = Vector::zAxis().cross(vDir);
00555     float fRotAngle = Vector::zAxis().angleTo(vDir);
00556     float fHeight = vTop.distanceTo(vBottom);
00557 
00558     glTranslatef(vCenter.x, vCenter.y, vCenter.z);
00559     glRotatef(fRotAngle * RAD_TO_DEG, vRotAxis.x, vRotAxis.y, vRotAxis.z);
00560     glScalef(fRadius, fRadius, fHeight);
00561 
00562     drawCylinder(style, kAxis_Z);
00563   }
00564 
00565   // convenience function for drawing skeleton API hand
00566   void drawSkeletonHand(const Leap::Hand& hand, const GLVector4fv& vBoneColor, const GLVector4fv& vJointColor) {
00567     static const float kfJointRadiusScale = 0.75f;
00568     static const float kfBoneRadiusScale = 0.5f;
00569     static const float kfPalmRadiusScale = 1.15f;
00570 
00571     LeapUtilGL::GLAttribScope colorScope( GL_CURRENT_BIT );
00572 
00573     const Vector vPalm = hand.palmPosition();
00574     const Vector vPalmDir = hand.direction();
00575     const Vector vPalmNormal = hand.palmNormal();
00576     const Vector vPalmSide = vPalmDir.cross(vPalmNormal).normalized();
00577 
00578     const float fThumbDist = hand.fingers()[Finger::TYPE_THUMB].bone(Bone::TYPE_METACARPAL).prevJoint().distanceTo(hand.palmPosition());
00579     const Vector vWrist = vPalm - fThumbDist*(vPalmDir*0.90f + (hand.isLeft() ? -1.0f : 1.0f)*vPalmSide*0.38f);
00580 
00581     FingerList fingers = hand.fingers();
00582 
00583     float fRadius = 0.0f;
00584     Vector vCurBoxBase;
00585     Vector vLastBoxBase = vWrist;
00586 
00587     for (int i = 0, ei = fingers.count(); i < ei; i++) {
00588       const Finger& finger = fingers[i];
00589       fRadius = finger.width() * 0.5f;
00590 
00591       // draw individual fingers
00592       for (int j = Bone::TYPE_METACARPAL; j <= Bone::TYPE_DISTAL; j++) {
00593         const Bone& bone = finger.bone(static_cast<Bone::Type>(j));
00594 
00595         // don't draw metacarpal, a box around the metacarpals is draw instead.
00596         if (j == Bone::TYPE_METACARPAL) {
00597           // cache the top of the metacarpal for the next step in metacarpal box
00598           vCurBoxBase = bone.nextJoint();
00599         } else {
00600           glColor4fv(vBoneColor);
00601           drawCylinder(kStyle_Solid, bone.prevJoint(), bone.nextJoint(), kfBoneRadiusScale*fRadius);
00602           glColor4fv(vJointColor);
00603           drawSphere(kStyle_Solid, bone.nextJoint(), kfJointRadiusScale*fRadius);
00604         }
00605       }
00606 
00607       // draw segment of metacarpal box
00608       glColor4fv(vBoneColor);
00609       drawCylinder(kStyle_Solid, vCurBoxBase, vLastBoxBase, kfBoneRadiusScale*fRadius);
00610       glColor4fv(vJointColor);
00611       drawSphere(kStyle_Solid, vCurBoxBase, kfJointRadiusScale*fRadius);
00612       vLastBoxBase = vCurBoxBase;
00613     }
00614 
00615     // close the metacarpal box
00616     fRadius = fingers[Finger::TYPE_THUMB].width() * 0.5f;
00617     vCurBoxBase = vWrist;
00618     glColor4fv(vBoneColor);
00619     drawCylinder(kStyle_Solid, vCurBoxBase, vLastBoxBase, kfBoneRadiusScale*fRadius);
00620     glColor4fv(vJointColor);
00621     drawSphere(kStyle_Solid, vCurBoxBase, kfJointRadiusScale*fRadius);
00622 
00623     // draw palm position
00624     glColor4fv(vJointColor);
00625     drawSphere(kStyle_Solid, vPalm, kfPalmRadiusScale*fRadius);
00626   }
00627 
00628 //GLCamera methods
00629 
00630 void CameraGL::SetupGLProjection() const
00631 {
00632   ResetGLProjection();
00633   gluPerspective( GetVerticalFOVDegrees(), GetAspectRatio(), GetNearClip(), GetFarClip() );
00634 }
00635 
00636 void CameraGL::SetupGLView() const
00637 {
00638   ResetGLView();
00639   glMultMatrixf( GetView().toArray4x4() );
00640 }
00641 
00642 } // namespace LeapUtilGL


leap_motion
Author(s): Florian Lier , Mirza Shah , Isaac IY Saito
autogenerated on Sat Jun 8 2019 18:47:25