Congratulations on your purchase of a genuine fine quality Leap Motion gesture input device! This handy guide will walk you through the assembly, proper usage, and care of your Leap Motion.
To get started, remove your Leap Motion SDK and Leap Motion™ device from the box and unpack the shared object files and headers from their shrink-wrap. Gently place your SDK in a handy directory and fire up your favorite IDE to begin.
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
We'll get things going right away with a short C++ application to illustrate how to interact with the Leap SDK to receive events and input.
#include <iostream> #include <Leap.h> class Quickstart : public Leap::Listener { public: virtual void onConnect(const Leap::Controller &); virtual void onFrame(const Leap::Controller &); };
To interact with the Leap software, we will begin by creating a subclass of Leap::Listener
and defining the callback methods we wish to receive. While it is possible to poll the controller for the current frame, generally you will want to make your program as responsive as possible which is most easily accomplished by acting on input events immediately via callbacks. In case you're wondering, the primary available callback methods are:
onInit
: This indicates that the listener is added to a controller and called only once.onExit
: This indicates that the controller is destroyed or the listener is removed.onConnect
: This indicates that the device is connected and recognized by the driver and is ready to start processing frames.onDisconnect
: This indicates that the device is disconnected. Connection state can also be polled by checkingcontroller.isConnected()
so that you don't need to keep track of whether the controller is plugged in or not. (An earlier version of the SDK lacked this state accessor but the kind folks at Leap Motion realized us devs are really lazy).onFrame
: This indicates that a new frame of input data has been captured and processed. This is the only handler you really need to implement if you want to make use of the Leap.
Let's implement our onConnect
handler real quick so that we can verify that the controller driver and SDK are communicating with the device properly. If everything is working as it should be, the following code should cause a message to be emitted on stdout when the device is plugged in to a USB port:
void Quickstart::onConnect(const Leap::Controller &controller) { std::cout << "Hello, Leap user!\n"; }
We can display a friendly contrived greeting to ourselves when the program is run with the controller connected and the driver software is running. This will cause breathless anticipation in your users as they prepare themselves to experience the magic and wonder of this fantastic new input technology.
A listener is attached to a Leap::Controller
, which acts as the primary interface between the Leap driver and your application. A controller tracks processed frames, device connection state, configuration parameters, and invokes callback methods on a listener.
To begin receiving events, instantiate a new listener and a controller:
int main() { // create instance of our Listener subclass Quickstart listener; // create generic Controller to interface with the Leap device Leap::Controller controller; // tell the Controller to start sending events to our Listener controller.addListener(listener); …
If you place your hands over the device Quickstart::onFrame()
will start being called. Let's create an onFrame
handler that reports on the horizontal velocity of the first finger or tool detected:
void Quickstart::onFrame(const Leap::Controller &controller) { const Leap::Frame frame = controller.frame();
controller.frame()
returns a Frame
instance, which contains information detected about our scene at a specific point in time. It has a single optional parameter history
, which allows you to travel backwards through the misty sands of time to compare frames and determine hand changes over time. Unfortunately this time machine is rather limited; only about 60 previous frames are stored in the controller.
// do nothing unless hands are detected if (frame.hands().empty()) return;
Get used to making these sorts of checks. You'll be seeing a lot more of them. Here, we have no interest in processing this frame unless there are hands in it.
// first detected hand const Leap::Hand firstHand = frame.hands()[0]; // first pointable object (finger or tool) const Leap::PointableList pointables = firstHand.pointables(); if (pointables.empty()) return; const Leap::Pointable firstPointable = pointables[0];
All fingers attached to a hand and all tools that the hand is grasping are returned as a PointableList, which behaves like an std::vector
, including providing an iterator for people who are into that. Most commonly we will want to find out where a pointable is in space and how fast it is moving, which we can easily find out with tipPosition()
and tipVelocity()
respectively. Both return Leap::Vectors
consisting of X, Y, and Z components.
std::cout << "Pointable X velocity: " << firstPointable.tipVelocity()[0] << endl;
If you wave an outstretched finger or a tool (a chopstick works pretty well if you happen to have one lying around) back and forth over the controller you will be rewarded with the following riveting output:
Pointable X velocity: -223.937 Pointable X velocity: -117.421 Pointable X velocity: -242.293 Pointable X velocity: -141.43 Pointable X velocity: -61.9314 Pointable X velocity: 9.85328 Pointable X velocity: 41.9575 Pointable X velocity: 71.7436 Pointable X velocity: 96.0459 Pointable X velocity: 116.465
Leftwards motion is represented by negative values (mm/s). Rightwards motion is positive.
Tip
A note on the sample code
Because of frequent changes to the SDK, your best bet for finding the most up-to-date code samples is to check out the GitHub repository.
All sample code can be found at https://github.com/openleap/leapbook. This program and others like it can be built using the following command on Mac OS X or Linux using GCC or clang:
$ g++ quickstart.cpp -lLeap –Lpath/to/Leap_SDK/lib/libc++ –Ipath/to/Leap_SDK/include –o quickstart
Note that path/to/Leap_SDK
should be replaced with the location of your Leap_SDK directory. It may be helpful to set an environment variable with the path or install the libraries and headers system-wide.