├── README.md
├── examples
├── active_fingers
│ └── active_fingers.pde
├── finger_to_pvector
│ └── finger_to_pvector.pde
├── gesture_recognition
│ └── gesture_recognition.pde
├── lowlevel_access
│ └── lowlevel_access.pde
├── lowlevel_access_multiple_frames
│ └── lowlevel_access_multiple_frames.pde
├── screen_calibration
│ └── screen_calibration.pde
└── velocity_graph
│ └── velocity_graph.pde
├── library.properties
├── library
├── LeapJava.jar
├── LeapMotionP5.jar
├── macosx
│ ├── libLeap.dylib
│ └── libLeapJava.dylib
├── windows
│ ├── Leap.dll
│ └── LeapJava.dll
└── windows64
│ ├── Leap.dll
│ └── LeapJava.dll
└── src
└── com
└── onformative
└── leap
├── LeapMotionListener.java
└── LeapMotionP5.java
/README.md:
--------------------------------------------------------------------------------
1 | LeapMotionP5
2 | ======================
3 | #### A Leap Motion Library for Processing
4 |
5 | Working with all Processing versions and all operating systems (OSX, Windows), with the newest version of the leap motion sdk. Moreover it is including a variety of gestures.
6 | Just download the library archive at the bottom of this readme and extract it into the libraries folder of your processing sketchbook and your're ready to go.
7 |
8 | Check http://www.onformative.com/lab/leapmotionp5 for additional information about the library.
9 |
10 | Download
11 | --------
12 | Download from here https://github.com/mrzl/LeapMotionP5/archive/master.zip extract the folder in the archive into your processing libraries folder and rename it from LeapMotionP5-master to LeapMotionP5. After that restart Processing and the library should be included. Check the examples within the library.
13 |
14 |
15 | Examples
16 | --------
17 | #### Basic Example
18 |
19 | import com.onformative.leap.LeapMotionP5;
20 | import com.leapmotion.leap.Finger;
21 |
22 | LeapMotionP5 leap;
23 |
24 | public void setup() {
25 | size(500, 500);
26 | leap = new LeapMotionP5(this);
27 | }
28 |
29 | public void draw() {
30 | background(0);
31 | fill(255);
32 | for (Finger finger : leap.getFingerList()) {
33 | PVector fingerPos = leap.getTip(finger);
34 | ellipse(fingerPos.x, fingerPos.y, 10, 10);
35 | }
36 | }
37 |
38 | public void stop() {
39 | leap.stop();
40 | }
41 |
42 |
43 | #### Gesture Recognition
44 |
45 | import com.leapmotion.leap.CircleGesture;
46 | import com.leapmotion.leap.Gesture.State;
47 | import com.leapmotion.leap.Gesture.Type;
48 | import com.leapmotion.leap.Hand;
49 | import com.leapmotion.leap.KeyTapGesture;
50 | import com.leapmotion.leap.ScreenTapGesture;
51 | import com.leapmotion.leap.SwipeGesture;
52 | import com.onformative.leap.LeapMotionP5;
53 |
54 | LeapMotionP5 leap;
55 | String lastGesture =
56 | "enabling gestures: \n'c' for CircleGesture\n's' for SwipeGesture\n'k' for KeyTapGesture\n't' for ScreenTapGesture";
57 |
58 | public void setup() {
59 | size(500, 500);
60 | textSize(17);
61 |
62 | leap = new LeapMotionP5(this);
63 | }
64 |
65 | public void draw() {
66 | background(0);
67 | for (Hand hand : leap.getHandList()) {
68 | PVector handPos = leap.getPosition(hand);
69 | ellipse(handPos.x, handPos.y, 20, 20);
70 | }
71 | text(lastGesture, 30, 30);
72 | }
73 |
74 | public void circleGestureRecognized(CircleGesture gesture, String clockwiseness) {
75 | if (gesture.state() == State.STATE_STOP) {
76 | System.out.println("//////////////////////////////////////");
77 | System.out.println("Gesture type: " + gesture.type().toString());
78 | System.out.println("ID: " + gesture.id());
79 | System.out.println("Radius: " + gesture.radius());
80 | System.out.println("Normal: " + gesture.normal());
81 | System.out.println("Clockwiseness: " + clockwiseness);
82 | System.out.println("Turns: " + gesture.progress());
83 | System.out.println("Center: " + leap.convertVectorToPVector(gesture.center()));
84 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
85 | System.out.println("//////////////////////////////////////");
86 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
87 | lastGesture += "ID: " + gesture.id() + "\n";
88 | lastGesture += "Radius: " + gesture.radius() + "\n";
89 | lastGesture += "Normal: " + gesture.normal() + "\n";
90 | lastGesture += "Clockwiseness: " + clockwiseness + "\n";
91 | lastGesture += "Turns: " + gesture.progress() + "\n";
92 | lastGesture += "Center: " + leap.convertVectorToPVector(gesture.center()) + "\n";
93 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
94 | }
95 | else if (gesture.state() == State.STATE_START) {
96 | }
97 | else if (gesture.state() == State.STATE_UPDATE) {
98 | }
99 | }
100 |
101 | public void swipeGestureRecognized(SwipeGesture gesture) {
102 | if (gesture.state() == State.STATE_STOP) {
103 | System.out.println("//////////////////////////////////////");
104 | System.out.println("Gesture type: " + gesture.type());
105 | System.out.println("ID: " + gesture.id());
106 | System.out.println("Position: " + leap.convertVectorToPVector(gesture.position()));
107 | System.out.println("Direction: " + gesture.direction());
108 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
109 | System.out.println("Speed: " + gesture.speed());
110 | System.out.println("//////////////////////////////////////");
111 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
112 | lastGesture += "ID: " + gesture.id() + "\n";
113 | lastGesture += "Position: " + leap.convertVectorToPVector(gesture.position()) + "\n";
114 | lastGesture += "Direction: " + gesture.direction() + "\n";
115 | lastGesture += "Speed: " + gesture.speed() + "\n";
116 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
117 | }
118 | else if (gesture.state() == State.STATE_START) {
119 | }
120 | else if (gesture.state() == State.STATE_UPDATE) {
121 | }
122 | }
123 |
124 | public void screenTapGestureRecognized(ScreenTapGesture gesture) {
125 | if (gesture.state() == State.STATE_STOP) {
126 | System.out.println("//////////////////////////////////////");
127 | System.out.println("Gesture type: " + gesture.type());
128 | System.out.println("ID: " + gesture.id());
129 | System.out.println("Position: " + leap.convertVectorToPVector(gesture.position()));
130 | System.out.println("Direction: " + gesture.direction());
131 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
132 | System.out.println("//////////////////////////////////////");
133 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
134 | lastGesture += "ID: " + gesture.id() + "\n";
135 | lastGesture += "Position: " + leap.convertVectorToPVector(gesture.position()) + "\n";
136 | lastGesture += "Direction: " + gesture.direction() + "\n";
137 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
138 | }
139 | else if (gesture.state() == State.STATE_START) {
140 | }
141 | else if (gesture.state() == State.STATE_UPDATE) {
142 | }
143 | }
144 |
145 | public void KeyTapGestureRecognized(KeyTapGesture gesture) {
146 | if (gesture.state() == State.STATE_STOP) {
147 | System.out.println("//////////////////////////////////////");
148 | System.out.println("Gesture type: " + gesture.type());
149 | System.out.println("ID: " + gesture.id());
150 | System.out.println("Position: " + leap.convertVectorToPVector(gesture.position()));
151 | System.out.println("Direction: " + gesture.direction());
152 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
153 | System.out.println("//////////////////////////////////////");
154 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
155 | lastGesture += "ID: " + gesture.id() + "\n";
156 | lastGesture += "Position: " + leap.convertVectorToPVector(gesture.position()) + "\n";
157 | lastGesture += "Direction: " + gesture.direction() + "\n";
158 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
159 | }
160 | else if (gesture.state() == State.STATE_START) {
161 | }
162 | else if (gesture.state() == State.STATE_UPDATE) {
163 | }
164 | }
165 |
166 | public void keyPressed() {
167 | if (key == 'c') {
168 | if (leap.isEnabled(Type.TYPE_CIRCLE)) {
169 | leap.disableGesture(Type.TYPE_CIRCLE);
170 | lastGesture = "Circle Gesture disabled.";
171 | }
172 | else {
173 | leap.enableGesture(Type.TYPE_CIRCLE);
174 | lastGesture = "Circle Gesture enabled.";
175 | }
176 | }
177 |
178 | if (key == 's') {
179 | if (leap.isEnabled(Type.TYPE_SWIPE)) {
180 | leap.disableGesture(Type.TYPE_SWIPE);
181 | lastGesture = "Swipe Gesture disabled.";
182 | }
183 | else {
184 | leap.enableGesture(Type.TYPE_SWIPE);
185 | lastGesture = "Swipe Gesture enabled.";
186 | }
187 | }
188 |
189 | if (key == 'k') {
190 | if (leap.isEnabled(Type.TYPE_KEY_TAP)) {
191 | leap.disableGesture(Type.TYPE_KEY_TAP);
192 | lastGesture = "KeyTap Gesture disabled.";
193 | }
194 | else {
195 | leap.enableGesture(Type.TYPE_KEY_TAP);
196 | lastGesture = "KeyTap Gesture enabled.";
197 | }
198 | }
199 |
200 | if (key == 't') {
201 | if (leap.isEnabled(Type.TYPE_SCREEN_TAP)) {
202 | leap.disableGesture(Type.TYPE_SCREEN_TAP);
203 | lastGesture = "ScreenTap Gesture disabled. ";
204 | }
205 | else {
206 | leap.enableGesture(Type.TYPE_SCREEN_TAP);
207 | lastGesture = "ScreenTap Gesture enabled. ";
208 | }
209 | }
210 | }
211 | public void stop() {
212 | leap.stop();
213 | }
214 |
215 |
216 |
217 |
218 | License
219 | -------
220 |
221 | LeapMotionP5 library for Processing.
222 | Copyright (c) 2012-2013 held jointly by the individual authors.
223 |
224 | LeapMotionP5 library for Processing is free software: you can redistribute it and/or
225 | modify it under the terms of the GNU General Public License as published by
226 | the Free Software Foundation, either version 3 of the License, or
227 | (at your option) any later version.
228 |
229 | LeapMotionP5 library for Processing is distributed in the hope that it will be
230 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
231 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
232 | GNU General Public License for more details.
233 |
234 | You should have received a copy of the GNU General Public License
235 | along with LeapMotionP5 library for Processing. If not, see http://www.gnu.org/licenses/.
236 |
237 |
238 |
239 | Leap Developer SDK.
240 | Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.
241 |
242 | NOTICE: This developer release of Leap Motion, Inc. software is confidential
243 | and intended for very limited distribution. Parties using this software must
244 | accept the SDK Agreement prior to obtaining this software and related tools.
245 | This software is subject to copyright.
246 |
247 |
--------------------------------------------------------------------------------
/examples/active_fingers/active_fingers.pde:
--------------------------------------------------------------------------------
1 | import com.onformative.leap.LeapMotionP5;
2 | import com.leapmotion.leap.Finger;
3 |
4 | LeapMotionP5 leap;
5 |
6 | public void setup() {
7 | size(500, 500);
8 | leap = new LeapMotionP5(this);
9 | }
10 |
11 | public void draw() {
12 | background(0);
13 | fill(255);
14 | for (Finger finger : leap.getFingerList()) {
15 | PVector fingerPos = leap.getTip(finger);
16 | ellipse(fingerPos.x, fingerPos.y, 10, 10);
17 | }
18 | }
19 |
20 | public void stop() {
21 | leap.stop();
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/examples/finger_to_pvector/finger_to_pvector.pde:
--------------------------------------------------------------------------------
1 | import com.onformative.leap.LeapMotionP5;
2 |
3 | LeapMotionP5 leap;
4 |
5 | void setup() {
6 | size(500, 500);
7 | leap = new LeapMotionP5(this);
8 | }
9 |
10 | void draw() {
11 | background(0);
12 | PVector fingerPos = leap.getTip(leap.getFinger(0));
13 | ellipse(fingerPos.x, fingerPos.y, 20, 20);
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/examples/gesture_recognition/gesture_recognition.pde:
--------------------------------------------------------------------------------
1 | import com.leapmotion.leap.CircleGesture;
2 | import com.leapmotion.leap.Gesture.State;
3 | import com.leapmotion.leap.Gesture.Type;
4 | import com.leapmotion.leap.Hand;
5 | import com.leapmotion.leap.KeyTapGesture;
6 | import com.leapmotion.leap.ScreenTapGesture;
7 | import com.leapmotion.leap.SwipeGesture;
8 | import com.onformative.leap.LeapMotionP5;
9 |
10 | LeapMotionP5 leap;
11 | String lastGesture =
12 | "enabling gestures: \n'c' for CircleGesture\n's' for SwipeGesture\n'k' for KeyTapGesture\n't' for ScreenTapGesture";
13 |
14 | public void setup() {
15 | size(500, 500);
16 | textSize(17);
17 |
18 | leap = new LeapMotionP5(this);
19 | }
20 |
21 | public void draw() {
22 | background(0);
23 | for (Hand hand : leap.getHandList()) {
24 | PVector handPos = leap.getPosition(hand);
25 | ellipse(handPos.x, handPos.y, 20, 20);
26 | }
27 | text(lastGesture, 30, 30);
28 | }
29 |
30 | public void circleGestureRecognized(CircleGesture gesture, String clockwiseness) {
31 | if (gesture.state() == State.STATE_STOP) {
32 | System.out.println("//////////////////////////////////////");
33 | System.out.println("Gesture type: " + gesture.type().toString());
34 | System.out.println("ID: " + gesture.id());
35 | System.out.println("Radius: " + gesture.radius());
36 | System.out.println("Normal: " + gesture.normal());
37 | System.out.println("Clockwiseness: " + clockwiseness);
38 | System.out.println("Turns: " + gesture.progress());
39 | System.out.println("Center: " + leap.vectorToPVector(gesture.center()));
40 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
41 | System.out.println("//////////////////////////////////////");
42 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
43 | lastGesture += "ID: " + gesture.id() + "\n";
44 | lastGesture += "Radius: " + gesture.radius() + "\n";
45 | lastGesture += "Normal: " + gesture.normal() + "\n";
46 | lastGesture += "Clockwiseness: " + clockwiseness + "\n";
47 | lastGesture += "Turns: " + gesture.progress() + "\n";
48 | lastGesture += "Center: " + leap.vectorToPVector(gesture.center()) + "\n";
49 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
50 | }
51 | else if (gesture.state() == State.STATE_START) {
52 | }
53 | else if (gesture.state() == State.STATE_UPDATE) {
54 | }
55 | }
56 |
57 | public void swipeGestureRecognized(SwipeGesture gesture) {
58 | if (gesture.state() == State.STATE_STOP) {
59 | System.out.println("//////////////////////////////////////");
60 | System.out.println("Gesture type: " + gesture.type());
61 | System.out.println("ID: " + gesture.id());
62 | System.out.println("Position: " + leap.vectorToPVector(gesture.position()));
63 | System.out.println("Direction: " + gesture.direction());
64 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
65 | System.out.println("Speed: " + gesture.speed());
66 | System.out.println("//////////////////////////////////////");
67 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
68 | lastGesture += "ID: " + gesture.id() + "\n";
69 | lastGesture += "Position: " + leap.vectorToPVector(gesture.position()) + "\n";
70 | lastGesture += "Direction: " + gesture.direction() + "\n";
71 | lastGesture += "Speed: " + gesture.speed() + "\n";
72 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
73 | }
74 | else if (gesture.state() == State.STATE_START) {
75 | }
76 | else if (gesture.state() == State.STATE_UPDATE) {
77 | }
78 | }
79 |
80 | public void screenTapGestureRecognized(ScreenTapGesture gesture) {
81 | if (gesture.state() == State.STATE_STOP) {
82 | System.out.println("//////////////////////////////////////");
83 | System.out.println("Gesture type: " + gesture.type());
84 | System.out.println("ID: " + gesture.id());
85 | System.out.println("Position: " + leap.vectorToPVector(gesture.position()));
86 | System.out.println("Direction: " + gesture.direction());
87 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
88 | System.out.println("//////////////////////////////////////");
89 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
90 | lastGesture += "ID: " + gesture.id() + "\n";
91 | lastGesture += "Position: " + leap.vectorToPVector(gesture.position()) + "\n";
92 | lastGesture += "Direction: " + gesture.direction() + "\n";
93 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
94 | }
95 | else if (gesture.state() == State.STATE_START) {
96 | }
97 | else if (gesture.state() == State.STATE_UPDATE) {
98 | }
99 | }
100 |
101 | public void KeyTapGestureRecognized(KeyTapGesture gesture) {
102 | if (gesture.state() == State.STATE_STOP) {
103 | System.out.println("//////////////////////////////////////");
104 | System.out.println("Gesture type: " + gesture.type());
105 | System.out.println("ID: " + gesture.id());
106 | System.out.println("Position: " + leap.vectorToPVector(gesture.position()));
107 | System.out.println("Direction: " + gesture.direction());
108 | System.out.println("Duration: " + gesture.durationSeconds() + "s");
109 | System.out.println("//////////////////////////////////////");
110 | lastGesture = "Gesture type: " + gesture.type().toString() + "\n";
111 | lastGesture += "ID: " + gesture.id() + "\n";
112 | lastGesture += "Position: " + leap.vectorToPVector(gesture.position()) + "\n";
113 | lastGesture += "Direction: " + gesture.direction() + "\n";
114 | lastGesture += "Duration: " + gesture.durationSeconds() + "s" + "\n";
115 | }
116 | else if (gesture.state() == State.STATE_START) {
117 | }
118 | else if (gesture.state() == State.STATE_UPDATE) {
119 | }
120 | }
121 |
122 | public void keyPressed() {
123 | if (key == 'c') {
124 | if (leap.isEnabled(Type.TYPE_CIRCLE)) {
125 | leap.disableGesture(Type.TYPE_CIRCLE);
126 | lastGesture = "Circle Gesture disabled.";
127 | }
128 | else {
129 | leap.enableGesture(Type.TYPE_CIRCLE);
130 | lastGesture = "Circle Gesture enabled.";
131 | }
132 | }
133 |
134 | if (key == 's') {
135 | if (leap.isEnabled(Type.TYPE_SWIPE)) {
136 | leap.disableGesture(Type.TYPE_SWIPE);
137 | lastGesture = "Swipe Gesture disabled.";
138 | }
139 | else {
140 | leap.enableGesture(Type.TYPE_SWIPE);
141 | lastGesture = "Swipe Gesture enabled.";
142 | }
143 | }
144 |
145 | if (key == 'k') {
146 | if (leap.isEnabled(Type.TYPE_KEY_TAP)) {
147 | leap.disableGesture(Type.TYPE_KEY_TAP);
148 | lastGesture = "KeyTap Gesture disabled.";
149 | }
150 | else {
151 | leap.enableGesture(Type.TYPE_KEY_TAP);
152 | lastGesture = "KeyTap Gesture enabled.";
153 | }
154 | }
155 |
156 | if (key == 't') {
157 | if (leap.isEnabled(Type.TYPE_SCREEN_TAP)) {
158 | leap.disableGesture(Type.TYPE_SCREEN_TAP);
159 | lastGesture = "ScreenTap Gesture disabled. ";
160 | }
161 | else {
162 | leap.enableGesture(Type.TYPE_SCREEN_TAP);
163 | lastGesture = "ScreenTap Gesture enabled. ";
164 | }
165 | }
166 | }
167 | public void stop() {
168 | leap.stop();
169 | }
170 |
171 |
--------------------------------------------------------------------------------
/examples/lowlevel_access/lowlevel_access.pde:
--------------------------------------------------------------------------------
1 | import com.onformative.leap.LeapMotionP5;
2 |
3 | LeapMotionP5 leap;
4 |
5 | public void setup() {
6 | size(500, 500);
7 | leap = new LeapMotionP5(this);
8 | }
9 |
10 | public void draw() {
11 | com.leapmotion.leap.Frame frame = leap.getFrame();
12 | // do some processing of the frame
13 | // this is the same frame you'd get if you would use the callback
14 | }
15 |
16 | public void stop() {
17 | leap.stop();
18 | }
19 |
--------------------------------------------------------------------------------
/examples/lowlevel_access_multiple_frames/lowlevel_access_multiple_frames.pde:
--------------------------------------------------------------------------------
1 | import com.onformative.leap.LeapMotionP5;
2 |
3 | LeapMotionP5 leap;
4 |
5 | public void setup() {
6 | size(500, 500);
7 | leap = new LeapMotionP5(this);
8 | }
9 |
10 | public void draw() {
11 | for (com.leapmotion.leap.Frame frame : leap.getFrames(200)) {
12 | // do something with the last 250 frames
13 | }
14 | }
15 |
16 | public void stop() {
17 | leap.stop();
18 | }
19 |
--------------------------------------------------------------------------------
/examples/screen_calibration/screen_calibration.pde:
--------------------------------------------------------------------------------
1 | import com.leapmotion.leap.Finger;
2 | import com.onformative.leap.LeapMotionP5;
3 |
4 | LeapMotionP5 leap;
5 |
6 | /**
7 | * this example shows how to use the screen calibration utility in processing.
8 | * in order to use this example you have to have your leap calibrated to your
9 | * screen. this will show you the intersection points between the extension of
10 | * your fingertips and your screen.
11 | * TIP: try moving the sketch window while you are pointing at your screen
12 | */
13 | public void setup() {
14 | size(1000, 700, P3D);
15 |
16 | leap = new LeapMotionP5(this);
17 | fill(255);
18 | }
19 |
20 | public void draw() {
21 | background(0);
22 | for (Finger f : leap.getFingerList()) {
23 | PVector screenPos = leap.getTipOnScreen(f);
24 | ellipse(screenPos.x, screenPos.y, 10, 10);
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/examples/velocity_graph/velocity_graph.pde:
--------------------------------------------------------------------------------
1 | import com.onformative.leap.LeapMotionP5;
2 | import java.util.*;
3 |
4 | LeapMotionP5 leap;
5 | LinkedList values;
6 |
7 | public void setup() {
8 | size(800, 300);
9 | frameRate(120);
10 | leap = new LeapMotionP5(this);
11 | values = new LinkedList();
12 | stroke(255);
13 | }
14 |
15 | int lastY = 0;
16 |
17 | public void draw() {
18 | translate(0, 180);
19 | background(0);
20 | if (values.size() >= width) {
21 | values.removeFirst();
22 | }
23 |
24 | values.add((int) leap.getVelocity(leap.getHand(0)).y);
25 | //System.out.println((int) leap.getVelocity(leap.getHand(0)).y);
26 | int counter = 0;
27 | for (Integer val : values) {
28 | val = (int) map(val, 0, 1500, 0, height);
29 | line(counter, val, counter - 1, lastY);
30 | point(counter, val);
31 | lastY = val;
32 | counter++;
33 | }
34 |
35 | line(0, map(1300, 0, 1500, 0, height), width, map(1300, 0, 1500, 0, height));
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | # UTF-8 supported.
2 |
3 | # The name of your library as you want it formatted
4 | name = LeapMotionP5
5 |
6 | # List of authors. Links can be provided using the syntax [author name](url)
7 | authorList = [Marcel Schwittlick] (https://github.com/mrzl) [onformative](http://www.onformative.com/)
8 |
9 | # A web page for your library, NOT a direct link to where to download it
10 | url = http://www.onformative.com/lab/leapmotionp5
11 |
12 | # The category of your library, must be one (or many) of the following:
13 | # "3D" "Animation" "Compilations" "Data"
14 | # "Fabrication" "Geometry" "GUI" "Hardware"
15 | # "I/O" "Language" "Math" "Simulation"
16 | # "Sound" "Utilities" "Typography" "Video & Vision"
17 | #
18 | # If a value other than those listed is used, your library will listed as "Other."
19 | category = Hardware
20 |
21 | # A short sentence (or fragment) to summarize the library's function. This will be
22 | # shown from inside the PDE when the library is being installed. Avoid repeating
23 | # the name of your library here. Also, avoid saying anything redundant like
24 | # mentioning that its a library. This should start with a capitalized letter, and
25 | # end with a period.
26 | sentence = Easy access library for the Leap Motion controller
27 |
28 | # Additional information suitable for the Processing website. The value of
29 | # 'sentence' always will be prepended, so you should start by writing the
30 | # second sentence here. If your library only works on certain operating systems,
31 | # mention it here.
32 | paragraph =
33 |
34 | # Links in the 'sentence' and 'paragraph' attributes can be inserted using the
35 | # same syntax as for authors. That is, [here is a link to Processing](http://processing.org/)
36 |
37 |
38 | # A version number that increments once with each release. This
39 | # is used to compare different versions of the same library, and
40 | # check if an update is available. You should think of it as a
41 | # counter, counting the total number of releases you've had.
42 | version = 1 # This must be parsable as an int
43 |
44 | # The version as the user will see it. If blank, the version attribute will be used here
45 | prettyVersion = 0.5b # This is treated as a String
--------------------------------------------------------------------------------
/library/LeapJava.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/LeapJava.jar
--------------------------------------------------------------------------------
/library/LeapMotionP5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/LeapMotionP5.jar
--------------------------------------------------------------------------------
/library/macosx/libLeap.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/macosx/libLeap.dylib
--------------------------------------------------------------------------------
/library/macosx/libLeapJava.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/macosx/libLeapJava.dylib
--------------------------------------------------------------------------------
/library/windows/Leap.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/windows/Leap.dll
--------------------------------------------------------------------------------
/library/windows/LeapJava.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/windows/LeapJava.dll
--------------------------------------------------------------------------------
/library/windows64/Leap.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/windows64/Leap.dll
--------------------------------------------------------------------------------
/library/windows64/LeapJava.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onformative/LeapMotionP5/70d2926806a62462039073af565160b8a634df7e/library/windows64/LeapJava.dll
--------------------------------------------------------------------------------
/src/com/onformative/leap/LeapMotionListener.java:
--------------------------------------------------------------------------------
1 | package com.onformative.leap;
2 |
3 | /**
4 | * LeapMotionP5
5 | *
6 | * LeapMotionP5 library for Processing. Copyright (c) 2012-2013 held jointly by the individual
7 | * authors.
8 | *
9 | * LeapMotionP5 library for Processing is free software: you can redistribute it and/or modify it
10 | * under the terms of the GNU General Public License as published by the Free Software Foundation,
11 | * either version 3 of the License, or (at your option) any later version.
12 | *
13 | * LeapMotionP5 for Processing is distributed in the hope that it will be useful, but WITHOUT ANY
14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 | * PURPOSE. See the GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License along with LeapMotionP5 library
18 | * for Processing. If not, see http://www.gnu.org/licenses/.
19 | *
20 | * Leap Developer SDK. Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.
21 | *
22 | * NOTICE: This developer release of Leap Motion, Inc. software is confidential and intended for
23 | * very limited distribution. Parties using this software must accept the SDK Agreement prior to
24 | * obtaining this software and related tools. This software is subject to copyright.
25 | */
26 |
27 | import java.util.Date;
28 | import java.util.LinkedList;
29 | import java.util.concurrent.ConcurrentSkipListMap;
30 | import java.util.concurrent.CopyOnWriteArrayList;
31 |
32 | import processing.core.PApplet;
33 |
34 | import com.leapmotion.leap.CircleGesture;
35 | import com.leapmotion.leap.Controller;
36 | import com.leapmotion.leap.Frame;
37 | import com.leapmotion.leap.Gesture;
38 | import com.leapmotion.leap.Gesture.State;
39 | import com.leapmotion.leap.GestureList;
40 | import com.leapmotion.leap.KeyTapGesture;
41 | import com.leapmotion.leap.Listener;
42 | import com.leapmotion.leap.ScreenTapGesture;
43 | import com.leapmotion.leap.SwipeGesture;
44 |
45 | /**
46 | * LeapMotionListener.java
47 | *
48 | * @author Marcel Schwittlick
49 | * @modified 04.02.2013
50 | *
51 | * this listener is listening for the events of the offical leap motion sdk
52 | */
53 | class LeapMotionListener extends Listener {
54 | private LeapMotionP5 leap;
55 |
56 | protected int maxFramesToRecord = 1000;
57 | private String callbackMethodNameCircle;
58 | private String callbackMethodNameSwipe;
59 | private String callbackMethodNameScreenTap;
60 | private String callbackMethodNameKeyTap;
61 |
62 | /**
63 | *
64 | * @param p PApplet the processing applet
65 | * @param leap LeapMotionP5 an instance of the LeapMotionP5 class
66 | */
67 | public LeapMotionListener(LeapMotionP5 leap) {
68 | this.leap = leap;
69 | this.leap.currentFrame = new Frame();
70 | this.leap.lastFrames = new LinkedList();
71 | this.leap.lastFramesInclProperTimestamps = new ConcurrentSkipListMap();
72 | this.leap.oldFrames = new CopyOnWriteArrayList();
73 | this.leap.oldControllers = new LinkedList();
74 |
75 | this.callbackMethodNameCircle = "circleGestureRecognized";
76 | this.callbackMethodNameSwipe = "swipeGestureRecognized";
77 | this.callbackMethodNameScreenTap = "screenTapGestureRecognized";
78 | this.callbackMethodNameKeyTap = "keyTapGestureRecognized";
79 | }
80 |
81 | public void onInit(Controller controller) {
82 | System.out.println("Leap Motion Initialized");
83 | }
84 |
85 | public void onConnect(Controller controller) {
86 | System.out.println("Leap Motion Connected");
87 | }
88 |
89 | public void onDisconnect(Controller controller) {
90 | System.out.println("Leap Motion Disconnected");
91 | }
92 |
93 | public void onExit(Controller controller) {
94 | System.out.println("Leap Motion Exited");
95 | }
96 |
97 | private void invokeCallback(Gesture gesture) {
98 | PApplet parent = this.leap.getParent();
99 |
100 | if (parent != null) {
101 | switch (gesture.type()) {
102 | case TYPE_CIRCLE:
103 | CircleGesture circleGesture = new CircleGesture(gesture);
104 | String clockwiseness;
105 | if (circleGesture.pointable().direction().angleTo(circleGesture.normal()) <= Math.PI / 4) {
106 | // Clockwise if angle is less than 90 degrees
107 | clockwiseness = "clockwise";
108 | } else {
109 | clockwiseness = "counterclockwise";
110 | }
111 | try {
112 | parent.getClass()
113 | .getMethod(this.callbackMethodNameCircle, CircleGesture.class, String.class)
114 | .invoke(parent, circleGesture, clockwiseness);
115 | } catch (Exception e) {
116 | PApplet.println(e.getMessage() + " CALLBACK ERROR");
117 | }
118 | break;
119 | case TYPE_SWIPE:
120 | SwipeGesture swipeGesture = new SwipeGesture(gesture);
121 | try {
122 | parent.getClass().getMethod(this.callbackMethodNameSwipe, SwipeGesture.class)
123 | .invoke(parent, swipeGesture);
124 | } catch (Exception e) {
125 | PApplet.println(e.getMessage() + " CALLBACK ERROR");
126 | }
127 | break;
128 | case TYPE_SCREEN_TAP:
129 | ScreenTapGesture screenTapGesture = new ScreenTapGesture(gesture);
130 | try {
131 | parent.getClass().getMethod(this.callbackMethodNameScreenTap, ScreenTapGesture.class)
132 | .invoke(parent, screenTapGesture);
133 | } catch (Exception e) {
134 | PApplet.println(e.getMessage() + " CALLBACK ERROR");
135 | }
136 | break;
137 | case TYPE_KEY_TAP:
138 | KeyTapGesture keyTapGesture = new KeyTapGesture(gesture);
139 | try {
140 | parent.getClass().getMethod(this.callbackMethodNameKeyTap, KeyTapGesture.class)
141 | .invoke(parent, keyTapGesture);
142 | } catch (Exception e) {
143 | PApplet.println(e.getMessage() + " CALLBACK ERROR");
144 | }
145 | break;
146 | default:
147 | break;
148 | }
149 | }
150 |
151 |
152 | }
153 |
154 | private void printGestureDetails(Gesture gesture, Controller controller) {
155 | switch (gesture.type()) {
156 | case TYPE_CIRCLE:
157 | CircleGesture circle = new CircleGesture(gesture);
158 |
159 | // Calculate clock direction using the angle between circle normal and pointable
160 | String clockwiseness;
161 | if (circle.pointable().direction().angleTo(circle.normal()) <= Math.PI / 4) {
162 | // Clockwise if angle is less than 90 degrees
163 | clockwiseness = "clockwise";
164 | } else {
165 | clockwiseness = "counterclockwise";
166 | }
167 |
168 | // Calculate angle swept since last frame
169 | double sweptAngle = 0;
170 | if (circle.state() != State.STATE_START) {
171 | CircleGesture previousUpdate =
172 | new CircleGesture(controller.frame(1).gesture(circle.id()));
173 | sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * Math.PI;
174 | }
175 |
176 | System.out.println("Circle id: " + circle.id() + ", " + circle.state() + ", progress: "
177 | + circle.progress() + ", radius: " + circle.radius() + ", angle: "
178 | + Math.toDegrees(sweptAngle) + ", " + clockwiseness);
179 | break;
180 | case TYPE_SWIPE:
181 | SwipeGesture swipe = new SwipeGesture(gesture);
182 | System.out.println("Swipe id: " + swipe.id() + ", " + swipe.state() + ", position: "
183 | + swipe.position() + ", direction: " + swipe.direction() + ", speed: " + swipe.speed());
184 | break;
185 | case TYPE_SCREEN_TAP:
186 | ScreenTapGesture screenTap = new ScreenTapGesture(gesture);
187 | System.out.println("Screen Tap id: " + screenTap.id() + ", " + screenTap.state()
188 | + ", position: " + screenTap.position() + ", direction: " + screenTap.direction());
189 | break;
190 | case TYPE_KEY_TAP:
191 | KeyTapGesture keyTap = new KeyTapGesture(gesture);
192 | System.out.println("Key Tap id: " + keyTap.id() + ", " + keyTap.state() + ", position: "
193 | + keyTap.position() + ", direction: " + keyTap.direction());
194 | break;
195 | default:
196 | System.out.println("Unknown gesture type.");
197 | break;
198 | }
199 |
200 | }
201 |
202 | private void processGestures(Controller controller) {
203 | GestureList list = controller.frame().gestures();
204 | if (list.empty() == false) {
205 | for (int i = 0; i < list.count(); i++) {
206 | Gesture gesture = list.get(i);
207 | invokeCallback(gesture);
208 | // printGestureDetails(gesture, controller);
209 | }
210 | }
211 | }
212 |
213 | /**
214 | * this is called about 100-120 times a second delevering a new frame with information from the
215 | * leap tracking everything in its viewport. This is where most of the data which is accessible in
216 | * processing is coming from
217 | */
218 | public void onFrame(Controller controller) {
219 | Frame frame = controller.frame();
220 | this.leap.currentFrame = frame;
221 |
222 | processGestures(controller);
223 |
224 | // adding frames the list. making sure that only the newest frames are saved in order
225 | if (leap.lastFrames.size() >= maxFramesToRecord) {
226 | leap.lastFrames.removeFirst();
227 | }
228 | leap.lastFrames.add(frame);
229 |
230 | // adding frames to the list. adding a proper timestamp to each frame object
231 | if (leap.lastFramesInclProperTimestamps.size() >= maxFramesToRecord) {
232 | leap.lastFramesInclProperTimestamps.remove(leap.lastFramesInclProperTimestamps.firstKey());
233 | }
234 | leap.lastFramesInclProperTimestamps.put(new Date(), frame);
235 |
236 | // adding old frames to different object
237 | if (leap.oldFrames.size() >= maxFramesToRecord) {
238 | leap.oldFrames.remove(0);
239 | }
240 | leap.oldFrames.add(frame);
241 |
242 | if (leap.oldControllers.size() >= maxFramesToRecord) {
243 | leap.oldControllers.removeLast();
244 | }
245 | leap.oldControllers.add(controller);
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/src/com/onformative/leap/LeapMotionP5.java:
--------------------------------------------------------------------------------
1 | package com.onformative.leap;
2 |
3 | /**
4 | * LeapMotionP5
5 | *
6 | * LeapMotionP5 library for Processing. Copyright (c) 2012-2013 held jointly by the individual
7 | * authors.
8 | *
9 | * LeapMotionP5 library for Processing is free software: you can redistribute it and/or modify it
10 | * under the terms of the GNU General Public License as published by the Free Software Foundation,
11 | * either version 3 of the License, or (at your option) any later version.
12 | *
13 | * LeapMotionP5 for Processing is distributed in the hope that it will be useful, but WITHOUT ANY
14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 | * PURPOSE. See the GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License along with LeapMotionP5 library
18 | * for Processing. If not, see http://www.gnu.org/licenses/.
19 | *
20 | * Leap Developer SDK. Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.
21 | *
22 | * NOTICE: This developer release of Leap Motion, Inc. software is confidential and intended for
23 | * very limited distribution. Parties using this software must accept the SDK Agreement prior to
24 | * obtaining this software and related tools. This software is subject to copyright.
25 | */
26 |
27 | import java.util.ArrayList;
28 | import java.util.Date;
29 | import java.util.HashMap;
30 | import java.util.Iterator;
31 | import java.util.LinkedList;
32 | import java.util.Map.Entry;
33 | import java.util.Set;
34 | import java.util.concurrent.ConcurrentSkipListMap;
35 | import java.util.concurrent.CopyOnWriteArrayList;
36 |
37 | import processing.core.PApplet;
38 | import processing.core.PVector;
39 |
40 | import com.leapmotion.leap.Config;
41 | import com.leapmotion.leap.Controller;
42 | import com.leapmotion.leap.Finger;
43 | import com.leapmotion.leap.Frame;
44 | import com.leapmotion.leap.Gesture.Type;
45 | import com.leapmotion.leap.Hand;
46 | import com.leapmotion.leap.Pointable;
47 | import com.leapmotion.leap.ScreenList;
48 | import com.leapmotion.leap.Tool;
49 | import com.leapmotion.leap.Vector;
50 |
51 | /**
52 | * LeapMotionP5.java
53 | *
54 | * @author Marcel Schwittlick
55 | * @modified 15.03.2013
56 | *
57 | */
58 | public class LeapMotionP5 {
59 | private PApplet p;
60 | private LeapMotionListener listener;
61 | private Controller controller;
62 | private String sdkVersion = "0.7.7";
63 |
64 | private final float LEAP_WIDTH = 200.0f; // in mm
65 | private final float LEAP_HEIGHT = 500.0f; // in mm
66 | private final float LEAP_DEPTH = 200.0f; // in mm
67 |
68 | protected Frame currentFrame;
69 | protected LinkedList lastFrames;
70 | protected CopyOnWriteArrayList oldFrames;
71 | protected LinkedList oldControllers;
72 | protected ConcurrentSkipListMap lastFramesInclProperTimestamps;
73 |
74 | protected HashMap lastDetectedFinger;
75 | protected HashMap lastDetectedPointable;
76 | protected HashMap lastDetectedHand;
77 | protected HashMap lastDetectedTool;
78 |
79 | private int activeScreenNr = 0;
80 |
81 | private Finger velocityOffsetTestFinger;
82 |
83 | /**
84 | * this class gives you some high level access to the data tracked and recorded by the leap. it
85 | * gives you a different way of access than the original leap sdk and transoforms all data into
86 | * processing equivalent datatypes.
87 | *
88 | * @param p PApplet the processing applet
89 | */
90 | public LeapMotionP5(PApplet p) {
91 | this.p = p;
92 |
93 | this.listener = new LeapMotionListener(this);
94 | this.controller = new Controller();
95 |
96 | this.controller.addListener(listener);
97 |
98 | this.lastDetectedFinger = new HashMap();
99 | this.lastDetectedPointable = new HashMap();
100 | this.lastDetectedHand = new HashMap();
101 | this.lastDetectedTool = new HashMap();
102 |
103 | this.lastDetectedFinger.put(0, new Finger());
104 | this.lastDetectedPointable.put(0, new Pointable());
105 | this.lastDetectedHand.put(0, new Hand());
106 | this.lastDetectedTool.put(0, new Tool());
107 |
108 | // this is neccessary because the velocity of all objects has an offset.
109 | this.velocityOffsetTestFinger = new Finger();
110 | }
111 |
112 | /**
113 | *
114 | * @return
115 | */
116 | public String getSDKVersion() {
117 | return this.sdkVersion;
118 | }
119 |
120 | /**
121 | *
122 | * @param max
123 | */
124 | public void maxFramesToRecord(int max) {
125 | this.listener.maxFramesToRecord = max;
126 | }
127 |
128 | /**
129 | * this prints out the current offset of the vectors from the sdk. this is just for information
130 | * and will give you the position, velocity and acceleration offsets
131 | */
132 | public void printCorrectionOffset() {
133 | System.out.println("pos offset: " + getTip(this.velocityOffsetTestFinger));
134 | System.out.println("velo offset: " + getVelocity(this.velocityOffsetTestFinger));
135 | System.out.println("acc offset: " + getAcceleration(this.velocityOffsetTestFinger));
136 | }
137 |
138 | /**
139 | *
140 | */
141 | public void stop() {
142 | this.controller.removeListener(this.listener);
143 | this.p.stop();
144 | }
145 |
146 | /**
147 | * this returns a pvector containing the velocity offset. the problems the velocity offset has
148 | * with it, is that the velocity is slightly shiftet. for example if you shouldnt have any
149 | * velocity, because the finger is stanging still its returning a velocity that is initialized
150 | * with a new Finger object. this should be fixed with the upcoming sdk releases (i hope) *
151 | *
152 | * @return PVector containing the velocity offset
153 | */
154 | public PVector velocityOffset() {
155 | return vectorToPVector(this.velocityOffsetTestFinger.tipVelocity());
156 | }
157 |
158 | public PVector positionOffset() {
159 | return vectorToPVector(this.velocityOffsetTestFinger.tipPosition());
160 | }
161 |
162 | /**
163 | * this retuns an pvector containing the acceleration offset, that has to be substracted from
164 | * every vector returned from the library. unfortunately the leap sdk has a little bug there.
165 | *
166 | * @return PVector containing the acceleration offset
167 | */
168 | public PVector accelerationOffset() {
169 | return getAcceleration(this.velocityOffsetTestFinger);
170 | }
171 |
172 | public void enableGesture(Type gestureName) {
173 | this.controller.enableGesture(gestureName);
174 | }
175 |
176 | public void disableGesture(Type gesture) {
177 | this.controller.enableGesture(gesture, false);
178 | }
179 |
180 | public boolean isEnabled(Type gesture) {
181 | return this.controller.isGestureEnabled(gesture);
182 | }
183 |
184 | /**
185 | * this returns the parent applet of the library - the processing applet.
186 | *
187 | * @return PApplet parent
188 | */
189 | public PApplet getParent() {
190 | return this.p;
191 | }
192 |
193 | /**
194 | * returns the controller of the leap sdk
195 | *
196 | * @return Controller controller
197 | */
198 | public Controller getController() {
199 | try {
200 | return this.controller;
201 | } catch (Exception e) {
202 | System.err
203 | .println("Can not return controller not initialized. Returning new Controller object");
204 | System.out.println(e);
205 | return new Controller();
206 | }
207 | }
208 |
209 | /**
210 | * returns the most current frame from the leap sdk. a frame contains every tracked data from the
211 | * leap about your fingers.
212 | *
213 | * @return Frame the leap frame
214 | */
215 | public Frame getFrame() {
216 | try {
217 | return this.currentFrame;
218 | } catch (Exception e) {
219 | System.err.println("Can not return current frame. Returning new Frame object instead");
220 | System.err.println(e);
221 | return new Frame();
222 | }
223 | }
224 |
225 | /**
226 | * returns a frame by id.
227 | *
228 | * @param id the id of the frame you want
229 | * @return Frame the frame which id you passed as a parameter. if the frame with the id you asked
230 | * for is not currently saved anymore you'll get a new Frame object.
231 | */
232 | public Frame getFrame(int id) {
233 | Frame returnFrame = new Frame();
234 | for (Frame frame : getFrames()) {
235 | if (frame.id() >= id) {
236 | returnFrame = frame;
237 | }
238 | }
239 | return returnFrame;
240 | }
241 |
242 | /**
243 | * returns the frame before the most current frame.
244 | *
245 | * @return
246 | */
247 | public Frame getLastFrame() {
248 | return getFrames().get(getFrames().size() - 2);
249 | }
250 |
251 | public Controller getLastController() {
252 | return getLastControllers().get(getLastControllers().size() - 40);
253 | }
254 |
255 | /**
256 | * returns the frame that was before the frame you passed.
257 | *
258 | * @param frame
259 | * @return the frame that was recorded right before the frame you passed.
260 | */
261 | public Frame getFrameBeforeFrame(Frame frame) {
262 | Frame frameBefore = null;
263 |
264 | for (Frame of : getFrames()) {
265 | if (of.id() == frame.id() - 1) {
266 | frameBefore = of;
267 | }
268 | }
269 |
270 |
271 | return frameBefore;
272 | }
273 |
274 | /**
275 | * returns a CopyOnWriteArrayList containing all recently buffered frames.
276 | *
277 | * @return a CopyOnWriteArrayList containing the newest elements
278 | */
279 | public CopyOnWriteArrayList getFrames() {
280 | try {
281 | return this.oldFrames;
282 | } catch (Exception e) {
283 | System.err.println("Can not return list of last frames. Returning empty list instead.");
284 | System.err.println(e);
285 | return new CopyOnWriteArrayList();
286 | }
287 | }
288 |
289 | public LinkedList getLastControllers() {
290 | return this.oldControllers;
291 | }
292 |
293 | /**
294 | * returns a linkedlist containing the last buffered frame
295 | *
296 | * @param frameCount the number of last frames
297 | * @return a list containing all last frames
298 | */
299 | public LinkedList getFrames(int frameCount) {
300 | LinkedList frames = new LinkedList();
301 | for (int i = 0; i < frameCount; i++) {
302 | if (getFrames().size() > frameCount) {
303 | Frame fr = getFrames().get(getFrames().size() - frameCount + i);
304 | frames.add(fr);
305 | }
306 | }
307 | return frames;
308 | }
309 |
310 | /**
311 | *
312 | * @return
313 | */
314 | public PVector getFingerPositionXYPlane() {
315 | PVector fingerPositionXYPlane = new PVector();
316 |
317 | Frame frame = getFrame();
318 | if (frame.hands().isEmpty() == false) {
319 | Hand hand = frame.hands().get(0);
320 | if (hand.fingers().isEmpty() == false) {
321 | Finger finger = hand.fingers().get(0);
322 | fingerPositionXYPlane.x = transformLeapToScreenX(finger.tipPosition().getX());
323 | fingerPositionXYPlane.y = transformLeapToScreenY(finger.tipPosition().getY());
324 | }
325 | }
326 |
327 | return fingerPositionXYPlane;
328 | }
329 |
330 | /**
331 | * converts the x coordinate from the leap space into the processing window space
332 | *
333 | * @param x leap-space
334 | * @return processing-window space
335 | */
336 | public float transformLeapToScreenX(float x) {
337 | /*
338 | * int startX = -243; int endX = 256; float valueMapped = PApplet.map(x, startX, endX, 0,
339 | * p.width); return valueMapped;
340 | */
341 | float c = this.p.width / 2.0f;
342 | if (x > 0.0) {
343 | return PApplet.lerp(c, this.p.width, x / LEAP_WIDTH);
344 | } else {
345 | return PApplet.lerp(c, 0.0f, -x / LEAP_WIDTH);
346 | }
347 | }
348 |
349 | /**
350 | * converts the y coordinate from the leap space into the processing window space
351 | *
352 | * @param y leap space
353 | * @return processing-window space
354 | */
355 | public float transformLeapToScreenY(float y) {
356 | /*
357 | * int startY = 50; int endY = 350; float valueMapped = PApplet.map(y, startY, endY, 0,
358 | * p.height); return valueMapped;
359 | */
360 | return PApplet.lerp(this.p.height, 0.0f, y / LEAP_HEIGHT);
361 | }
362 |
363 | /**
364 | * converts the z coordinate from the leap space into the processing window space
365 | *
366 | * @param z leap space
367 | * @return processing window space
368 | */
369 | public float transformLeapToScreenZ(float z) {
370 | /*
371 | * int startZ = -51; int endZ = 149; float valueMapped = PApplet.map(z, startZ, endZ, 0,
372 | * p.width); return valueMapped;
373 | */
374 | return PApplet.lerp(0, this.p.width, z / LEAP_DEPTH);
375 | }
376 |
377 | /**
378 | * converts a vector from the leap space into the processing window space
379 | *
380 | * @param vector from the leap sdk containing a position in the leap space
381 | * @return the vector in PVector data type containing the same position in processing window space
382 | */
383 | public PVector vectorToPVector(Vector vector) {
384 | return convertLeapToScreenDimension(vector.getX(), vector.getY(), vector.getZ());
385 | }
386 |
387 | /**
388 | * converts x, y and z coordinates of the leap to the dimensions of your sketch
389 | *
390 | * @param x x position in leap world coordinate system
391 | * @param y y position in leap world coordinate system
392 | * @param z z position in leap world coordinate system
393 | * @return PVector the pvector of the point you passed in converted to the dimensions of your
394 | * processing sketch window
395 | */
396 | public PVector convertLeapToScreenDimension(float x, float y, float z) {
397 | PVector positionRelativeToFrame = new PVector();
398 | positionRelativeToFrame.x = transformLeapToScreenX(x);
399 | positionRelativeToFrame.y = transformLeapToScreenY(y);
400 | positionRelativeToFrame.z = transformLeapToScreenZ(z);
401 | return positionRelativeToFrame;
402 | }
403 |
404 | /**
405 | * returns an arraylist containing all currently tracked hands
406 | *
407 | * @return ArrayList an arraylist containing all currently tracked hands
408 | */
409 | public ArrayList getHandList() {
410 | ArrayList hands = new ArrayList();
411 | Frame frame = getFrame();
412 | if (frame.hands().isEmpty() == false) {
413 | for (Hand hand : frame.hands()) {
414 | hands.add(hand);
415 | }
416 | }
417 | return hands;
418 | }
419 |
420 | /**
421 | * returns all hands tracked in the frame you passed
422 | *
423 | * @param frame the frame from which to find out all tracked hands
424 | * @return arraylist containing all hands from the passed frame
425 | */
426 | public ArrayList getHandList(Frame frame) {
427 | ArrayList hands = new ArrayList();
428 | try {
429 | if (frame.hands().isEmpty() == false) {
430 | for (Hand hand : frame.hands()) {
431 | if (hand.isValid()) {
432 | hands.add(hand);
433 | }
434 | }
435 | }
436 | } catch (Exception e) {
437 | // ignore
438 | }
439 | return hands;
440 | }
441 |
442 | /**
443 | * gets a hand by number. the number is indicated by the order the hand appeared in the leap. so
444 | * the first hand tracked has the nr 0 and the second one the number 1. once one hand of them two
445 | * leaves the leap the one hand left has the nr 0. this is implemented like that because the leap
446 | * is loosing track of the id's of hand to easily.
447 | *
448 | * @param handNr nr of the hand
449 | * @return
450 | */
451 | public Hand getHand(int handNr) {
452 | Hand returnHand = null;
453 | if (!getHandList().isEmpty()) {
454 | this.lastDetectedHand.put(handNr, getHandList().get(handNr));
455 | }
456 | // returnHand = lastDetectedHand.get(handNr);
457 | int downCounter = 0;
458 | while (returnHand == null) {
459 | returnHand = this.lastDetectedHand.get(handNr - downCounter);
460 | downCounter++;
461 | }
462 | return returnHand;
463 | }
464 |
465 | /**
466 | * returns a hand by id in the frame you passed.
467 | *
468 | * @param id
469 | * @param frame
470 | * @return
471 | */
472 | public Hand getHandById(int id, Frame frame) {
473 | Hand returnHand = null;
474 | for (Hand hand : getHandList(frame)) {
475 | if (hand.id() == id) {
476 | returnHand = hand;
477 | }
478 | }
479 | return returnHand;
480 | }
481 |
482 | /**
483 | *
484 | * @return
485 | */
486 | public float getScaleFactor() {
487 | return getFrame().scaleFactor(getLastFrame());
488 | }
489 |
490 | /**
491 | *
492 | * @return
493 | */
494 | public float getScaleFactor(Frame frame) {
495 | return getFrame().scaleFactor(frame);
496 | }
497 |
498 | /**
499 | * returns averaged translation of all points tracked by the leap in comparison to the last frame
500 | *
501 | * @return
502 | */
503 | public PVector getTranslation() {
504 | PVector translation = vectorToPVector(getFrame().translation(getLastFrame()));
505 | translation.sub(velocityOffset());
506 | return translation;
507 | }
508 |
509 | /**
510 | * returns averaged translation of all points tracked by the leap in comparison to the frame you
511 | * passed in the method
512 | *
513 | * @return
514 | */
515 | public PVector getTranslation(Frame frame) {
516 | PVector translation = vectorToPVector(getFrame().translation(frame));
517 | translation.sub(velocityOffset());
518 | return translation;
519 | }
520 |
521 | /**
522 | * returns the pitch of the hand you passed
523 | *
524 | * @param hand the hand you want the pitch of
525 | * @return a float value containing the pitch of the hand
526 | */
527 | public float getPitch(Hand hand) {
528 | // return PApplet.map((float) Math.toDegrees(hand.direction().pitch()), 0, 22, 0,
529 | // PConstants.TWO_PI);
530 | return (float) Math.toDegrees(hand.direction().pitch());
531 | }
532 |
533 | /**
534 | * returns the roll of the hand you passed
535 | *
536 | * @param hand the hand you want the roll of
537 | * @return a float value containing the roll of the hand
538 | */
539 | public float getRoll(Hand hand) {
540 | // return -PApplet.map((float) Math.toDegrees(hand.direction().roll()), 0, 180, 0,
541 | // PConstants.TWO_PI);
542 | return (float) Math.toDegrees(hand.palmNormal().roll());
543 | }
544 |
545 | /**
546 | * returns the yaw of the hand you passed
547 | *
548 | * @param hand the hand you want the yaw of
549 | * @return a float value containing the yaw of the hand
550 | */
551 | public float getYaw(Hand hand) {
552 | return (float) Math.toDegrees(hand.direction().yaw());
553 | }
554 |
555 | /**
556 | * returns a PVector containing the direction of the hand
557 | *
558 | * @param hand the hand you want the direction of
559 | * @return PVector direction of the hand
560 | */
561 | public PVector getDirection(Hand hand) {
562 |
563 | PVector dir = vectorToPVector(hand.direction());
564 | dir.sub(positionOffset());
565 | return dir;
566 | }
567 |
568 | /**
569 | * returns a PVector containing the position of the hand
570 | *
571 | * @param hand the hand you want the position of
572 | * @return PVector position of the hand
573 | */
574 | public PVector getPosition(Hand hand) {
575 | return vectorToPVector(hand.palmPosition());
576 | }
577 |
578 | /**
579 | * retrusn the normal of the palm of the hand
580 | *
581 | * @param hand the hand you want the normal of the handpalm of
582 | * @return a PVector containing the normal of thepalm of the hand
583 | */
584 | public PVector getNormal(Hand hand) {
585 | PVector normal = vectorToPVector(hand.palmNormal());
586 | normal.sub(positionOffset());
587 | return normal;
588 | }
589 |
590 | /**
591 | * returns the velocity of the palm of the hand you passed in
592 | *
593 | * @param hand the hand of which palm you want the velocity of
594 | * @return a PVector containing the velocity of the hand
595 | */
596 | public PVector getVelocity(Hand hand) {
597 | PVector velo = vectorToPVector(hand.palmVelocity());
598 | velo.sub(velocityOffset());
599 | return velo;
600 | }
601 |
602 | /**
603 | * access to the acceleration of the hand you passed in.
604 | *
605 | * @param hand the hand you want the acceleration of
606 | * @return a PVector containing the acceleration of the hand you passed in
607 | */
608 | public PVector getAcceleration(Hand hand) {
609 | PVector acceleration = null;
610 |
611 | Frame currentFrame = getFrame();
612 | Frame lastFrame = getFrameBeforeFrame(currentFrame);
613 | PVector currentVelo = new PVector();
614 | PVector lastVelo = new PVector();
615 | try {
616 | currentVelo = getVelocity(hand);
617 | lastVelo = getVelocity(getHandById(hand.id(), lastFrame));
618 | } catch (Exception e) {
619 | // ignore
620 | }
621 | currentVelo.sub(lastVelo);
622 | currentVelo.div(2);
623 | acceleration = currentVelo;
624 |
625 | return acceleration;
626 | }
627 |
628 | /**
629 | *
630 | * @param hand
631 | * @return
632 | */
633 | public PVector getSphereCenter(Hand hand) {
634 | return vectorToPVector(hand.sphereCenter());
635 | }
636 |
637 | /**
638 | *
639 | * @param hand
640 | * @return
641 | */
642 | public float getSphereRadius(Hand hand) {
643 | return hand.sphereRadius();
644 | }
645 |
646 | /**
647 | * access to all fingers that are currently tracked
648 | *
649 | * @return ArrayList an arraylist containing all currently tracked fingers
650 | */
651 | public ArrayList getFingerList() {
652 | ArrayList fingers = new ArrayList();
653 |
654 | Frame frame = getFrame();
655 | if (frame.hands().isEmpty() == false) {
656 | for (Hand hand : frame.hands()) {
657 | fingers.addAll(getFingerList(hand));
658 | }
659 | }
660 |
661 | return fingers;
662 | }
663 |
664 | /**
665 | * access to all tracked fingers in the frame you passed in
666 | *
667 | * @param frame the frame you want all tracked fingers of
668 | * @return an arraylist containing all tracked fingers
669 | */
670 | public ArrayList getFingerList(Frame frame) {
671 | ArrayList fingers = new ArrayList();
672 |
673 | if (frame.hands().isEmpty() == false) {
674 | for (Hand hand : frame.hands()) {
675 | fingers.addAll(getFingerList(hand));
676 | }
677 | }
678 |
679 | return fingers;
680 | }
681 |
682 | /**
683 | * access to all fingers of the hand you passed in
684 | *
685 | * @param hand the hand you want all tracked fingers of
686 | * @return an arraylist containing all tracked fingers of the hand
687 | */
688 | public ArrayList getFingerList(Hand hand) {
689 | ArrayList fingers = new ArrayList();
690 |
691 | for (Finger finger : hand.fingers()) {
692 | fingers.add(finger);
693 | }
694 | return fingers;
695 | }
696 |
697 | /**
698 | * returns the finger by number. the fingers are numbered by the occurence in the leap.
699 | *
700 | * @param fingerNr
701 | * @return
702 | */
703 | public Finger getFinger(int fingerNr) {
704 | Finger returnFinger = null;
705 | if (getFingerList().size() > fingerNr) {
706 | this.lastDetectedFinger.put(fingerNr, getFingerList().get(fingerNr));
707 | }
708 | // returnFinger = lastDetectedFinger.get(fingerNr);
709 | int downCounter = 0;
710 | while (returnFinger == null) {
711 | returnFinger = this.lastDetectedFinger.get(fingerNr - downCounter);
712 | downCounter++;
713 | }
714 | return returnFinger;
715 | }
716 |
717 | /**
718 | *
719 | * @param id
720 | * @param frame
721 | * @return
722 | */
723 | public Finger getFingerById(int id, Frame frame) {
724 | Finger returnFinger = null;
725 | for (Finger finger : getFingerList(frame)) {
726 | if (finger.id() == id) {
727 | returnFinger = finger;
728 | }
729 | }
730 | return returnFinger;
731 | }
732 |
733 | /**
734 | * returns the tip position of the passed pointable
735 | *
736 | * @param pointable the pointable you want the tippoisition of
737 | * @return a PVector containing the position of the tip of the pointable
738 | */
739 | public PVector getTip(Pointable pointable) {
740 | return convertLeapToScreenDimension(pointable.tipPosition().getX(), pointable.tipPosition()
741 | .getY(), pointable.tipPosition().getZ());
742 | }
743 |
744 | /**
745 | * sets the current screen for gettings the calibrated points. I should rewrite this, but nobody
746 | * is gonna read it anyway. arr.
747 | *
748 | * @param screenNr
749 | */
750 | public void setActiveScreen(int screenNr) {
751 | this.activeScreenNr = screenNr;
752 | }
753 |
754 | /**
755 | * to use this utility you have to have the leap calirated to your screen
756 | *
757 | * @param pointable the finger you want the intersection with your screen from
758 | * @param screenNr the number of the screen you calibrated
759 | * @return
760 | */
761 | public PVector getTipOnScreen(Pointable pointable) {
762 | PVector pos;
763 |
764 | ScreenList sl = this.controller.locatedScreens();
765 | com.leapmotion.leap.Screen calibratedScreen = sl.get(activeScreenNr);
766 | Vector loc = calibratedScreen.intersect(pointable, true);
767 |
768 | float _x = PApplet.map(loc.getX(), 0, 1, 0, this.p.displayWidth);
769 | _x -= p.getLocationOnScreen().x;
770 | float _y = PApplet.map(loc.getY(), 0, 1, this.p.displayHeight, 0);
771 | _y -= p.getLocationOnScreen().y;
772 |
773 | pos = new PVector(_x, _y);
774 | return pos;
775 | }
776 |
777 | /**
778 | * returns the velocity of a finger on the screen
779 | *
780 | * @param pointable
781 | * @return
782 | */
783 |
784 | public PVector getVelocityOnScreen(Pointable pointable) {
785 | Vector loc = new Vector();
786 | Vector oldLoc = new Vector();
787 | try {
788 | oldLoc =
789 | getLastController().locatedScreens().get(this.activeScreenNr)
790 | .intersect(getPointableById(pointable.id(), getLastFrame()), true);
791 | loc = this.controller.locatedScreens().get(this.activeScreenNr).intersect(pointable, true);
792 | } catch (NullPointerException e) {
793 | // dirty dirty hack to keep the programm runing. i like it.
794 | }
795 |
796 | float _x = PApplet.map(loc.getX(), 0, 1, 0, this.p.displayWidth);
797 | _x -= this.p.getLocationOnScreen().x;
798 | float _y = PApplet.map(loc.getY(), 0, 1, this.p.displayHeight, 0);
799 | _y -= this.p.getLocationOnScreen().y;
800 |
801 | float _x2 = PApplet.map(oldLoc.getX(), 0, 1, 0, this.p.displayWidth);
802 | _x2 -= this.p.getLocationOnScreen().x;
803 | float _y2 = PApplet.map(oldLoc.getY(), 0, 1, this.p.displayHeight, 0);
804 | _y2 -= this.p.getLocationOnScreen().y;
805 |
806 | return new PVector(_x - _x2, _y - _y2);
807 | }
808 |
809 | /**
810 | * returns the origin of the pointable. the origin is the place where the pointable leaves the
811 | * body of the hand.
812 | *
813 | * @param pointable the pointable you want the origin of
814 | * @return a PVector containing the position of the origin of the passed pointable
815 | */
816 | public PVector getOrigin(Pointable pointable) {
817 | Vector anklePos;
818 |
819 | float length = pointable.length();
820 | PVector direction = new PVector();
821 | direction.x = pointable.direction().getX();
822 | direction.y = pointable.direction().getY();
823 | direction.z = pointable.direction().getZ();
824 | direction.mult(length);
825 | anklePos =
826 | new Vector(pointable.tipPosition().getX() - direction.x, pointable.tipPosition().getY()
827 | - direction.y, pointable.tipPosition().getZ() - direction.z);
828 |
829 | return vectorToPVector(anklePos);
830 | }
831 |
832 | /**
833 | * returns the velocity of the pointbale
834 | *
835 | * @param pointable the pointable you want the velocity of
836 | * @return a PVector containing the velocity of the tip of the pointble
837 | */
838 | public PVector getVelocity(Pointable pointable) {
839 | PVector velo = vectorToPVector(pointable.tipVelocity());
840 | velo.sub(velocityOffset());
841 | return velo;
842 | }
843 |
844 |
845 |
846 | /**
847 | * calculates the direction of the passed pointable
848 | *
849 | * @param pointable the pointable you want the direction of
850 | * @return a PVector containing the direction of the pointable
851 | */
852 | public PVector getDirection(Pointable pointable) {
853 | return vectorToPVector(pointable.direction());
854 | }
855 |
856 | /**
857 | * passes the length of a pointable though.
858 | *
859 | * @param pointable
860 | * @return
861 | */
862 | public float getLength(Pointable pointable) {
863 | return pointable.length();
864 | }
865 |
866 | /**
867 | * passes the width of a pointable through
868 | *
869 | * @param pointable
870 | * @return
871 | */
872 | public float getWidth(Pointable pointable) {
873 | return pointable.width();
874 | }
875 |
876 | /**
877 | * calculates the acceleration of the pointable according to the velocity of the curent and the
878 | * last frame
879 | *
880 | * @param pointable the pointable you want the acceleration of
881 | * @return a PVector containing the acceleration of the tip of the passed pointable
882 | */
883 | public PVector getAcceleration(Pointable pointable) {
884 |
885 | PVector acceleration = null;
886 |
887 | Frame currentFrame = getFrame();
888 | Frame lastFrame = getFrameBeforeFrame(currentFrame);
889 | PVector currentVelo = new PVector();
890 | PVector lastVelo = new PVector();
891 | try {
892 | currentVelo = getVelocity(pointable);
893 | lastVelo = getVelocity(getPointableById(pointable.id(), lastFrame));
894 | } catch (Exception e) {
895 | // ignore
896 | }
897 | currentVelo.sub(lastVelo);
898 | currentVelo.div(2);
899 | acceleration = currentVelo;
900 |
901 | return acceleration;
902 | }
903 |
904 | /**
905 | * returns all pointables in the current frame
906 | *
907 | * @return ArrayList an arraylist containing all currently tracked pointables
908 | */
909 | public ArrayList getPointableList() {
910 | ArrayList pointables = new ArrayList();
911 |
912 | Frame frame = getFrame();
913 | if (frame.hands().isEmpty() == false) {
914 | for (Hand hand : frame.hands()) {
915 | pointables.addAll(getPointableList(hand));
916 | }
917 | }
918 |
919 | return pointables;
920 | }
921 |
922 | /**
923 | * returns all pointables of the passed framre
924 | *
925 | * @return ArrayList an arraylist containing all currently tracked pointables
926 | */
927 | public ArrayList getPointableList(Frame frame) {
928 | ArrayList pointables = new ArrayList();
929 |
930 | if (frame.hands().isEmpty() == false) {
931 | for (Hand hand : frame.hands()) {
932 | pointables.addAll(getPointableList(hand));
933 | }
934 | }
935 |
936 | return pointables;
937 | }
938 |
939 | /**
940 | * returns all pointables of the passed hand
941 | *
942 | * @param hand the hand you want the pointables of
943 | * @return an arraylist containing the pointables of the passed hand
944 | */
945 | public ArrayList getPointableList(Hand hand) {
946 | ArrayList pointables = new ArrayList();
947 |
948 | for (Pointable pointable : hand.pointables()) {
949 | pointables.add(pointable);
950 | }
951 |
952 | return pointables;
953 | }
954 |
955 | /**
956 | * returns a pointable by its number. look up to the equivalent methods for hand/finger for
957 | * documentation
958 | *
959 | * @param pointableNr the number of the pointable
960 | * @return
961 | */
962 | public Pointable getPointable(int pointableNr) {
963 | Pointable returnPointable = null;
964 | if (!getPointableList().isEmpty()) {
965 | this.lastDetectedPointable.put(pointableNr, getPointableList().get(pointableNr));
966 | }
967 | // returnPointable = lastDetectedPointable.get(pointableNr);
968 | int downCounter = 0;
969 | while (returnPointable == null) {
970 | returnPointable = this.lastDetectedPointable.get(pointableNr - downCounter);
971 | downCounter++;
972 | }
973 | return returnPointable;
974 | }
975 |
976 | /**
977 | * returns a pointable by id in the passed frame
978 | *
979 | * @param id the if of the pointbale
980 | * @param frame the frame where to look for the pointable
981 | * @return
982 | */
983 | public Pointable getPointableById(int id, Frame frame) {
984 | Pointable returnPointable = null;
985 | for (Pointable pointable : getPointableList(frame)) {
986 | if (pointable.id() == id) {
987 | returnPointable = pointable;
988 | }
989 | }
990 | return returnPointable;
991 | }
992 |
993 | /**
994 | * calculates an arraylist containing all tools in the current frame
995 | *
996 | * @return
997 | */
998 | public ArrayList getToolList() {
999 | ArrayList tools = new ArrayList();
1000 |
1001 | Frame frame = getFrame();
1002 | if (frame.hands().isEmpty() == false) {
1003 | for (Hand hand : frame.hands()) {
1004 | tools.addAll(getToolList(hand));
1005 | }
1006 | }
1007 |
1008 | return tools;
1009 | }
1010 |
1011 | /**
1012 | * calculates an arraylist containing all tools in the passed frame
1013 | *
1014 | * @return
1015 | */
1016 | public ArrayList getToolList(Frame frame) {
1017 | ArrayList tools = new ArrayList();
1018 |
1019 | if (frame.hands().isEmpty() == false) {
1020 | for (Hand hand : frame.hands()) {
1021 | tools.addAll(getToolList(hand));
1022 | }
1023 | }
1024 |
1025 | return tools;
1026 | }
1027 |
1028 | /**
1029 | * returns a arraylist of tools attached to the passed hand
1030 | *
1031 | * @param hand
1032 | * @return
1033 | */
1034 | public ArrayList getToolList(Hand hand) {
1035 | ArrayList tools = new ArrayList();
1036 |
1037 | for (Tool tool : hand.tools()) {
1038 | tools.add(tool);
1039 | }
1040 |
1041 | return tools;
1042 | }
1043 |
1044 | /**
1045 | * returns a tool by its number
1046 | *
1047 | * @param toolNr
1048 | * @return
1049 | */
1050 | public Tool getTool(int toolNr) {
1051 | Tool returnTool = null;
1052 | if (!getToolList().isEmpty()) {
1053 | this.lastDetectedTool.put(toolNr, getToolList().get(toolNr));
1054 | }
1055 | // returnTool = lastDetectedTool.get(toolNr);
1056 | int downCounter = 0;
1057 | while (returnTool == null) {
1058 | returnTool = this.lastDetectedTool.get(toolNr - downCounter);
1059 | downCounter++;
1060 | }
1061 | return returnTool;
1062 | }
1063 |
1064 | /**
1065 | * calculates a proper timestamp of the passed frame
1066 | *
1067 | * @param frame the frame you want the timestamp of
1068 | * @return Date containing the timestamp when the frame was taken
1069 | */
1070 | public Date getTimestamp(Frame frame) {
1071 | Date date = null;
1072 | Set> lastFramesInclDates = this.lastFramesInclProperTimestamps.entrySet();
1073 | Iterator> i = lastFramesInclDates.iterator();
1074 | while (i.hasNext()) {
1075 | Entry entry = i.next();
1076 | String stringOfTimestampInMap = entry.getValue().timestamp() + "";
1077 | String stringOfTimestampPassedParameter = frame.timestamp() + "";
1078 | if (stringOfTimestampInMap.equals(stringOfTimestampPassedParameter)) {
1079 | date = entry.getKey();
1080 | }
1081 | }
1082 | return date;
1083 | }
1084 | }
1085 |
--------------------------------------------------------------------------------