Vuo 2.4.2
Loading...
Searching...
No Matches
VuoLeap.cc
Go to the documentation of this file.
1
10#include "VuoLeap.h"
11#include "VuoLeapHand.h"
12#include "VuoLeapPointable.h"
13#include "VuoList_VuoLeapHand.h"
15
16#pragma clang diagnostic push
17#pragma clang diagnostic ignored "-Wdocumentation"
18#include <Leap.h>
19#pragma clang diagnostic pop
20
21#include "module.h"
22
23extern "C"
24{
25#ifdef VUO_COMPILER
27 "title": "VuoLeap",
28 "dependencies": [
29 "VuoLeapFrame",
30 "VuoLeapHand",
31 "VuoLeapPointable",
32 "VuoList_VuoLeapHand",
33 "VuoList_VuoLeapPointable",
34 "VuoTransform",
35 "Leap",
36 ],
37 "compatibility": {
38 "macos": {
39 "arch": ["x86_64"],
40 },
41 },
42});
43// The Leap SDK isn't yet available on arm64.
44#endif
45}
46
47
48#if defined(__x86_64__) || defined(DOXYGEN)
53static double VuoLeap_vuoDistanceFromLeapMillimeters(double millimeters, Leap::InteractionBox ibox)
54{
55 return (millimeters / ibox.width()) * 2.;
56}
57
62static VuoPoint3d VuoLeap_vuoPointFromLeapVector(Leap::Vector vector, Leap::InteractionBox ibox)
63{
64 return VuoPoint3d_make(
68 );
69}
70
75{
76 switch(zone)
77 {
78 case Leap::Pointable::ZONE_TOUCHING:
79 return VuoLeapTouchZone_Touching;
80
81 case Leap::Pointable::ZONE_HOVERING:
82 return VuoLeapTouchZone_Hovering;
83
84 case Leap::Pointable::ZONE_NONE:
85 return VuoLeapTouchZone_None;
86 }
87}
88
93static VuoPoint3d VuoLeap_vuoPointFromLeapPosition(Leap::Vector position, Leap::InteractionBox ibox)
94{
95 return VuoLeap_vuoPointFromLeapVector(position - ibox.center(), ibox);
96}
97
101static VuoPoint3d VuoPoint3dWithLeapVector(Leap::Vector vector)
102{
103 return VuoPoint3d_make(vector.x, vector.y, vector.z);
104}
105
109class VuoLeapListener : public Leap::Listener {
110public:
111
116 (
117 void (*receivedFrame)(VuoLeapFrame frame)
118 )
119 {
120 this->receivedFrame = receivedFrame;
121 }
122
123private:
124 void (*receivedFrame)(VuoLeapFrame frame);
125
126 virtual void onInit(const Leap::Controller&) {}
127 virtual void onDisconnect(const Leap::Controller&) {}
128 virtual void onExit(const Leap::Controller&) {}
129 virtual void onFocusGained(const Leap::Controller&) {}
130 virtual void onFocusLost(const Leap::Controller&) {}
131
132 virtual void onConnect(const Leap::Controller &controller)
133 {
134 controller.enableGesture(Leap::Gesture::TYPE_CIRCLE);
135 controller.enableGesture(Leap::Gesture::TYPE_KEY_TAP);
136 controller.enableGesture(Leap::Gesture::TYPE_SCREEN_TAP);
137 controller.enableGesture(Leap::Gesture::TYPE_SWIPE);
138
139 controller.setPolicyFlags(Leap::Controller::POLICY_BACKGROUND_FRAMES);
140 }
141
142 virtual void onFrame(const Leap::Controller &controller)
143 {
144 const Leap::Frame frame = controller.frame();
145
146 // used to normalize leap coordinates (the boolean parameter says 'no clamping' which allows for coordinates > 1)
147 // https://developer.leapmotion.com/documentation/Languages/Java/API/classcom_1_1leapmotion_1_1leap_1_1_interaction_box.html#details
148 Leap::InteractionBox interactionBox = frame.interactionBox();
149
150 // https://developer.leapmotion.com/documentation/Languages/C++/Guides/Leap_Frames.html
151 if(!frame.isValid())
152 return;
153
155
156 Leap::HandList allHands = frame.hands();
157 Leap::PointableList allPointables = frame.pointables();
158
159 for (Leap::PointableList::const_iterator pointable = allPointables.begin(); pointable != allPointables.end(); ++pointable)
160 {
161 VuoPoint3d position = VuoLeap_vuoPointFromLeapPosition((*pointable).tipPosition(), interactionBox);
162 VuoPoint3d stabilized = VuoLeap_vuoPointFromLeapPosition((*pointable).stabilizedTipPosition(), interactionBox);
163 VuoPoint3d tipPosition = VuoPoint3d_make(stabilized.x, stabilized.y, position.z);
164
166 (*pointable).id(),
167 (*pointable).isFinger() ? VuoLeapPointableType_Finger : VuoLeapPointableType_Tool,
168 VuoLeap_vuoDistanceFromLeapMillimeters((*pointable).length(), interactionBox),
169 VuoLeap_vuoDistanceFromLeapMillimeters((*pointable).width(), interactionBox),
170 VuoPoint3dWithLeapVector( (*pointable).direction() ), // leave as is
171 tipPosition,
172 VuoLeap_vuoPointFromLeapVector((*pointable).tipVelocity(), interactionBox),
173 (*pointable).timeVisible(),
174 (*pointable).touchDistance(),
175 VuoLeap_vuoLeapTouchZoneFromLeapTouchZone((*pointable).touchZone()),
176 (*pointable).isExtended()
177 ));
178 }
179
181
182 for(Leap::HandList::const_iterator hand = allHands.begin(); hand != allHands.end(); ++hand)
183 {
185 Leap::FingerList fingers = (*hand).fingers();
186
187 for (Leap::FingerList::const_iterator pointable = fingers.begin(); pointable != fingers.end(); ++pointable)
188 {
189 VuoPoint3d position = VuoLeap_vuoPointFromLeapPosition((*pointable).tipPosition(), interactionBox);
190 VuoPoint3d stabilized = VuoLeap_vuoPointFromLeapPosition((*pointable).stabilizedTipPosition(), interactionBox);
191 VuoPoint3d tipPosition = VuoPoint3d_make(stabilized.x, stabilized.y, position.z);
192
194 (*pointable).id(),
195 VuoLeapPointableType_Finger,
196 VuoLeap_vuoDistanceFromLeapMillimeters((*pointable).length(), interactionBox),
197 VuoLeap_vuoDistanceFromLeapMillimeters((*pointable).width(), interactionBox),
198 VuoPoint3dWithLeapVector( (*pointable).direction() ),
199 tipPosition,
200 VuoLeap_vuoPointFromLeapVector((*pointable).tipVelocity(), interactionBox),
201 (*pointable).timeVisible(),
202 (*pointable).touchDistance(),
203 VuoLeap_vuoLeapTouchZoneFromLeapTouchZone((*pointable).touchZone()),
204 (*pointable).isExtended()
205 ));
206 }
207
208 Leap::Matrix basis = (*hand).basis();
209 if ((*hand).isLeft())
210 {
211 // "the basis matrix will be left-handed for left hands"
212 // https://developer.leapmotion.com/documentation/skeletal/cpp/api/Leap.Hand.html#cppclass_leap_1_1_hand_1a4ff50b291a30106f8306ba26d55ada76
213 basis.xBasis *= -1;
214 }
215
216 Leap::Matrix basisInverse = basis.rigidInverse();
217 VuoPoint3d basisPoint3d[3] = {
218 VuoPoint3dWithLeapVector(basisInverse.xBasis),
219 VuoPoint3dWithLeapVector(basisInverse.yBasis),
220 VuoPoint3dWithLeapVector(basisInverse.zBasis)
221 };
222
223 VuoPoint3d position = VuoLeap_vuoPointFromLeapPosition((*hand).palmPosition(), interactionBox);
224 VuoPoint3d stabilized = VuoLeap_vuoPointFromLeapPosition((*hand).stabilizedPalmPosition(), interactionBox);
225 VuoPoint3d palmPosition = VuoPoint3d_make(stabilized.x, stabilized.y, position.z);
226
228 (*hand).id(),
230 palmPosition,
231 VuoLeap_vuoPointFromLeapVector((*hand).palmVelocity(), interactionBox),
232 VuoLeap_vuoDistanceFromLeapMillimeters((*hand).sphereRadius(), interactionBox),
233 VuoLeap_vuoPointFromLeapPosition((*hand).sphereCenter(), interactionBox),
234 VuoLeap_vuoDistanceFromLeapMillimeters((*hand).palmWidth(), interactionBox),
235 VuoLeap_vuoPointFromLeapPosition( (*hand).wristPosition(), interactionBox ),
236 (*hand).pinchStrength(),
237 (*hand).grabStrength(),
238 (*hand).timeVisible(),
239 (*hand).isLeft(),
240 (*hand).confidence(),
241 handPointables));
242 }
243
244 receivedFrame(VuoLeapFrame_make(frame.id(), hands, pointables));
245 }
246};
247
251typedef struct _VuoLeapInternal
252{
253 Leap::Controller *controller;
254 VuoLeapListener *listener;
256
265(
266 VuoOutputTrigger(receivedFrame, VuoLeapFrame)
267)
268{
269 VuoLeapInternal leap = (VuoLeapInternal)malloc(sizeof(struct _VuoLeapInternal));
270
271 leap->controller = new Leap::Controller;
272 leap->listener = new VuoLeapListener(receivedFrame);
273 leap->controller->addListener(*leap->listener);
274
275 return (VuoLeap)leap;
276}
277
282{
284
285 leap->controller->removeListener(*leap->listener);
286
287 delete leap->listener;
288 delete leap->controller;
289 delete leap;
290}
291#endif