Leap Motion C API  4.1.0
The API to the LeapC library.
3D Drawing Example

The 3D Drawing Example illustrates how to access the tracking data in a more "complete" application – in this a simple GLUT-based window. Because you cannot send drawing commands from a secondary thread, this example uses callbacks to set state variables that the GLUT thread then checks during its idle loop. If a new tracking frame is available, the idle() function calls a GLUT function to signal that a redraw is needed. The example then polls the ExampleConnection object to get the latest frame of data.

The hands are drawn using a GLUT primitives at the position of the elbow, the wrist, the palm point and the end of each bone in the fingers.

1 #undef __cplusplus
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 
6 #ifdef _WIN32
7 #include <Windows.h>
8 #else
9 #include <unistd.h>
10 #endif
11 
12 #include <time.h>
13 #include "LeapC.h"
14 #include "ExampleConnection.h"
15 #include "GLutils.h"
16 
17 int32_t lastDrawnFrameId = 0;
18 volatile int32_t newestFrameId = 0;
19 int window; // GLUT window handle
20 
21 /* Notifies us that a new frame is available. */
22 void OnFrame(const LEAP_TRACKING_EVENT *frame){
23  newestFrameId = (int32_t)frame->tracking_frame_id;
24 }
25 
26 void display(void)
27 {
28  glMatrixMode(GL_MODELVIEW);
29  glPushMatrix();
30  glTranslatef(0, -300, -500); //"Camera" viewpoint
31  glClear(GL_COLOR_BUFFER_BIT);
32  LEAP_TRACKING_EVENT *frame = GetFrame();
33  for(uint32_t h = 0; h < frame->nHands; h++){
34  // Draw the hand
35  LEAP_HAND *hand = &frame->pHands[h];
36  //elbow
37  glPushMatrix();
38  glTranslatef(hand->arm.prev_joint.x, hand->arm.prev_joint.y, hand->arm.prev_joint.z);
39  glutWireOctahedron();
40  glPopMatrix();
41 
42  //wrist
43  glPushMatrix();
44  glTranslatef(hand->arm.next_joint.x, hand->arm.next_joint.y, hand->arm.next_joint.z);
45  glutWireOctahedron();
46  glPopMatrix();
47 
48  //palm position
49  glPushMatrix();
50  glTranslatef(hand->palm.position.x, hand->palm.position.y, hand->palm.position.z);
51  glutWireOctahedron();
52  glPopMatrix();
53 
54  //Distal ends of bones for each digit
55  for(int f = 0; f < 5; f++){
56  LEAP_DIGIT finger = hand->digits[f];
57  for(int b = 0; b < 4; b++){
58  LEAP_BONE bone = finger.bones[b];
59  glPushMatrix();
60  glTranslatef(bone.next_joint.x, bone.next_joint.y, bone.next_joint.z);
61  glutWireOctahedron();
62  glPopMatrix();
63  }
64  }
65  // End of draw hand
66  }
67  glFlush();
68  glPopMatrix();
69 }
70 
71 void reshape(int w, int h)
72 {
73  glViewport(0, 0, (GLsizei) w, (GLsizei) h);
74  glMatrixMode(GL_PROJECTION);
75  glLoadIdentity();
76  gluPerspective(60, 640/240, 1.0, 1000);
77 }
78 
79 void keyboard(unsigned char key, int x, int y)
80 {
81  switch((char)key) {
82  case 'q':
83  case 27: // ESC
84  glutDestroyWindow(window);
85  CloseConnection();
86  exit(0);
87  default:
88  break;
89  }
90 }
91 
92 void idle(void){
93  if(lastDrawnFrameId < newestFrameId){
94  lastDrawnFrameId = newestFrameId;
95  glutPostRedisplay();
96  }
97 }
98 
99 int main(int argc, char *argv[])
100 {
101  ConnectionCallbacks.on_frame = OnFrame;
102  OpenConnection();
103 
104  while(!IsConnected){
105  millisleep(250);
106  }
107 
108  glutInit(&argc, argv);
109  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
110  glutInitWindowSize(640, 240);
111  window = glutCreateWindow("LeapC Example");
112 
113  // GLUT callbacks
114  glutIdleFunc(idle);
115  glutReshapeFunc(reshape);
116  glutKeyboardFunc(keyboard);
117  glutDisplayFunc(display);
118 
119  // init GL
120  glClearColor(1.0, 1.0, 1.0, 0.0);
121  glColor3f(0.0, 0.0, 0.0);
122  glLineWidth(3.0);
123 
124  // Start GLUT loop
125  glutMainLoop();
126 
127  CloseConnection();
128  return 0;
129 }
130 //End-of-Sample

This example is only supported on platforms for which a working version of GLUT exists. It should not be overly difficult to port the example to a different OpenGL-based context, however.

Image Examples

The Leap Motion service creates the tracking data provided in a LEAP_TRACKING_EVENT struct by analyzing a set of stereo images taken by the Leap Motion device cameras. The image set used to create a frame of data can be obtained by calling LeapRequestImages(). LeapC writes the set of stereo images to a buffer that you supply; stacked with the left image on top of the right image. After you call LeapRequestImages(), LeapC dispatches a LEAP_IMAGE_COMLETE_EVENT message through the usual message pump when the image buffer has been completely written. The message struct also contains the image properties.