greenhouse
a creative coding toolkit for spatial interfaces

Leap Motion Event Handling

To get started with Leap Motion devices, see our setup tutorial.

Here we show how to receive various kinds of events that have been piped from the Leap sensor, through the splash application, into the leap pool, and into your application. Our tutorial shows how to get this input pipeline up and running. (It’s not as bad as it sounds.)

To start using Leap capabilities, add the following line somewhere at the top of your program:

#include "LeapPointing.h"
  • EnableLeapPointing ()
  • ListenForLeapEvents ()
  • LeapPointer ()
  • LeapHand ()
  • LeapCircle ()
  • LeapSwipe ()
  • LeapScreenTap ()
  • LeapKeyTap ()
  • LMFrame

Example

#include "Greenhouse.h"
#include "LeapPointing.h"

class CustomImage : public Image
{
public:
  CustomImage (const Str &img_path) : Image (img_path)
    { SetHeightUniformly (0.04 * Feld () -> Height ()); }

  bool PointerNotBeingHeeded (PointingEvent *e)
    { return Find <CustomImage> ("." + e -> Provenance ()) == NULL; }

  void PointingAppear (PointingEvent *e)
    { if (IsHeedless () && PointerNotBeingHeeded (e))
        { Heed (e);
          Tag (e -> Provenance ());
        }
    }
  void PointingMove (PointingEvent *e)
    { if (IsHeedless () && PointerNotBeingHeeded (e))
        { Heed (e);
          Tag (e -> Provenance ());
        }
      if (IsHeeding (e))
        SetTranslation (Intersection (e));
    }

  void PointingVanish (PointingEvent *e)
    { StopHeeding ();
      UnTag (e -> Provenance ());
    }
};

class CustomLeapHandler  :  public Thing, public LeapListener
{
private:
  Image *img;
public:

  CustomLeapHandler ()  :  Thing (), LeapListener ()
    { ListenForLeapEvents (this);
      SlapOnFeld ();
      img = new Image ("images/heart.png");
      img -> SetHeightUniformly (0.1 * Feld () -> Height ());
      img -> TranslationAnimateQuadratic (1.0);
      AppendKid (img);
    }

  void LeapPointer (const LMPointer &p, const LMFrame &f)
    { /* doing nothing; */ }

  void LeapHand (const LMHand &h, const LMFrame &f)
    { /* doing nothing; */ }

  void LeapCircle (const LMCircle &c, const LMFrame &f)
    { static float64 last_progress = 0.0;
      if (c . state == "start")
        last_progress = 0.0;
      if (c . normal . Dot (Norm ()) > 0)
        IncRotation (Norm (), (c . progress - last_progress) / (2 * PI));
      else
        IncRotation (Norm (), -(c . progress - last_progress) / (2 * PI));
      last_progress = c . progress;
    }

  void LeapSwipe (const LMSwipe &s, const LMFrame &f)
    { if (s . state != "stop")
        return;
      Vect offset = 50 * (s . direction -
                          s . direction . Dot (Norm ()) * Norm ());
      img -> SetTranslation (offset);
    }

  void LeapScreenTap (const LMScreenTap &s, const LMFrame &f)
    { img -> SetScale (Random (0, 5)); }

  void LeapKeyTap (const LMKeyTap &k, const LMFrame &f)
    { img -> Heartbeat ();
      LMPointer p;
      if (PointerFromGesture(k, f, p))
        INFORM ("Current pointer's intersection with the feld is: " +
                ToStr (Intersection(p .phys_origin, p .phys_through)));
    }
};

void Setup ()
{ EnableLeapPointing ();
  for (int i = 0; i < 10; i++)
    new CustomImage ("images/mouse.png");
  new CustomLeapHandler ();
}