package com.dronecontrol.leapcontrol.input.leapmotion;
import com.google.common.collect.Sets;
import com.leapmotion.leap.Controller;
import com.leapmotion.leap.Frame;
import com.leapmotion.leap.Gesture;
import com.leapmotion.leap.GestureList;
import com.leapmotion.leap.Hand;
import com.leapmotion.leap.Listener;
import com.leapmotion.leap.Vector;
import com.dronecontrol.leapcontrol.input.leapmotion.data.DetectionData;
import com.dronecontrol.leapcontrol.input.leapmotion.data.GestureData;
import com.dronecontrol.leapcontrol.input.leapmotion.listeners.DetectionListener;
import com.dronecontrol.leapcontrol.input.leapmotion.listeners.GestureListener;
import org.apache.log4j.Logger;
import java.util.Set;
public class LeapMotionListener extends Listener
{
public static final float MAX_ROLL = 40.0f;
public static final float MAX_PITCH = 40.0f;
private static final float MAX_YAW = 40.0f;
public static final float MAX_HEIGHT = 600.0f;
private static int currentGestureId = 0;
private Logger logger = Logger.getLogger(LeapMotionListener.class);
private final Set<DetectionListener> detectionListeners;
private final Set<GestureListener> gestureListeners;
public LeapMotionListener()
{
detectionListeners = Sets.newHashSet();
gestureListeners = Sets.newHashSet();
}
public void onInit(Controller controller)
{
logger.info("Leap motion listener initialized");
}
public void onConnect(Controller controller)
{
logger.info("Leap motion listener connected");
}
public void onDisconnect(Controller controller)
{
logger.info("Leap motion listener disconnected");
}
public void onExit(Controller controller)
{
logger.info("Leap motion listener exited");
}
public void onFrame(Controller controller)
{
Frame frame = controller.frame();
GestureList gestures = frame.gestures();
for (Gesture gesture : gestures)
{
processGestureEvent(gesture);
}
if (frame.hands().isEmpty())
{
processNoDetectionEvent();
} else
{
Hand hand = frame.hands().get(0);
processDetectionEvent(hand);
}
}
private void processGestureEvent(Gesture gesture)
{
if (gesture.id() <= currentGestureId)
{
return;
}
currentGestureId = gesture.id();
logger.info(String.format("Gesture '%s' detected.", gesture.type().name()));
emitGestureEvent(gesture.id(), Gesture.Type.TYPE_CIRCLE);
}
private void emitGestureEvent(int eventId, Gesture.Type gestureType)
{
for (GestureListener listener : gestureListeners)
{
listener.onGesture(new GestureData(eventId, gestureType));
}
}
private void processNoDetectionEvent()
{
logger.trace("No hand detected");
for (DetectionListener listener : detectionListeners)
{
listener.onNoDetect();
}
}
public void processDetectionEvent(Hand hand)
{
DetectionData detectionData = getDetectionData(hand);
logger.trace(String
.format("Detected a hand - roll: %.2f, pitch: %.2f, yaw: %.2f, height: %.2f",
detectionData.getRoll(), detectionData.getPitch(),
detectionData.getYaw(), detectionData.getHeight()));
for (DetectionListener listener : detectionListeners)
{
listener.onDetect(detectionData);
}
}
public DetectionData getDetectionData(Hand hand)
{
// Get the hand's normal vector and direction
Vector normal = hand.palmNormal();
Vector direction = hand.direction();
float pitch = ((Double) Math.toDegrees(direction.pitch())).floatValue()
/ MAX_PITCH;
float roll = ((Double) Math.toDegrees(normal.roll())).floatValue()
/ MAX_ROLL;
float yaw = ((Double) Math.toDegrees(direction.yaw())).floatValue()
/ MAX_YAW;
float height = hand.palmPosition().getY() / MAX_HEIGHT;
return new DetectionData(roll, pitch, yaw, height);
}
public void addDetectionListener(DetectionListener detectionListener)
{
if (!detectionListeners.contains(detectionListener))
{
detectionListeners.add(detectionListener);
}
}
public void removeDetectionListener(DetectionListener detectionListener)
{
if (detectionListeners.contains(detectionListener))
{
detectionListeners.remove(detectionListener);
}
}
public void addGestureListener(GestureListener gestureListener)
{
if (!gestureListeners.contains(gestureListener))
{
gestureListeners.add(gestureListener);
}
}
public void removeGestureListener(GestureListener gestureListener)
{
if (gestureListeners.contains(gestureListener))
{
gestureListeners.remove(gestureListener);
}
}
}