Package com.onformative.leap

Source Code of com.onformative.leap.LeapMotionListener

package com.onformative.leap;

/**
* LeapMotionP5
*
* LeapMotionP5 library for Processing. Copyright (c) 2012-2013 held jointly by the individual
* authors.
*
* LeapMotionP5 library for Processing is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* LeapMotionP5 for Processing is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with LeapMotionP5 library
* for Processing. If not, see http://www.gnu.org/licenses/.
*
* Leap Developer SDK. Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.
*
* NOTICE: This developer release of Leap Motion, Inc. software is confidential and intended for
* very limited distribution. Parties using this software must accept the SDK Agreement prior to
* obtaining this software and related tools. This software is subject to copyright.
*/

import java.util.Date;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;

import processing.core.PApplet;

import com.leapmotion.leap.CircleGesture;
import com.leapmotion.leap.Controller;
import com.leapmotion.leap.Frame;
import com.leapmotion.leap.Gesture;
import com.leapmotion.leap.Gesture.State;
import com.leapmotion.leap.GestureList;
import com.leapmotion.leap.KeyTapGesture;
import com.leapmotion.leap.Listener;
import com.leapmotion.leap.ScreenTapGesture;
import com.leapmotion.leap.SwipeGesture;

/**
* LeapMotionListener.java
*
* @author Marcel Schwittlick
* @modified 04.02.2013
*
*           this listener is listening for the events of the offical leap motion sdk
*/
class LeapMotionListener extends Listener {
  private LeapMotionP5 leap;

  protected int maxFramesToRecord = 1000;
  private String callbackMethodNameCircle;
  private String callbackMethodNameSwipe;
  private String callbackMethodNameScreenTap;
  private String callbackMethodNameKeyTap;

  /**
   *
   * @param p PApplet the processing applet
   * @param leap LeapMotionP5 an instance of the LeapMotionP5 class
   */
  public LeapMotionListener(LeapMotionP5 leap) {
    this.leap = leap;
    this.leap.currentFrame = new Frame();
    this.leap.lastFrames = new LinkedList<Frame>();
    this.leap.lastFramesInclProperTimestamps = new ConcurrentSkipListMap<Date, Frame>();
    this.leap.oldFrames = new CopyOnWriteArrayList<Frame>();
    this.leap.oldControllers = new LinkedList<Controller>();

    this.callbackMethodNameCircle = "circleGestureRecognized";
    this.callbackMethodNameSwipe = "swipeGestureRecognized";
    this.callbackMethodNameScreenTap = "screenTapGestureRecognized";
    this.callbackMethodNameKeyTap = "keyTapGestureRecognized";
  }

  public void onInit(Controller controller) {
    System.out.println("Leap Motion Initialized");
  }

  public void onConnect(Controller controller) {
    System.out.println("Leap Motion Connected");
  }

  public void onDisconnect(Controller controller) {
    System.out.println("Leap Motion Disconnected");
  }

  public void onExit(Controller controller) {
    System.out.println("Leap Motion Exited");
  }

  private void invokeCallback(Gesture gesture) {
    PApplet parent = this.leap.getParent();

    if (parent != null) {
      switch (gesture.type()) {
        case TYPE_CIRCLE:
          CircleGesture circleGesture = new CircleGesture(gesture);
          String clockwiseness;
          if (circleGesture.pointable().direction().angleTo(circleGesture.normal()) <= Math.PI / 4) {
            // Clockwise if angle is less than 90 degrees
            clockwiseness = "clockwise";
          } else {
            clockwiseness = "counterclockwise";
          }
          try {
            parent.getClass()
                .getMethod(this.callbackMethodNameCircle, CircleGesture.class, String.class)
                .invoke(parent, circleGesture, clockwiseness);
          } catch (Exception e) {
            PApplet.println(e.getMessage() + " CALLBACK ERROR");
          }
          break;
        case TYPE_SWIPE:
          SwipeGesture swipeGesture = new SwipeGesture(gesture);
          try {
            parent.getClass().getMethod(this.callbackMethodNameSwipe, SwipeGesture.class)
                .invoke(parent, swipeGesture);
          } catch (Exception e) {
            PApplet.println(e.getMessage() + " CALLBACK ERROR");
          }
          break;
        case TYPE_SCREEN_TAP:
          ScreenTapGesture screenTapGesture = new ScreenTapGesture(gesture);
          try {
            parent.getClass().getMethod(this.callbackMethodNameScreenTap, ScreenTapGesture.class)
                .invoke(parent, screenTapGesture);
          } catch (Exception e) {
            PApplet.println(e.getMessage() + " CALLBACK ERROR");
          }
          break;
        case TYPE_KEY_TAP:
          KeyTapGesture keyTapGesture = new KeyTapGesture(gesture);
          try {
            parent.getClass().getMethod(this.callbackMethodNameKeyTap, KeyTapGesture.class)
                .invoke(parent, keyTapGesture);
          } catch (Exception e) {
            PApplet.println(e.getMessage() + " CALLBACK ERROR");
          }
          break;
        default:
          break;
      }
    }


  }

