/*
JWildfire - an image and animation processor written in Java
Copyright (C) 1995-2015 Andreas Maschke
This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This software 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this software;
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.create.tina.leapmotion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jwildfire.base.Tools;
public class LeapMotionEditorListenerRecorder {
private final LeapMotionConnectedProperties config;
private final int fps;
private List<LeapMotionEditorHandEvent> leftHandMotion = new ArrayList<LeapMotionEditorHandEvent>();
private List<LeapMotionEditorHandEvent> rightHandMotion = new ArrayList<LeapMotionEditorHandEvent>();
public LeapMotionEditorListenerRecorder(LeapMotionConnectedProperties pConfig, int pFps) {
config = pConfig;
fps = pFps;
}
public void recordEvent(LeapMotionEditorEvent pEvent) {
if (pEvent.getLeftHand() != null) {
leftHandMotion.add(pEvent.getLeftHand());
}
if (pEvent.getRightHand() != null) {
rightHandMotion.add(pEvent.getRightHand());
}
}
public boolean isEmpty() {
return leftHandMotion.isEmpty() && rightHandMotion.isEmpty();
}
public static class LeapMotionEditorEventWithFrame extends LeapMotionEditorEvent {
public LeapMotionEditorEventWithFrame() {
super(new LeapMotionEditorHandEvent(), new LeapMotionEditorHandEvent());
}
private double frame;
public double getFrame() {
return frame;
}
public void setFrame(double pFrame) {
frame = pFrame;
}
}
public List<LeapMotionEditorEventWithFrame> getTransformedData() {
Set<Long> keyFrames = new HashSet<Long>();
Map<Long, LeapMotionEditorHandEvent> leftMap = new HashMap<Long, LeapMotionEditorHandEvent>();
Map<Long, LeapMotionEditorHandEvent> rightMap = new HashMap<Long, LeapMotionEditorHandEvent>();
for (LeapMotionEditorHandEvent event : leftHandMotion) {
keyFrames.add(event.getTimestamp());
leftMap.put(event.getTimestamp(), event);
}
for (LeapMotionEditorHandEvent event : rightHandMotion) {
keyFrames.add(event.getTimestamp());
rightMap.put(event.getTimestamp(), event);
}
List<Long> sortedKeyFrames = new ArrayList<Long>(keyFrames);
Collections.sort(sortedKeyFrames);
LeapMotionEditorHandEvent lastLeftEvent = new LeapMotionEditorHandEvent();
LeapMotionEditorHandEvent lastRightEvent = new LeapMotionEditorHandEvent();
List<LeapMotionEditorEventWithFrame> res = new ArrayList<LeapMotionEditorEventWithFrame>();
for (Long keyFrame : sortedKeyFrames) {
LeapMotionEditorHandEvent leftEvent = leftMap.get(keyFrame);
if (leftEvent == null) {
leftEvent = lastLeftEvent;
}
else {
lastLeftEvent = leftEvent;
}
LeapMotionEditorHandEvent rightEvent = rightMap.get(keyFrame);
if (rightEvent == null) {
rightEvent = lastRightEvent;
}
else {
lastRightEvent = rightEvent;
}
LeapMotionEditorEventWithFrame data = new LeapMotionEditorEventWithFrame();
data.setFrame(((double) keyFrame * fps) / 1000.0);
data.getLeftHand().setPosX(leftEvent.getPosX());
data.getLeftHand().setPosY(leftEvent.getPosY());
data.getLeftHand().setPosZ(leftEvent.getPosZ());
data.getLeftHand().setRoll(leftEvent.getRoll());
data.getLeftHand().setPitch(leftEvent.getPitch());
data.getLeftHand().setYaw(leftEvent.getYaw());
data.getRightHand().setPosX(rightEvent.getPosX());
data.getRightHand().setPosY(rightEvent.getPosY());
data.getRightHand().setPosZ(rightEvent.getPosZ());
data.getRightHand().setRoll(rightEvent.getRoll());
data.getRightHand().setPitch(rightEvent.getPitch());
data.getRightHand().setYaw(rightEvent.getYaw());
res.add(data);
}
return res;
}
public String getDataAsString() {
StringBuilder sb = new StringBuilder();
addHeader(sb);
for (LeapMotionEditorEventWithFrame data : getTransformedData()) {
addKeyFrame(sb, data);
}
return sb.toString();
}
private void addKeyFrame(StringBuilder pSb, LeapMotionEditorEventWithFrame pData) {
pSb.append(Tools.doubleToString(pData.getFrame()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getPosX()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getPosY()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getPosZ()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getRoll()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getPitch()) + " ");
pSb.append(Tools.doubleToString(pData.getLeftHand().getYaw()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getPosX()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getPosY()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getPosZ()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getRoll()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getPitch()) + " ");
pSb.append(Tools.doubleToString(pData.getRightHand().getYaw()) + "\n");
}
private void addHeader(StringBuilder pSb) {
pSb.append("#");
pSb.append("time ");
pSb.append("leftPosX ");
pSb.append("leftPosY ");
pSb.append("leftPosZ ");
pSb.append("leftRoll ");
pSb.append("leftPitch ");
pSb.append("leftYaw ");
pSb.append("rightPosX ");
pSb.append("rightPosY ");
pSb.append("rightPosZ ");
pSb.append("rightRoll ");
pSb.append("rightPitch ");
pSb.append("rightYaw\n");
}
public LeapMotionConnectedProperties getConfig() {
return config;
}
public int getFps() {
return fps;
}
}