### Basic LeapC API Usage Example Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example This example demonstrates the fundamental steps required to initialize the LeapC API, establish a connection, and retrieve basic tracking data. ```APIDOC ## Basic LeapC API Usage Example ### Description Demonstrates the basic usage of the LeapC API to get tracking data. This includes initialization, connection, and data retrieval. ### Method N/A (Example) ### Endpoint N/A (Example) ### Parameters N/A (Example) ### Request Example N/A (Example) ### Response #### Success Response (N/A) - **Tracking Data** (struct) - Contains information about hand and finger tracking. #### Response Example N/A (Example) ``` -------------------------------- ### Initialize and Run LeapC 3D Drawing Example (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-example Sets up LeapC connection, initializes GLUT for a graphical window, and enters the main event loop. Handles connection callbacks and window management. Requires a working GLUT implementation. ```C #undef __cplusplus #include #include #ifdef _WIN32 #include #else #include #endif #include #include "LeapC.h" #include "ExampleConnection.h" #include "GLutils.h" int32_t lastDrawnFrameId = 0; volatile int32_t newestFrameId = 0; int window; // GLUT window handle /* Notifies us that a new frame is available. */ void OnFrame(const LEAP_TRACKING_EVENT *frame){ newestFrameId = (int32_t)frame->tracking_frame_id; } void display(void) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(0, -300, -500); //"Camera" viewpoint glClear(GL_COLOR_BUFFER_BIT); LEAP_TRACKING_EVENT *frame = GetFrame(); for(uint32_t h = 0; h < frame->nHands; h++){ // Draw the hand LEAP_HAND *hand = &frame->pHands[h]; //elbow glPushMatrix(); glTranslatef(hand->arm.prev_joint.x, hand->arm.prev_joint.y, hand->arm.prev_joint.z); glutWireOctahedron(); glPopMatrix(); //wrist glPushMatrix(); glTranslatef(hand->arm.next_joint.x, hand->arm.next_joint.y, hand->arm.next_joint.z); glutWireOctahedron(); glPopMatrix(); //palm position glPushMatrix(); glTranslatef(hand->palm.position.x, hand->palm.position.y, hand->palm.position.z); glutWireOctahedron(); glPopMatrix(); //Distal ends of bones for each digit for(int f = 0; f < 5; f++){ LEAP_DIGIT finger = hand->digits[f]; for(int b = 0; b < 4; b++){ LEAP_BONE bone = finger.bones[b]; glPushMatrix(); glTranslatef(bone.next_joint.x, bone.next_joint.y, bone.next_joint.z); glutWireOctahedron(); glPopMatrix(); } } // End of draw hand } glFlush(); glPopMatrix(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 640/240, 1.0, 1000); } void keyboard(unsigned char key, int x, int y) { switch((char)key) { case 'q': case 27: // ESC glutDestroyWindow(window); CloseConnection(); exit(0); default: break; } } void idle(void){ if(lastDrawnFrameId < newestFrameId){ lastDrawnFrameId = newestFrameId; glutPostRedisplay(); } } int main(int argc, char *argv[]) { ConnectionCallbacks.on_frame = OnFrame; OpenConnection(); while(!IsConnected){ millisleep(250); } glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize(640, 240); window = glutCreateWindow("LeapC Example"); // GLUT callbacks glutIdleFunc(idle); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); // init GL glClearColor(1.0, 1.0, 1.0, 0.0); glColor3f(0.0, 0.0, 0.0); glLineWidth(3.0); // Start GLUT loop glutMainLoop(); CloseConnection(); return 0; } //End-of-Sample ``` -------------------------------- ### Shader and Texture Setup Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-shader-example This snippet focuses on initializing the OpenGL shader program and textures. It includes creating the shader program using vertex and fragment shaders, getting uniform locations for texture samplers, and creating texture references for both raw and distortion data. ```c++ //Create the shader program program = createProgram(GLSL_VERT, GLSL_FRAG); glUseProgram(program); GLuint rawSampler = glGetUniformLocation(program, "rawTexture"); GLuint distortionSampler = glGetUniformLocation(program, "distortionTexture"); glUniform1i(rawSampler, 0); glUniform1i(distortionSampler, 1); //Create textures rawTextureLeft = createTextureReference(); distortionTextureLeft = createTextureReference(); rawTextureRight = createTextureReference(); distortionTextureRight = createTextureReference(); ``` -------------------------------- ### Leap Motion Configuration JSON Example Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration Example of a JSON configuration file for the Leap Motion service. This file allows setting various options, including WebSocket-related parameters. ```json { "configuration": { "websockets_enabled": true, "websockets_allow_remote": false, "ws_port": 51000, "wss_port": 51001 } } ``` -------------------------------- ### Specifying Configuration File via Command Line Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration These examples demonstrate how to specify a custom configuration file for the Leap Motion service (LeapSvc or leapd) using the `--config` command-line parameter. This allows overriding default settings. ```bash LeapSvc --config=/path/to/config.json leapd --config=/path/to/config.json ``` -------------------------------- ### Example Connection: Cache Leap Motion Data in C Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/polling-example The ExampleConnection.c file provides utility functions for the polling example, enabling the application to cache the latest Leap Motion tracking data and device properties. It uses mutexes to ensure thread-safe access to shared data structures, allowing the application to retrieve the most recent frame or device information at any time. ```c /* Used in Polling Example: */ /** * Caches the newest frame by copying the tracking event struct returned by * LeapC. */ void setFrame(const LEAP_TRACKING_EVENT *frame){ LockMutex(&dataLock); if(!lastFrame) lastFrame = malloc(sizeof(*frame)); *lastFrame = *frame; UnlockMutex(&dataLock); } /** Returns a pointer to the cached tracking frame. */ LEAP_TRACKING_EVENT* GetFrame(){ LEAP_TRACKING_EVENT *currentFrame; LockMutex(&dataLock); currentFrame = lastFrame; UnlockMutex(&dataLock); return currentFrame; } /** * Caches the last device found by copying the device info struct returned by * LeapC. */ static void setDevice(const LEAP_DEVICE_INFO *deviceProps){ LockMutex(&dataLock); if(lastDevice){ free(lastDevice->serial); } else { lastDevice = malloc(sizeof(*deviceProps)); } *lastDevice = *deviceProps; lastDevice->serial = malloc(deviceProps->serial_length); memcpy(lastDevice->serial, deviceProps->serial, deviceProps->serial_length); UnlockMutex(&dataLock); } /** Returns a pointer to the cached device info. */ LEAP_DEVICE_INFO* GetDeviceProperties(){ LEAP_DEVICE_INFO *currentDevice; LockMutex(&dataLock); currentDevice = lastDevice; UnlockMutex(&dataLock); return currentDevice; } //End of polling example-specific code ``` -------------------------------- ### Configure Leap Motion Service Settings (JSON) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration Example of how to configure Leap Motion service settings, including CPU affinity and process niceness, within a JSON configuration file. ```json { "configuration": { "cpu_affinity_mask": 1, "process_niceness": 6 } } ``` -------------------------------- ### Initialize GLUT Window and Callbacks for LeapC Image Display (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-images-example This C code snippet initializes a GLUT window for displaying LeapC images. It sets up essential GLUT callbacks for idle, reshape, keyboard, and display functions, along with basic OpenGL color settings. This example is supported on platforms with a working GLUT implementation. ```c #include // Assume other necessary LeapC and GLUT functions are defined elsewhere void idle() { // Handle idle processing } void reshape(int w, int h) { // Handle window reshape events } void keyboard(unsigned char key, int x, int y) { // Handle keyboard input } void display() { // Handle display updates } void CloseConnection() { // Close LeapC connection } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); int window = glutCreateWindow("LeapC Image Example"); // GLUT callbacks glutIdleFunc(idle); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); // init GL glClearColor(0.0, 0.0, 0.0, 0.0); glColor3f(1.0, 1.0, 1.0); // Start GLUT loop glutMainLoop(); CloseConnection(); return 0; } ``` -------------------------------- ### Initialize and Display Leap Motion Camera Images in C Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-images-example This C code snippet demonstrates the initialization of the Leap Motion connection, setting image policy flags, and setting up callbacks for image events. It includes the main loop to keep the connection open and initializes GLUT for display. The `OnImage` callback handles receiving and buffering image data. ```c #undef __cplusplus #include #include #ifdef _WIN32 #include #else #include #endif #include #include #include "LeapC.h" #include "ExampleConnection.h" #include "GLutils.h" void* image_buffer = NULL; uint64_t image_size = 0; bool imageReady = false; bool textureChanged = false; uint32_t image_width = 0; uint32_t image_height = 0; GLuint texture = 0; int window; // GLUT window handle /** Callback for when an image is available. */ static void OnImage(const LEAP_IMAGE_EVENT *imageEvent){ const LEAP_IMAGE_PROPERTIES* properties = &imageEvent->image[0].properties; if (properties->bpp != 1) return; if (properties->width*properties->height != image_size) { void* prev_image_buffer = image_buffer; image_width = properties->width; image_height = properties->height; image_size = image_width*image_height; image_buffer = malloc(2 * image_size); if (prev_image_buffer) free(prev_image_buffer); textureChanged = true; } memcpy(image_buffer, (char*)imageEvent->image[0].data + imageEvent->image[0].offset, image_size); memcpy((char*)image_buffer + image_size, (char*)imageEvent->image[1].data + imageEvent->image[1].offset, image_size); imageReady = true; } // Draw a textured quad displaying the image data static void DrawImageQuad(float p1X, float p1Y, float p2X, float p2Y, int width, int height, void* imagedata){ glEnable(GL_TEXTURE_2D); if(textureChanged){ textureChanged = false; glDeleteTextures(1, &texture); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagedata); checkGLError("Initializing texture."); } else { //update existing texture glBindTexture ( GL_TEXTURE_2D, texture); g lTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagedata); checkGLError("Updating texture."); } //Draw a texture-mapped quad glBegin(GL_QUADS); glTexCoord2f(1, 1); glVertex2f((GLfloat)p1X, (GLfloat)p1Y); glTexCoord2f(0, 1); glVertex2f((GLfloat)p2X, (GLfloat)p1Y); glTexCoord2f(0, 0); glVertex2f((GLfloat)p2X, (GLfloat)p2Y); glTexCoord2f(1, 0); glVertex2f((GLfloat)p1X, (GLfloat)p2Y); glEnd(); checkGLError("Drawing quad."); glDisable(GL_TEXTURE_2D); } // Done drawing quad static void display(void) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(-32, -24, -50); //"Camera" viewpoint glClear(GL_COLOR_BUFFER_BIT); if(imageReady){ DrawImageQuad(0, 0, 64, 48, image_width, image_height * 2, image_buffer); imageReady = false; } glFlush(); glPopMatrix(); glutSwapBuffers(); } static void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 640.0/240.0, 1.0, 1000); } static void keyboard(unsigned char key, int x, int y) { switch((char)key) { case 'q': case 27: // ESC glutDestroyWindow(window); CloseConnection(); if(image_buffer) free(image_buffer); exit(0); default: break; } } static void idle(void){ if(imageReady) glutPostRedisplay(); } int main(int argc, char *argv[]) { ConnectionCallbacks.on_image = OnImage; LEAP_CONNECTION *connection = OpenConnection(); LeapSetPolicyFlags(*connection, eLeapPolicyFlag_Images, 0); while(!IsConnected){ millisleep(250); } glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(640, 480); // Additional GLUT setup and main loop would follow here return 0; } ``` -------------------------------- ### Leap Motion Connection and Initialization Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-shader-example This snippet shows the main function's setup for connecting to the Leap Motion device and initializing the GLUT window. It includes setting connection callbacks, opening the connection, setting policy flags, and waiting for the connection to be established before initializing GLUT. ```c++ ConnectionCallbacks.on_image = OnImage; LEAP_CONNECTION *connection = OpenConnection(); LeapSetPolicyFlags(*connection, eLeapPolicyFlag_Images, 0); while(!IsConnected){ millisleep(250); } ``` -------------------------------- ### Getting and Setting Configuration Values Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/usingleapc This section covers how to access and modify various configuration settings of the Leap Motion service that are useful to individual applications. ```APIDOC ## Getting and Setting Configuration Values ### Description Accesses and modifies various configuration settings of the Leap Motion service that are relevant to individual applications. ### Method This section describes a process involving C API calls, not a single HTTP request. ### Endpoint N/A (C API functions) ### Parameters N/A (C API functions) ### Request Example ```c // Placeholder for configuration value retrieval/setting example // Specific C API functions for configuration are not detailed in the provided text. // Refer to the official Leap Motion C API documentation for details. ``` ### Response #### Success Response - Configuration values are typically read or set via specific API calls and their return values indicate success or failure. #### Response Example ```json { "setting_name": "example_setting", "setting_value": "example_value" } ``` ``` -------------------------------- ### Open Leap Motion Service Connection and Start Message Pump Thread (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example Establishes a connection to the Leap Motion service and initiates a dedicated thread to continuously poll for messages. This prevents blocking the main application thread and ensures timely event processing. Requires LeapC library. ```c #include "ExampleConnection.h" #include #include #include #if defined(_MSC_VER) #include #include #define LockMutex EnterCriticalSection #define UnlockMutex LeaveCriticalSection #else #include #include #define LockMutex pthread_mutex_lock #define UnlockMutex pthread_mutex_unlock #endif //Forward declarations #if defined(_MSC_VER) static void serviceMessageLoop(void * unused); #else static void* serviceMessageLoop(void * unused); #endif static void setFrame(const LEAP_TRACKING_EVENT *frame); static void setDevice(const LEAP_DEVICE_INFO *deviceProps); //External state bool IsConnected = false; //Internal state static volatile bool _isRunning = false; static LEAP_CONNECTION connectionHandle = NULL; static LEAP_TRACKING_EVENT *lastFrame = NULL; static LEAP_DEVICE_INFO *lastDevice = NULL; //Callback function pointers struct Callbacks ConnectionCallbacks; //Threading variables #if defined(_MSC_VER) static HANDLE pollingThread; static CRITICAL_SECTION dataLock; #else static pthread_t pollingThread; static pthread_mutex_t dataLock; #endif /** * Creates the connection handle and opens a connection to the Leap Motion * service. On success, creates a thread to service the LeapC message pump. */ LEAP_CONNECTION* OpenConnection(){ if(_isRunning){ return &connectionHandle; } if(connectionHandle || LeapCreateConnection(NULL, &connectionHandle) == eLeapRS_Success){ eLeapRS result = LeapOpenConnection(connectionHandle); if(result == eLeapRS_Success){ _isRunning = true; #if defined(_MSC_VER) InitializeCriticalSection(&dataLock); pollingThread = (HANDLE)_beginthread(serviceMessageLoop, 0, NULL); #else pthread_create(&pollingThread, NULL, serviceMessageLoop, NULL); #endif } } return &connectionHandle; } ``` -------------------------------- ### Request Stereo Images and Handle Image Events in C Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/images-example Demonstrates how to request stereo images from the Leap Motion service and handle the LEAP_IMAGE_EVENT callback. It includes setting up connection callbacks, requesting images using LeapRequestImages(), and calculating the required buffer size dynamically based on image properties. This example focuses on C and the LeapC API. ```c #undef __cplusplus #include #include #include "LeapC.h" #include "ExampleConnection.h" /** Callback for when the connection opens. */ static void OnConnect(){ printf("Connected.\n"); } /** Callback for when a device is found. */ static void OnDevice(const LEAP_DEVICE_INFO *props){ printf("Found device %s.\n", props->serial); } /** Callback for when a frame of tracking data is available. */ static void OnFrame(const LEAP_TRACKING_EVENT *frame){ printf("Frame %lli with %i hands.\n", (long long int)frame->info.frame_id, frame->nHands); for(uint32_t h = 0; h < frame->nHands; h++){ LEAP_HAND* hand = &frame->pHands[h]; printf(" Hand id %i is a %s hand with position (%f, %f, %f).\n", hand->id, (hand->type == eLeapHandType_Left ? "left" : "right"), hand->palm.position.x, hand->palm.position.y, hand->palm.position.z); } } /** Callback for when an image is available. */ static void OnImage(const LEAP_IMAGE_EVENT *imageEvent){ printf("Received image set for frame %lli with size %lli.\n", (long long int)imageEvent->info.frame_id, (long long int)imageEvent->image[0].properties.width* (long long int)imageEvent->image[0].properties.height*2); } int main(int argc, char** argv) { //Set callback function pointers ConnectionCallbacks.on_connection = &OnConnect; ConnectionCallbacks.on_device_found = &OnDevice; ConnectionCallbacks.on_frame = &OnFrame; ConnectionCallbacks.on_image = &OnImage; LEAP_CONNECTION *connection = OpenConnection(); LeapSetPolicyFlags(*connection, eLeapPolicyFlag_Images, 0); printf("Press Enter to exit program.\n"); getchar(); return 0; } //End-of-Sample.c ``` -------------------------------- ### Get Current Leap Motion System Time (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions Samples the system's universal clock to obtain a timestamp in microseconds. This counter is global, monotonic, and utilizes the system's most accurate high-performance counter for time measurements. ```c int64_t LeapGetNow( void ); ``` -------------------------------- ### Get List of Connected Leap Motion Devices (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions Retrieves a list of Leap Motion devices connected to the system. To determine the number of devices, call this function with 'pArray' as NULL; the count will be stored in 'pnArray'. Subsequently, allocate an array of LEAP_DEVICE_REF structs of the determined size and call the function again to populate the array with device handles. ```c eLeapRS LeapGetDeviceList( LEAP_CONNECTION _hConnection, LEAP_DEVICE_REF * _pArray, uint32_t * _pnArray ); ``` -------------------------------- ### Requesting Stereo Images from Leap Motion Device (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-example Demonstrates how to request stereo images from the Leap Motion device using LeapRequestImages(). The images are written to a provided buffer and a LEAP_IMAGE_COMLETE_EVENT is dispatched upon completion, containing image properties. ```C // 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. LeapRequestImages(); ``` -------------------------------- ### Get Leap Motion Device Info with Dynamic Buffer Allocation (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example This C code snippet shows how to retrieve device information, specifically the serial number, from a Leap Motion controller. It handles potential buffer size issues by initially allocating a small buffer and then reallocating a larger one if the initial size is insufficient, ensuring the serial number can be fully retrieved. It also includes error handling and callback invocation upon successful retrieval. ```c //Create a struct to hold the device properties, we have to provide a buffer for the serial string LEAP_DEVICE_INFO deviceProperties = { sizeof(deviceProperties) }; // Start with a length of 1 (pretending we don't know a priori what the length is). // Currently device serial numbers are all the same length, but that could change in the future deviceProperties.serial_length = 1; deviceProperties.serial = malloc(deviceProperties.serial_length); //This will fail since the serial buffer is only 1 character long // But deviceProperties is updated to contain the required buffer length result = LeapGetDeviceInfo(deviceHandle, &deviceProperties); if(result == eLeapRS_InsufficientBuffer){ //try again with correct buffer size deviceProperties.serial = realloc(deviceProperties.serial, deviceProperties.serial_length); result = LeapGetDeviceInfo(deviceHandle, &deviceProperties); if(result != eLeapRS_Success){ printf("Failed to get device info %s.\n", ResultString(result)); free(deviceProperties.serial); return; } } setDevice(&deviceProperties); if(ConnectionCallbacks.on_device_found){ ConnectionCallbacks.on_device_found(&deviceProperties); } free(deviceProperties.serial); LeapCloseDevice(deviceHandle); ``` -------------------------------- ### Get Leap Motion Device Information (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions Retrieves properties of a Leap Motion device. To obtain the serial number, ensure the 'serial' member of LEAP_DEVICE_INFO points to a sufficiently large character array. If the required size is unknown, call the function with 'serial' set to NULL to get the length from the 'serial_length' field. ```c eLeapRS LeapGetDeviceInfo( LEAP_DEVICE_HANDLE _hDevice, LEAP_DEVICE_INFO * _info ); ``` -------------------------------- ### LEAP_POLICY_EVENT Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___structs The response from a request to get or set a policy, indicating the effective policies at the time of processing. ```APIDOC ## LEAP_POLICY_EVENT ### Description Event structure detailing the current policy settings effective for the Leap Motion service. ### Method N/A (Structure Definition) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (N/A) N/A #### Response Example N/A ### Fields - **reserved** (uint32_t) - Reserved for future use. - **current_policy** (uint32_t) - A bitfield containing the policies effective at the time the policy event was processed. ``` -------------------------------- ### Leap Motion C Client with Callbacks Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example This C code snippet demonstrates a sample client application for the Leap Motion controller. It defines callback functions for connection, device discovery, and frame data. The callbacks are invoked by the ExampleConnection when events occur, allowing the application to process tracking data, device information, and connection status. It highlights potential threading issues when integrating with UI frameworks and suggests solutions. ```c #undef __cplusplus #include #include #include "LeapC.h" #include "ExampleConnection.h" static LEAP_CONNECTION* connectionHandle; /** Callback for when the connection opens. */ static void OnConnect(){ printf("Connected.\n"); } /** Callback for when a device is found. */ static void OnDevice(const LEAP_DEVICE_INFO *props){ printf("Found device %s.\n", props->serial); } /** Callback for when a frame of tracking data is available. */ static void OnFrame(const LEAP_TRACKING_EVENT *frame){ printf("Frame %lli with %i hands.\n", (long long int)frame->info.frame_id, frame->nHands); for(uint32_t h = 0; h < frame->nHands; h++){ LEAP_HAND* hand = &frame->pHands[h]; printf(" Hand id %i is a %s hand with position (%f, %f, %f).\n", hand->id, (hand->type == eLeapHandType_Left ? "left" : "right"), hand->palm.position.x, hand->palm.position.y, hand->palm.position.z); } } static void OnImage(const LEAP_IMAGE_EVENT *image){ printf("Image %lli => Left: %d x %d (bpp=%d), Right: %d x %d (bpp=%d)\n", (long long int)image->info.frame_id, image->image[0].properties.width,image->image[0].properties.height,image->image[0].properties.bpp*8, image->image[1].properties.width,image->image[1].properties.height,image->image[1].properties.bpp*8); } static void OnLogMessage(const eLeapLogSeverity severity, const int64_t timestamp, const char* message) { const char* severity_str; switch(severity) { case eLeapLogSeverity_Critical: severity_str = "Critical"; break; case eLeapLogSeverity_Warning: severity_str = "Warning"; break; case eLeapLogSeverity_Information: severity_str = "Info"; break; default: severity_str = ""; break; } printf("[%s][%lli] %s\n", severity_str, (long long int)timestamp, message); } static void* allocate(uint32_t size, eLeapAllocatorType typeHint, void* state) { void* ptr = malloc(size); return ptr; } static void deallocate(void* ptr, void* state) { if (!ptr) return; free(ptr); } void OnPointMappingChange(const LEAP_POINT_MAPPING_CHANGE_EVENT *change){ if (!connectionHandle) return; uint64_t size = 0; if (LeapGetPointMappingSize(*connectionHandle, &size) != eLeapRS_Success || !size) return; LEAP_POINT_MAPPING* pointMapping = (LEAP_POINT_MAPPING*)malloc(size); if (!pointMapping) return; if (LeapGetPointMapping(*connectionHandle, pointMapping, &size) == eLeapRS_Success && pointMapping->nPoints > 0) { printf("Managing %u points as of frame %lld at %lld\n", pointMapping->nPoints, (long long int)pointMapping->frame_id, (long long int)pointMapping->timestamp); } free(pointMapping); } void OnHeadPose(const LEAP_HEAD_POSE_EVENT *event) { printf("Head pose:\n"); printf(" Head position (%f, %f, %f).\n", event->head_position.x, event->head_position.y, event->head_position.z); printf(" Head orientation (%f, %f, %f, %f).\n", event->head_orientation.w, event->head_orientation.x, event->head_orientation.y, event->head_orientation.z); } int main(int argc, char** argv) { //Set callback function pointers ConnectionCallbacks.on_connection = &OnConnect; ConnectionCallbacks.on_device_found = &OnDevice; ConnectionCallbacks.on_frame = &OnFrame; ``` -------------------------------- ### Setting Leap Motion Configuration via Command Line (Windows) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration Demonstrates how to set Leap Motion configuration options on Windows using the command line. This involves running the LeapSvc executable with specified options. ```bash LeapSvc --option_name=value --another_option=value ``` ```bash LeapSvc --image_processing_auto_flip=true --images_mode=2 ``` -------------------------------- ### LEAP_VARIANT Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___structs A variant data type used for getting and setting Leap Motion service configuration values. ```APIDOC ## LEAP_VARIANT ### Description A flexible data structure capable of holding different data types, used for Leap Motion service configuration. ### Method N/A (Structure Definition) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (N/A) N/A #### Response Example N/A ### Fields - **type** (eLeapValueType) - The active data type in this instance. - **boolValue** (bool) - A Boolean value. - **iValue** (int32_t) - An integer value. - **fValue** (float) - A floating point value. - **strValue** (const char *) - A pointer to a string buffer. ``` -------------------------------- ### Open LeapC Connection and Start Message Pump Thread Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/usingleapc This C function initializes and opens a connection to the Leap Motion service using LeapCreateConnection() and LeapOpenConnection(). It then starts a separate thread to run the message pump function, serviceMessageLoop(), to continuously poll for connection messages. A valid connection handle is returned upon successful connection. ```c LEAP_CONNECTION* OpenConnection(){ eLeapRS result = LeapCreateConnection(NULL, &connectionHandle); if(result == eLeapRS_Success){ result = LeapOpenConnection(connectionHandle); if(result == eLeapRS_Success){ _isRunning = true; pthread_create(&pollingThread, NULL, serviceMessageLoop, NULL); } } return &connectionHandle; } ``` -------------------------------- ### Interpolate Leap Motion Frame Data by Timestamp (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/interpolation-example This C code snippet demonstrates how to interpolate Leap Motion tracking data for a specific timestamp. It involves synchronizing application and Leap Motion clocks, calculating the required buffer size, allocating memory, and then requesting the interpolated frame. The example requires the LeapC library and ExampleConnection.c for establishing a connection. ```c #undef __cplusplus #include #include #ifdef _WIN32 #include #else #include #endif #include #include "LeapC.h" #include "ExampleConnection.h" LEAP_CLOCK_REBASER clockSynchronizer; int main(int argc, char** argv) { LEAP_CONNECTION* connHandle = OpenConnection(); while(!IsConnected){ millisleep(250); } printf("Connected.\n"); //Create the clock synchronizer LeapCreateClockRebaser(&clockSynchronizer); cpuTime; int64_t targetFrameTime = 0; uint64_t targetFrameSize = 0; eLeapRS result; for(;;){ //Calculate the application time cpuTime = (clock_t).000001 * clock()/CLOCKS_PER_SEC;//microseconds //Synchronize the clocks LeapUpdateRebase(clockSynchronizer, cpuTime, LeapGetNow()); //Simulate delay (i.e. processing load, v-sync, etc) millisleep(10); //Now get the updated application time cpuTime = (clock_t) .000001 * clock()/CLOCKS_PER_SEC; //Translate application time to Leap time LeapRebaseClock(clockSynchronizer, cpuTime, &targetFrameTime); //Get the buffer size needed to hold the tracking data result = LeapGetFrameSize(*connHandle, targetFrameTime, &targetFrameSize); if(result == eLeapRS_Success){ //Allocate enough memory LEAP_TRACKING_EVENT* interpolatedFrame = malloc((size_t)targetFrameSize); //Get the frame result = LeapInterpolateFrame(*connHandle, targetFrameTime, interpolatedFrame, targetFrameSize); if(result == eLeapRS_Success){ //Use the data... printf("Frame %lli with %i hands with delay of %lli microseconds.\n", (long long int)interpolatedFrame->tracking_frame_id, interpolatedFrame->nHands, (long long int)LeapGetNow() - interpolatedFrame->info.timestamp); for(uint32_t h = 0; h < interpolatedFrame->nHands; h++){ LEAP_HAND* hand = &interpolatedFrame->pHands[h]; printf(" Hand id %i is a %s hand with position (%f, %f, %f).\n", hand->id, (hand->type == eLeapHandType_Left ? "left" : "right"), hand->palm.position.x, hand->palm.position.y, hand->palm.position.z); } //Free the allocated buffer when done. free(interpolatedFrame); } else { printf("LeapInterpolateFrame() result was %s.\n", ResultString(result)); } } else { printf("LeapGetFrameSize() result was %s.\n", ResultString(result)); } } //ctrl-c to exit return 0; } //End-of-Sample ``` -------------------------------- ### Combining Mount Rotations and Translations Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/vrar Illustrates how to combine individual mount rotation matrices (Rx, Ry, Rz) into a single rotation matrix (Rmounted) and then incorporate mount translation (Tmounted) to create a final transformation matrix (Mtabletop↦mounted). ```mathematics Rmounted = Rx * Ry * Rz Mtabletop↦mounted = Tmounted * Rmounted ``` -------------------------------- ### Leap Motion Recording Management Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions API functions for opening, closing, reading, writing, and getting the status of Leap Motion recording files. ```APIDOC ## Leap Motion Recording Management ### Description Functions to manage Leap Motion recording files, including opening, closing, reading, writing, and status retrieval. ### Method Various (primarily C-style function calls) ### Endpoint N/A (Library functions) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c // Example for LeapRecordingOpen and LeapRecordingRead LEAP_RECORDING recording; const char* filePath = "/sdcard/myrecording.lmt"; LEAP_RECORDING_PARAMETERS params = {0}; eLeapRS result = LeapRecordingOpen(&recording, filePath, params); if (result == eLeapRS_Success) { LEAP_TRACKING_EVENT trackingEvent; uint64_t eventSize; result = LeapRecordingReadSize(recording, &eventSize); if (result == eLeapRS_Success) { // Allocate buffer of size eventSize // result = LeapRecordingRead(recording, &trackingEvent, eventSize); } LeapRecordingClose(recording); } ``` ### Response #### Success Response (eLeapRS_Success) - **ppRecording** (LEAP_RECORDING*) - Pointer to the recording handle. - **pstatus** (LEAP_RECORDING_STATUS*) - Pointer to receive recording status. - **pncbEvent** (uint64_t*) - Pointer to receive the size of the next frame in bytes. #### Response Example ```json { "recordingStatus": { "flags": "eLeapRecordingFlags_Active" } } ``` ### Notes - Recording file path is relative to the "user path" on Android. - An ".lmt" suffix is suggested for recording file names. ``` -------------------------------- ### Leap Motion Policy Event Structure Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___structs Contains information about the current policy settings after a request to get or set a policy. It includes reserved fields and the current policy bitfield. ```c struct LEAP_POLICY_EVENT { uint32_t reserved; uint32_t current_policy; }; ``` -------------------------------- ### Initialize Leap Motion Connection and Set Callbacks (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example This C code snippet demonstrates how to initialize a Leap Motion connection, set custom memory allocators, and register callback functions for various events such as image data, point mapping changes, log messages, and head pose updates. It also shows how to set policy flags for image and point mapping data. ```c 110 ConnectionCallbacks.on_image = &OnImage; 111 ConnectionCallbacks.on_point_mapping_change = &OnPointMappingChange; 112 ConnectionCallbacks.on_log_message = &OnLogMessage; 113 ConnectionCallbacks.on_head_pose = &OnHeadPose; 115 connectionHandle = OpenConnection(); 116 { 117 LEAP_ALLOCATOR allocator = { allocate, deallocate, NULL }; 118 LeapSetAllocator(*connectionHandle, &allocator); 119 } 120 LeapSetPolicyFlags(*connectionHandle, eLeapPolicyFlag_Images | eLeapPolicyFlag_MapPoints, 0); 122 printf("Press Enter to exit program.\n"); 123 getchar(); 125 DestroyConnection(); 126 127 return 0; 128 } ``` -------------------------------- ### Setting Leap Motion Configuration via Command Line (Mac/Linux) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration Illustrates how to set Leap Motion configuration options on macOS and Linux using the command line. This involves running the leapd executable with specified options. ```bash leapd --option_name=value --another_option=value ``` ```bash leapd --image_processing_auto_flip=true --images_mode=2 ``` -------------------------------- ### GLUT Callbacks and Initialization Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/glut-shader-example This section details the GLUT initialization and callback function assignments. It sets up the display mode, window size, and registers functions for idle, reshape, keyboard, and display events. OpenGL clear color and initial color are also set. ```c++ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(windowWidth, windowHeight); window = glutCreateWindow("LeapC Distortion Shader Example"); // GLUT callbacks glutIdleFunc(idle); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); // init GL glclearColor(0.0, 0.0, 0.0, 0.0); glcColor3f(1.0, 1.0, 1.0); ``` -------------------------------- ### Leap Motion Variant Data Type Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___structs A versatile data type used for getting and setting configuration values in the Leap Motion service. It supports boolean, integer, float, and string values, indicated by the `type` field. ```c struct LEAP_VARIANT { eLeapValueType type; union { bool boolValue; int32_t iValue; float fValue; const char *strValue; }; }; ``` -------------------------------- ### Handle Leap Motion Device Event (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example Callback function triggered when a device event occurs, providing information about connected Leap Motion devices. It demonstrates opening a device handle using the event data. Requires the LeapC library. ```c /** * Called by serviceMessageLoop() when a device event is returned by LeapPollConnection() * Demonstrates how to access device properties. */ static void handleDeviceEvent(const LEAP_DEVICE_EVENT *device_event){ LEAP_DEVICE deviceHandle; //Open device using LEAP_DEVICE_REF from event struct. eLeapRS result = LeapOpenDevice(device_event->device, &deviceHandle); if(result != eLeapRS_Success){ printf("Could not open device %s.\n", ResultString(result)); return; } } ``` -------------------------------- ### Reading Device Properties Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/usingleapc This section details how to retrieve properties of connected Leap Motion devices. It involves getting a list of devices, opening a specific device, and then fetching its information. ```APIDOC ## Reading Device Properties ### Description Retrieves properties of connected Leap Motion devices by first obtaining a list of known devices, then opening a specific device, and finally fetching its detailed information. ### Method This section describes a process involving multiple C API calls, not a single HTTP request. ### Endpoints N/A (C API functions) ### Parameters N/A (C API functions) ### Request Example ```c // Example C code snippet for reading device properties LEAP_DEVICE_INFO deviceProperties; deviceProperties.serial_length = 1; deviceProperties.serial = malloc(deviceProperties.serial_length); result = LeapGetDeviceInfo(deviceHandle, &deviceProperties); if(result == eLeapRS_InsufficientBuffer){ free(deviceProperties.serial); deviceProperties.serial = malloc(deviceProperties.serial_length); result = LeapGetDeviceInfo(deviceHandle, &deviceProperties); } ``` ### Response #### Success Response - **LEAP_DEVICE_INFO** (struct) - Contains device properties including serial number. #### Response Example ```json { "serial_length": 12, // Example serial number length "serial": "ABC123XYZ789", // Example serial number "device_type": "Leap Motion Controller", // Example device type "firmware_major": 5, // Example firmware version "firmware_minor": 4, "firmware_patch": 0, "firmware_build": 12345 } ``` ``` -------------------------------- ### Leap Motion Service Configuration Options (JSON) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/configuration This JSON object defines various configuration options for the Leap Motion service. These options control aspects like CPU affinity, image processing modes, power saving, and hand tracking behavior. The file must be valid JSON. ```json { "configuration": { "cpu_affinity_mask": 3, "images_mode": 2, "power_saving_adapter": false, "power_saving_battery": false, "process_niceness": 5, "robust_mode_enabled": false, "tracking_hand_enabled": true } } ``` -------------------------------- ### Get Size for Interpolated Leap Motion Frame (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions Determines the required buffer size for an interpolated Leap Motion frame at a specific timestamp. This function is used in conjunction with LeapInterpolateFrame() to ensure adequate memory allocation for frame data. ```c eLeapRS LeapGetFrameSize( LEAP_CONNECTION _hConnection, int64_t _timestamp, uint64_t * _pncbEvent ); ``` -------------------------------- ### Using Images Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/images This section explains how to retrieve and process image data from the Leap Motion controller using the LeapC API. It covers setting image policies, polling for image events, and understanding the structure of the image buffer. ```APIDOC ## Using Images ### Description This endpoint describes the process of obtaining and utilizing image data from the Leap Motion controller. Images are automatically sent when the image policy is enabled. Stereo image pairs are available via `LEAP_IMAGE_EVENT` in the event queue, accessed through `LeapPollConnection()`. ### Method Polling ### Endpoint `LeapPollConnection()` ### Parameters #### Query Parameters - **image policy** (boolean) - Required - Enables the automatic sending of image data. ### Request Example ```json { "action": "set_image_policy", "enabled": true } ``` ### Response #### Success Response (200) - **LEAP_IMAGE_EVENT** (struct) - Contains image properties, distortion correction data, and a pointer to the image buffer. #### Response Example ```json { "type": "LEAP_IMAGE_EVENT", "timestamp": 1678886400000, "images": [ { "type": "left", "width": 640, "height": 240, "format": "bytesPerPixel", "data": "..." }, { "type": "right", "width": 640, "height": 240, "format": "bytesPerPixel", "data": "..." } ], "distortion_map": "..." } ``` ``` -------------------------------- ### Interpolate Leap Motion Frame Data (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___functions Constructs a Leap Motion tracking frame at a specified timestamp by interpolating between available measured frames. The caller must allocate a buffer of sufficient size, which can be determined using LeapGetFrameSize(). Accurate interpolation requires time synchronization using LeapCreateClockRebaser(), LeapUpdateRebase(), and LeapRebaseClock(). ```c eLeapRS LeapInterpolateFrame( LEAP_CONNECTION _hConnection, int64_t _timestamp, LEAP_TRACKING_EVENT * _pEvent, uint64_t _ncbEvent ); ``` -------------------------------- ### Handle Leap Motion Connection Event (C) Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/callback-example Callback function invoked when a connection event is received from the Leap Motion service. It updates the connection status and triggers an optional user-defined callback. Requires the LeapC library. ```c /** Called by serviceMessageLoop() when a connection event is returned by LeapPollConnection(). */ static void handleConnectionEvent(const LEAP_CONNECTION_EVENT *connection_event){ IsConnected = true; if(ConnectionCallbacks.on_connection){ ConnectionCallbacks.on_connection(); } } ``` -------------------------------- ### Oculus SDK Head Tracking Transformation Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/vrar Demonstrates how to obtain and combine head tracking data from the Oculus SDK (using `ovr_GetTrackingState`) to create an HMD-to-world transformation matrix. This is crucial for anchoring Leap Motion tracking data correctly in VR. ```c++ #include // Assuming ovr_GetTrackingState is called elsewhere and returns a valid state OVR::TrackingState trackingState = ovr_GetTrackingState(...); ovrPosef headPose = trackingState.HeadPose.ThePose; OVR::Matrix4f translation = OVR::Matrix4f::Translation(headPose.Position); OVR::Matrix4f rotation = OVR::Matrix4f(headPose.Orientation); OVR::Matrix4f hmdToWorld = translation * rotation; ``` -------------------------------- ### eLeapEventType_ConfigResponse Source: https://www.leapmotiontechnology.com/developer-sub/documentation/v4/group___enum Represents the asynchronous response to a request for a configuration value. ```APIDOC ## eLeapEventType_ConfigResponse ### Description The asynchronous response to a call to LeapRequestConfigValue(). Contains the value of requested configuration item. ### Since 3.0.0 ```