  private void printGestureDetails(Gesture gesture, Controller controller) {
    switch (gesture.type()) {
      case TYPE_CIRCLE:
        CircleGesture circle = new CircleGesture(gesture);

        // Calculate clock direction using the angle between circle normal and pointable
        String clockwiseness;
        if (circle.pointable().direction().angleTo(circle.normal()) <= Math.PI / 4) {
          // Clockwise if angle is less than 90 degrees
          clockwiseness = "clockwise";
        } else {
          clockwiseness = "counterclockwise";
        }

        // Calculate angle swept since last frame
        double sweptAngle = 0;
        if (circle.state() != State.STATE_START) {
          CircleGesture previousUpdate =
              new CircleGesture(controller.frame(1).gesture(circle.id()));
          sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * Math.PI;
        }

        System.out.println("Circle id: " + circle.id() + ", " + circle.state() + ", progress: "
            + circle.progress() + ", radius: " + circle.radius() + ", angle: "
            + Math.toDegrees(sweptAngle) + ", " + clockwiseness);
        break;
      case TYPE_SWIPE:
        SwipeGesture swipe = new SwipeGesture(gesture);
        System.out.println("Swipe id: " + swipe.id() + ", " + swipe.state() + ", position: "
            + swipe.position() + ", direction: " + swipe.direction() + ", speed: " + swipe.speed());
        break;
      case TYPE_SCREEN_TAP:
        ScreenTapGesture screenTap = new ScreenTapGesture(gesture);
        System.out.println("Screen Tap id: " + screenTap.id() + ", " + screenTap.state()
            + ", position: " + screenTap.position() + ", direction: " + screenTap.direction());
        break;
      case TYPE_KEY_TAP:
        KeyTapGesture keyTap = new KeyTapGesture(gesture);
        System.out.println("Key Tap id: " + keyTap.id() + ", " + keyTap.state() + ", position: "
            + keyTap.position() + ", direction: " + keyTap.direction());
        break;
      default:
        System.out.println("Unknown gesture type.");
        break;
    }

  }

  private void processGestures(Controller controller) {
    GestureList list = controller.frame().gestures();
    if (list.empty() == false) {
      for (int i = 0; i < list.count(); i++) {
        Gesture gesture = list.get(i);
        invokeCallback(gesture);
        // printGestureDetails(gesture, controller);
      }
    }
  }

  /**
   * this is called about 100-120 times a second delevering a new frame with information from the
   * leap tracking everything in its viewport. This is where most of the data which is accessible in
   * processing is coming from
   */
  public void onFrame(Controller controller) {
    Frame frame = controller.frame();
    this.leap.currentFrame = frame;

    processGestures(controller);

    // adding frames the list. making sure that only the newest frames are saved in order
    if (leap.lastFrames.size() >= maxFramesToRecord) {
      leap.lastFrames.removeFirst();
    }
    leap.lastFrames.add(frame);

    // adding frames to the list. adding a proper timestamp to each frame object
    if (leap.lastFramesInclProperTimestamps.size() >= maxFramesToRecord) {
      leap.lastFramesInclProperTimestamps.remove(leap.lastFramesInclProperTimestamps.firstKey());
    }
    leap.lastFramesInclProperTimestamps.put(new Date(), frame);

    // adding old frames to different object
    if (leap.oldFrames.size() >= maxFramesToRecord) {
      leap.oldFrames.remove(0);
    }
    leap.oldFrames.add(frame);

    if (leap.oldControllers.size() >= maxFramesToRecord) {
      leap.oldControllers.removeLast();
    }
    leap.oldControllers.add(controller);
  }
}
TOP

Related Classes of com.onformative.leap.LeapMotionListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.