00001
00002
00003
00004
00005
00006
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00596 if (j == Bone::TYPE_METACARPAL) {
00597
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
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
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
00624 glColor4fv(vJointColor);
00625 drawSphere(kStyle_Solid, vPalm, kfPalmRadiusScale*fRadius);
00626 }
00627
00628
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 }