greenhouse
a creative coding toolkit for spatial interfaces

Getting started with a Leap Motion

The Greenhouse SDK can take input from Leap Motion devices.

With Greenhouse, we tend to favor a philosophy of small pieces, loosely joined, so you’ll see evidence of that approach in our Leap integration: it’s a small pipeline of independent programs.

This is similar to the way that Greenhouse works with the Kinect device. In that case, the pipeline is the hantenna pipeline; its pieces were written by Oblong.

In the case of the Leap, the pipeline begins with the Leap SDK software, written by Leap Motion, Inc. The Leap SDK takes raw data from the device. Next, we’ve added a small program called splash.

splash translates Leap Motion data (which is in relative coordinates) into absolute coordinates that Greenhouse can use. It’s built as a Greenhouse worker application, and it’s open source.

Splash is not currently packaged with the Greenhouse SDK; you have to grab the source of Splash from Github and compile it in order to use it. (This is mainly because when you compile Splash, it needs to know where you’ve put your Leap SDK – which we don’t know in advance; thus we can’t compile it for you.)

Splash takes data from the Leap SDK, transforms it, and puts the result into a pool (called “leap”). Your Greenhouse program (or programs) will take the data from that pool and do something with it. To learn more about pools and our Plasma message-passing system, see here.

Greenhouse applications don’t actually know about, or do anything with, Leap input by default. But we’ve written some listener code which helps transform the points and rays which the Leap SDK gives us into (pseudo-) pointing and other events. Using our listener code, you can make your application Leap-aware with only a couple of lines. Or you can modify it to fit your purposes better.

The listener code is found in two header files that ship with Greenhouse: LeapListener.h and LeapPointing.h. These are header-only; there is no .C file. Feel free to modify and experiment with these files without needing to recompile or update the core Greenhouse library. The source code is open, and we welcome feedback and patches from the community.

One of our goals with Leap support was to provide a general, open model of how to integrate sensor devices with Greenhouse. If you look behind the scenes, you’ll see that aside from defining a few data structures, there’s not a large amount of code.

Using this approach as a template, you can build Greenhouse support for input from any kind of sensor, without needing to wait for that support to be built into the core library. Got ideas? Email us at greenhouse@oblong.com.

Check out the Leap API reference page for more details about adding Leap support in your application.

Mac OS X

Requirements: before you get started

  • a Leap Motion device
  • Leap SDK software from from Leap Motion. Version 0.7.9 or later.

Compile Splash

  • Grab the project from GitHub.

  • Follow the README and compile the program from source.

Compile our Leap sample

Using Xcode or the terminal, open the sample which the Greenhouse SDK installer put at /opt/oblong/greenhouse/samples/leap . (See Running your first application for help on the basics of building and running a Greenhouse app.)

Run

  1. Make sure the Leap is plugged in, the Leap software is running, and the setup is generally working.

  2. Run splash (consult Splash’s README for details):

     $ ./splash
    
  3. Verify that splash is working by inspecting the data streaming into the leap pool.

     $ peek leap
    
  4. Run the Leap sample, or your own application

Configuration

By default, splash will use your existing screen and feld configuration proteins and assume the leap is resting on a table about 500mm in front and 200mm below your main screen (see the diagram below). If you have a different setup, consult the splash README to discover how to change this configuration.

Default Leap Configuration

Write your Leap-driven application

Start by creating a new Greenhouse application, or copy and start hacking the sample. (Be aware that if you work in /opt/oblong/greenhouse/samples/, and then upgrade the Greenhouse SDK later, the samples directory may be overwritten by the upgrade. So copy the project folder somewhere else and work on the copy.)

Start by pasting this include near the top of your code:

   #include "LeapPointing.h"

Basic Pointing

Our most basic kind of Leap support sends your app Greenhouse PointingEvents when the Leap devices sees pointy things (such as fingers and pens). This treats the Leap as essentially a (clickless) mouse (or, to be more accurate, a gang of appearing and disappearing mice).

With basic pointing support, all your objects will have their PointingAppear()/PointingMove()/PointingVanish() methods invoked (if they have implemented them) when the Leap device generates that kind of event. You can get fairly accurate direction information from a pointing events by taking the line from its physorigin (origin) to its physthrough (a point it passes through).

Note: Our Leap support does not support the concept of “hardening” (aka clicking), so you will not receive PointingHarden()/PointingSoften() events. Also: Leap pointing objects can be highly transient, so you may receive a lot of appears and vanishes.

To enable basic pointing, add this to your Setup function:

    EnableLeapPointing ();

Specialized Events

The next level of support is for specialized events that the Leap SDK reports: Pointer, Hand, Circle, Swipe, ScreenTap, and KeyTap. To have a Greenhouse object receive these events, it should do two things:

1.  inherit from LeapListener, using C++ multiple inheritance.  (See example below.)
2.  Call ListenForLeapEvents () in the constructor of the listening object.

It looks like this:

    class myThing  :  public Thing,
                      public LeapListener     //  step 1
    { public:
      myThing ()
        { ListenForLeapEvents (this); }       // step 2            

      void LeapPointer (LMPointer const&p, LMFrame const &f)
        { // do something }
      void LeapHand (LMHand const&p, LMFrame const &f)
        { // do something }
      void LeapCircle (LMCircle const&p, LMFrame const &f)
        { // do something }
      void LeapSwipe (LMSwipe const&p, LMFrame const &f)
        { // do something }
      void LeapScreenTap (LMScreenTap const&p, LMFrame const &f)
        { // do something }
      void LeapKeyTap (LMKeyTap const &p, LMFrame const &f)
        { // do something }
    };

This sets up the myThing class so that any instance of it will listen for Leap events. The set of Leapxxx methods are virtual methods you can implement to get notified when these events happen.

Check out our Leap API reference page for more details. Or jump into LeapListener.h and LeapPointing.h (which you’ll find at /opt/oblong/greenhouse/include) for the straight dope.