Permalink
Browse files

small update to ofxLeapMotion added ofxLeapMotionSimpleHand with fing…

…er velocity and palm position and normal. added debugDraw which shows hand position.
  • Loading branch information...
1 parent ec5bb07 commit 5e7ea2120f48e1d6bf96da7eb0c52aba3952b116 @ofTheo committed Jan 9, 2013
Showing with 194 additions and 64 deletions.
  1. +4 −2 ofxLeapMotion.xcodeproj/project.pbxproj
  2. +103 −16 src/ofxLeapMotion/src/ofxLeapMotion.h
  3. +85 −45 src/testApp.cpp
  4. +2 −1 src/testApp.h
@@ -399,7 +399,8 @@
isa = XCBuildConfiguration;
baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
buildSettings = {
- ARCHS = "$(NATIVE_ARCH)";
+ ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
+ ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = i386;
CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
@@ -432,7 +433,8 @@
isa = XCBuildConfiguration;
baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
buildSettings = {
- ARCHS = "$(NATIVE_ARCH)";
+ ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
+ ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = i386;
CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/";
COPY_PHASE_STRIP = YES;
DEAD_CODE_STRIPPING = YES;
@@ -10,27 +10,69 @@
using namespace Leap;
+class ofxLeapMotionSimpleHand{
+ public:
+
+ typedef struct{
+ ofPoint pos;
+ ofPoint vel;
+ int64_t id;
+ }simpleFinger;
+
+ vector <simpleFinger> fingers;
+
+ ofPoint handPos;
+ ofPoint handNormal;
+
+ void debugDraw(){
+ ofPushStyle();
+
+ ofSetColor(190);
+ ofSetLineWidth(2);
+
+ ofEnableLighting();
+ ofPushMatrix();
+ ofTranslate(handPos);
+ //rotate the hand by the downwards normal
+ ofQuaternion q;
+ q.makeRotate(ofPoint(0, -1, 0), handNormal);
+ ofMatrix4x4 m;
+ q.get(m);
+ glMultMatrixf(m.getPtr());
+
+
+ //scale it to make it not a box
+ ofScale(1, 0.35, 1.0);
+ ofBox(0, 0, 0, 60);
+ ofPopMatrix();
+
+
+ for(int i = 0; i < fingers.size(); i++){
+ ofDrawArrow(handPos, fingers[i].pos, 10);
+ }
+
+ ofSetColor(220, 220, 0);
+ for(int i = 0; i < fingers.size(); i++){
+ ofDrawArrow(fingers[i].pos + fingers[i].vel/20, fingers[i].pos + fingers[i].vel/10, 10);
+ }
+
+ ofPopStyle();
+ }
+};
+
class ofxLeapMotion : public Listener{
public:
ofxLeapMotion(){
- currentFrameID = 0;
- preFrameId = -1;
-
- xOffsetIn = 0;
- yOffsetIn = 0;
- zOffsetIn = 0;
-
- xOffsetOut = 0;
- yOffsetOut = 0;
- zOffsetOut = 0;
-
- xScale = 1;
- yScale = 1;
- zScale = 1;
-
+ reset();
+ resetMapping();
ourController = new Leap::Controller();
}
+
+ void reset(){
+ currentFrameID = 0;
+ preFrameId = -1;
+ }
~ofxLeapMotion(){
//note we don't delete the controller as it causes a crash / mutex exception.
@@ -45,6 +87,7 @@ class ofxLeapMotion : public Listener{
//--------------------------------------------------------------
void open(){
+ reset();
ourController->addListener(*this);
}
@@ -74,7 +117,7 @@ class ofxLeapMotion : public Listener{
//Simple access to the hands
//--------------------------------------------------------------
- vector <Hand> getHands(){
+ vector <Hand> getLeapHands(){
vector <Hand> handsCopy;
if( ourMutex.tryLock(2000) ){
@@ -86,6 +129,35 @@ class ofxLeapMotion : public Listener{
}
//--------------------------------------------------------------
+ vector <ofxLeapMotionSimpleHand> getSimpleHands(){
+
+ vector <ofxLeapMotionSimpleHand> simpleHands;
+ vector <Hand> leapHands = getLeapHands();
+
+ for(int i = 0; i < leapHands.size(); i++){
+ ofxLeapMotionSimpleHand curHand;
+
+ curHand.handPos = getMappedofPoint( leapHands[i].palmPosition() );
+ curHand.handNormal = getofPoint( leapHands[i].palmNormal() );
+
+ for(int j = 0; j < leapHands[i].fingers().count(); j++){
+ const Finger & finger = hands[i].fingers()[j];
+
+ ofxLeapMotionSimpleHand::simpleFinger f;
+ f.pos = getMappedofPoint( finger.tipPosition() );
+ f.vel = getMappedofPoint(finger.tipVelocity());
+ f.id = finger.id();
+
+ curHand.fingers.push_back( f );
+ }
+
+ simpleHands.push_back( curHand );
+ }
+
+ return simpleHands;
+ }
+
+ //--------------------------------------------------------------
bool isFrameNew(){
return currentFrameID != preFrameId;
}
@@ -99,6 +171,21 @@ class ofxLeapMotion : public Listener{
int64_t getCurrentFrameID(){
return currentFrameID;
}
+
+ //--------------------------------------------------------------
+ void resetMapping(){
+ xOffsetIn = 0;
+ yOffsetIn = 0;
+ zOffsetIn = 0;
+
+ xOffsetOut = 0;
+ yOffsetOut = 0;
+ zOffsetOut = 0;
+
+ xScale = 1;
+ yScale = 1;
+ zScale = 1;
+ }
//--------------------------------------------------------------
void setMappingX(float minX, float maxX, float outputMinX, float outputMaxX){
View
@@ -16,6 +16,7 @@ void testApp::setup(){
cam.setOrientation(ofPoint(-20, 0, 0));
glEnable(GL_DEPTH_TEST);
+ glEnable(GL_NORMALIZE);
}
@@ -29,53 +30,86 @@ void testApp::update(){
//if instead you want to get the data as it comes in then you can inherit ofxLeapMotion and implement the onFrame method.
//there you can work with the frame data directly.
-
- vector <Hand> hands = leap.getHands();
-
- if( leap.isFrameNew() && hands.size() ){
- //leap returns data in mm - lets set a mapping to our world space.
- //you can get back a mapped point by using ofxLeapMotion::getMappedofPoint with the Leap::Vector that tipPosition returns
- leap.setMappingX(-230, 230, -ofGetWidth()/2, ofGetWidth()/2);
- leap.setMappingY(90, 490, -ofGetHeight()/2, ofGetHeight()/2);
- leap.setMappingZ(-150, 150, -200, 200);
-
- for(int i = 0; i < hands.size(); i++){
- for(int j = 0; j < hands[i].fingers().count(); j++){
- ofPoint pt;
-
- const Finger & finger = hands[i].fingers()[j];
-
- cout << "pos is " << finger.tipPosition() << endl;
-
- //here we convert the Leap point to an ofPoint - with mapping of coordinates
- //if you just want the raw point - use ofxLeapMotion::getofPoint
- pt = leap.getMappedofPoint( finger.tipPosition() );
-
- //lets get the correct trail (ofPolyline) out of our map - using the finger id as the key
- ofPolyline & polyline = fingerTrails[finger.id()];
-
- //if the distance between the last point and the current point is too big - lets clear the line
- //this stops us connecting to an old drawing
- if( polyline.size() && (pt-polyline[polyline.size()-1] ).length() > 50 ){
- polyline.clear();
- }
-
- //add our point to our trail
- polyline.addVertex(pt);
-
- //store fingers seen this frame for drawing
- fingersFound.push_back(finger.id());
- }
- }
-
-
- }
-
- //tell ofxLeapMotion that the frame is no longer new.
- leap.markFrameAsOld();
-
+
+ //Option 1: Use the simple ofxLeapMotionSimpleHand - this gives you quick access to fingers and palms.
+
+ simpleHands = leap.getSimpleHands();
+
+ if( leap.isFrameNew() && simpleHands.size() ){
+
+ leap.setMappingX(-230, 230, -ofGetWidth()/2, ofGetWidth()/2);
+ leap.setMappingY(90, 490, -ofGetHeight()/2, ofGetHeight()/2);
+ leap.setMappingZ(-150, 150, -200, 200);
+
+ for(int i = 0; i < simpleHands.size(); i++){
+
+ for(int j = 0; j < simpleHands[i].fingers.size(); j++){
+ int id = simpleHands[i].fingers[j].id;
+
+ ofPolyline & polyline = fingerTrails[id];
+ ofPoint pt = simpleHands[i].fingers[j].pos;
+
+ //if the distance between the last point and the current point is too big - lets clear the line
+ //this stops us connecting to an old drawing
+ if( polyline.size() && (pt-polyline[polyline.size()-1] ).length() > 50 ){
+ polyline.clear();
+ }
+
+ //add our point to our trail
+ polyline.addVertex(pt);
+
+ //store fingers seen this frame for drawing
+ fingersFound.push_back(id);
+ }
+ }
+ }
+
+
+ // Option 2: Work with the leap data / sdk directly - gives you access to more properties than the simple approach
+ // uncomment code below and comment the code above to use this approach. You can also inhereit ofxLeapMotion and get the data directly via the onFrame callback.
+
+// vector <Hand> hands = leap.getLeapHands();
+// if( leap.isFrameNew() && hands.size() ){
+//
+// //leap returns data in mm - lets set a mapping to our world space.
+// //you can get back a mapped point by using ofxLeapMotion::getMappedofPoint with the Leap::Vector that tipPosition returns
+// leap.setMappingX(-230, 230, -ofGetWidth()/2, ofGetWidth()/2);
+// leap.setMappingY(90, 490, -ofGetHeight()/2, ofGetHeight()/2);
+// leap.setMappingZ(-150, 150, -200, 200);
+//
+// for(int i = 0; i < hands.size(); i++){
+// for(int j = 0; j < hands[i].fingers().count(); j++){
+// ofPoint pt;
+//
+// const Finger & finger = hands[i].fingers()[j];
+//
+// //here we convert the Leap point to an ofPoint - with mapping of coordinates
+// //if you just want the raw point - use ofxLeapMotion::getofPoint
+// pt = leap.getMappedofPoint( finger.tipPosition() );
+//
+// //lets get the correct trail (ofPolyline) out of our map - using the finger id as the key
+// ofPolyline & polyline = fingerTrails[finger.id()];
+//
+// //if the distance between the last point and the current point is too big - lets clear the line
+// //this stops us connecting to an old drawing
+// if( polyline.size() && (pt-polyline[polyline.size()-1] ).length() > 50 ){
+// polyline.clear();
+// }
+//
+// //add our point to our trail
+// polyline.addVertex(pt);
+//
+// //store fingers seen this frame for drawing
+// fingersFound.push_back(finger.id());
+// }
+// }
+// }
+//
+
+ //IMPORTANT! - tell ofxLeapMotion that the frame is no longer new.
+ leap.markFrameAsOld();
}
//--------------------------------------------------------------
@@ -112,6 +146,12 @@ void testApp::draw(){
strip.getMesh().draw();
}
+ l2.disable();
+
+ for(int i = 0; i < simpleHands.size(); i++){
+ simpleHands[i].debugDraw();
+ }
+
m1.end();
cam.end();
View
@@ -22,7 +22,8 @@ class testApp : public ofBaseApp{
void gotMessage(ofMessage msg);
ofxLeapMotion leap;
-
+ vector <ofxLeapMotionSimpleHand> simpleHands;
+
vector <int> fingersFound;
ofEasyCam cam;
ofLight l1;

0 comments on commit 5e7ea21

Please sign in to comment.