//-------------------------------------------------------------- void testApp::recordHandXML (Hand & hand, int handIndex){ if (bRecordingThisFrame){ if (hand.isValid()){ int handTagNum = XML.addTag("H"); if( XML.pushTag("H", handTagNum) ){ XML.setValue("INDEX", handIndex, handTagNum); XML.setValue("ID", hand.id(), handTagNum); XML.setValue("TYPE", (hand.isLeft() ? "LEFT" : "RIGHT"), handTagNum); XML.setValue("CONF", hand.confidence(), handTagNum); FingerList fingers = hand.fingers(); for (int f=0; f<fingers.count(); f++){ const Finger & finger = fingers[f]; if (finger.isValid()){ recordFingerXML (finger); } } recordArmXML (hand); XML.popTag(); // pop H(AND) } } } }
ofPoint LeapVisualizer::getIndexFingertip(ofxLeapMotion & leap){ vector <Hand> hands = leap.getLeapHands(); Hand hand; if (hands.size() > 0){ for (int h=0; h<hands.size(); h++){ hand = hands[h]; if (hand.isValid()) break; } } // For each finger in the Hand, FingerList fingers = hand.fingers(); for (int f=0; f<fingers.count(); f++) { // Get the current finger, and it's type (index, thumb, etc.); const Finger & finger = fingers[f]; Finger::Type fingerType = finger.type(); if (finger.isValid() && fingerType == Finger::TYPE_INDEX) { return ofPoint(finger.tipPosition().x, finger.tipPosition().y, finger.tipPosition().z); } } cout << "FINGER NOT FOUND" << endl; return ofPoint(-1.0f,-1.0f,-1.0f); }
//callback function void glListener::onFrame(const Controller& controller){ /*memset(pitches, 0,sizeof(pitches)); memset(rolls, 0,sizeof(rolls)); memset(yaws, 0,sizeof(yaws));*/ //Get the most recent frame and report some basic information const Frame frame = controller.frame(); if(!frame.hands().empty()) { //get the first hand const Hand hand = frame.hands()[0]; //wrist pitches[0] = hand.palmNormal().pitch(); rolls[0] = hand.palmNormal().roll(); yaws[0] = hand.palmNormal().yaw(); /*pitches[0] = hand.direction().pitch(); rolls[0] = hand.direction().roll(); yaws[0] = hand.direction().yaw();*/ //check if the hand has any fingers const FingerList fingers = hand.fingers(); //如果检测到手指且手指的数目等于5 if (!fingers.empty() && fingers.count() == 5) { /*for(int i = 0; i < fingers.count(); i++) { }*/ //Thumb yaws[2] = -fingers.leftmost().direction().pitch(); //Index yaws[5] = -fingers[2].direction().pitch(); //Middle yaws[8]= -fingers[0].direction().pitch(); //Ring yaws[11]= -fingers[1].direction().pitch(); //Little yaws[14]= -fingers.rightmost().direction().pitch(); float temp = 0; //if index is at the right of ring if(fingers[2].tipPosition().x > fingers[1].tipPosition().x) { //swap the pitch angle of index and ring temp = yaws[5]; yaws[5] = yaws[11]; yaws[11] = temp; } } } pModel->animation(pitches,rolls,yaws); }
//-------------------------------------------------------------- void LeapVisualizer::drawFingers (Hand & hand,ofxLeapMotion & leap){ // For each finger in the Hand, FingerList fingers = hand.fingers(); for (int f=0; f<fingers.count(); f++){ // Get the current finger, and it's type (index, thumb, etc.); const Finger & finger = fingers[f]; if (finger.isValid()){ drawFinger(finger,leap); } //end if finger isValid() } // end for each finger }
void LeapBrowser::updateCursorLocation() { bool is_index_found = false; Frame frame = leap_controller.frame(); HandList hands = frame.hands(); for( int h=0; h < hands.count(); h++ ) { Hand hand = hands[h]; FingerList fingers = hand.fingers(); for( int f=0; f < fingers.count(); f++ ) { Finger finger = fingers[f]; if( finger.type() == Finger::Type::TYPE_INDEX ) { is_index_found = true; Vector position = finger.tipPosition(); cursor_location = math::position(position.x, position.y, position.z) * leap_transform; break; } } if( is_index_found ) { break; } } if( !is_index_found ) { cursor_location = math::position(0,0,0); is_cursor_located = false; } else { is_cursor_located = true; } }
void LeapController::onFrame(const Controller& controller) { //console() << "Leap: onFrame" << std::endl; // Get the most recent frame and report some basic information const Frame frame = controller.frame(); /* console() << "Frame id: " << frame.id() << ", timestamp: " << frame.timestamp() << ", hands: " << frame.hands().count() << ", fingers: " << frame.fingers().count() << ", tools: " << frame.tools().count() << ", gestures: " << frame.gestures().count() << std::endl; */ if (!frame.hands().empty()) { const FingerList fingers = frame.fingers(); for(int k = 0; k < fingers.count(); k++){ if (!fingers.empty()){ // Calculate the hand's average finger tip position for (int i = 0; i < fingers.count(); ++i) { ci::Vec2f currentFingerPos(fingers[i].tipPosition().x, fingers[i].tipPosition().z*-1.0); fingerPositions[i] = currentFingerPos; ci::Vec2f currentFingerVel(fingers[i].tipVelocity().x, (fingers[i].tipVelocity().z)); fingerVelocities[i] = currentFingerVel; } avgPos = fingers[0].tipPosition(); numActiveFingers = fingers.count(); hasFingers = true; } else{ hasFingers = false; } } /* // Get the first hand const Hand hand = frame.hands()[0]; // Check if the hand has any fingers const FingerList fingers = hand.fingers(); if (!fingers.empty()){ // Calculate the hand's average finger tip position for (int i = 0; i < fingers.count(); ++i) { ci::Vec2f currentFingerPos(fingers[i].tipPosition().x, fingers[i].tipPosition().y); fingerPositions[i] = currentFingerPos; ci::Vec2f currentFingerVel(fingers[i].tipVelocity().x, (fingers[i].tipVelocity().y*-1.0)); fingerVelocities[i] = currentFingerVel; } avgPos = fingers[0].tipPosition(); numActiveFingers = fingers.count(); //console() << "Hand has " << fingers.count() << " fingers, average finger tip position" << avgPos << std::endl; hasFingers = true; } else{ hasFingers = false; } */ /* // Get the hand's sphere radius and palm position console() << "Hand sphere radius: " << hand.sphereRadius() << " mm, palm position: " << hand.palmPosition() << std::endl; // Get the hand's normal vector and direction const Vector normal = hand.palmNormal(); const Vector direction = hand.direction(); // Calculate the hand's pitch, roll, and yaw angles console() << "Hand pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; */ } else{ hasFingers = false; } /* // Get gestures const GestureList gestures = frame.gestures(); for (int g = 0; g < gestures.count(); ++g) { Gesture gesture = gestures[g]; switch (gesture.type()) { case Gesture::TYPE_CIRCLE: { CircleGesture circle = gesture; std::string clockwiseness; if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4) { clockwiseness = "clockwise"; } else { clockwiseness = "counterclockwise"; } // Calculate angle swept since last frame float sweptAngle = 0; if (circle.state() != Gesture::STATE_START) { CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id())); sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI; } console() << "Circle id: " << gesture.id() << ", state: " << gesture.state() << ", progress: " << circle.progress() << ", radius: " << circle.radius() << ", angle " << sweptAngle * RAD_TO_DEG << ", " << clockwiseness << std::endl; break; } case Gesture::TYPE_SWIPE: { SwipeGesture swipe = gesture; console() << "Swipe id: " << gesture.id() << ", state: " << gesture.state() << ", direction: " << swipe.direction() << ", speed: " << swipe.speed() << std::endl; break; } case Gesture::TYPE_KEY_TAP: { KeyTapGesture tap = gesture; console() << "Key Tap id: " << gesture.id() << ", state: " << gesture.state() << ", position: " << tap.position() << ", direction: " << tap.direction()<< std::endl; break; } case Gesture::TYPE_SCREEN_TAP: { ScreenTapGesture screentap = gesture; console() << "Screen Tap id: " << gesture.id() << ", state: " << gesture.state() << ", position: " << screentap.position() << ", direction: " << screentap.direction()<< std::endl; break; } default: console() << "Unknown gesture type." << std::endl; break; } } if (!frame.hands().empty() || !gestures.empty()) { console() << std::endl; }*/ }
//-------------------------------------------------------------- void LeapVisualizer::drawPalm (Hand & hand,ofxLeapMotion & leap){ // This draws the palm as a gray region. // Collect the palm vertices into an ofMesh. ofMesh palmMesh; int nVertices = 0; float averageBoneWidth = 0; // For each finger, FingerList fingers = hand.fingers(); for (int f=0; f<fingers.count(); f++){ // Get the current finger, and it's type (index, thumb, etc.); const Finger & finger = fingers[f]; if (finger.isValid()){ Finger::Type fingerType = finger.type(); Bone bone; if (fingerType == Finger::TYPE_THUMB){ bone = finger.bone(Bone::TYPE_PROXIMAL); } else { bone = finger.bone(Bone::TYPE_METACARPAL); } // If we've found the bones we want, add their vertices to the mesh. if (bone.isValid()){ float boneLength = bone.length(); if (boneLength > 0){ ofPoint pt0 = leap.getofPoint ( bone.prevJoint()); ofPoint pt1 = leap.getofPoint ( bone.nextJoint()); palmMesh.addVertex(pt0); palmMesh.addVertex(pt1); averageBoneWidth += bone.width(); nVertices += 2; } } } } averageBoneWidth /= (nVertices/2); // Render the palm as a triangle strip surface, // (optionally) bordered by cylinders. if (nVertices > 3){ ofSetColor(ofColor::gray); // Draw the palm as a mesh of triangles. int nPalmMeshVertices = palmMesh.getNumVertices(); for (int i=0; i<(nPalmMeshVertices-2); i++){ palmMesh.addTriangle(i, i+1, i+2); } palmMesh.drawFaces(); // Add optional cylinders. if (!bDrawSimple){ float rad = averageBoneWidth / 2.0; if (nPalmMeshVertices == 10){ for (int i=0; i<4; i++){ ofVec3f p0 = palmMesh.getVertex( i *2); ofVec3f p1 = palmMesh.getVertex((i+1)*2); drawOrientedCylinder (p0, p1, 10); ofDrawSphere(p0, rad); ofDrawSphere(p1, rad); } for (int i=0; i<4; i++){ ofVec3f p0 = palmMesh.getVertex( i *2 + 1); ofVec3f p1 = palmMesh.getVertex((i+1)*2 + 1); drawOrientedCylinder (p0, p1, 10); ofDrawSphere(p0, rad); ofDrawSphere(p1, rad); } } } } }
void LeapListener::onFrame(const Controller &controller){ const Frame frame = controller.frame(); HandList hands = frame.hands(); std::vector<HandModel> myhands; BoneModel mybone; HandModel myhand; //printf("frame: %d\n", frame.id()); float scale = 0.025; float disp = 3.5f; bool record = true; for (int i = 0; i < hands.count(); i++){ FingerList fingers = hands[i].fingers(); myhand.bones.clear(); myhand.references.clear(); Vector handPosition = hands[i].palmPosition(); handPosition *= scale; handPosition.y -= disp; Vector wrist = hands[i].wristPosition(); wrist *= scale; wrist.y -= disp; myhand.palmPosition = handPosition; myhand.palmNormal = hands[i].palmNormal(); myhand.direction = hands[i].direction(); for (int j = 0; j < fingers.count(); j++){ Bone bone; Bone::Type boneType; Vector currentPosition = fingers[j].tipPosition(); currentPosition *= scale; currentPosition.y -= disp; Vector lastPosition = m_lastFrame.finger(fingers[j].id()).tipPosition(); lastPosition *= scale; lastPosition.y -= disp; Vector diff = currentPosition - lastPosition; //printf("%f, %f, %f\n", abs(diff.x), abs(diff.y), abs(diff.z)); //if (abs(diff.x) > 0.2 || abs(diff.y) > 0.2 || abs(diff.z) > 0.2) record = false; if (abs(diff.x) < 0.0001 || abs(diff.y) < 0.0001 || abs(diff.z) < 0.0001) record = false; for (int k = 0; k < 4; k++){ boneType = static_cast<Bone::Type>(k); bone = fingers[j].bone(boneType); if (fingers[j].type() == Finger::Type::TYPE_THUMB && k == 0) continue; Vector prevPos = bone.prevJoint(); prevPos *= scale; prevPos.y -= disp; Vector nextPos = bone.nextJoint(); nextPos *= scale; nextPos.y -= disp; mybone.direction = nextPos - prevPos; mybone.position = (prevPos + nextPos) / 2; mybone.prevJoint = prevPos; mybone.nextJoint = nextPos; mybone.length = bone.length() * scale; if (boneType == Bone::Type::TYPE_PROXIMAL){ if (fingers[j].type() == Finger::Type::TYPE_THUMB){ myhand.thumb = prevPos; //myhand.references.push_back(nextPos); } else{ myhand.references.push_back(prevPos); } } myhand.bones.push_back(mybone); } } myhand.base = myhand.references[3] - myhand.references[0]; Vector disp = myhand.base.normalized() * 0.3f; myhand.references[3] += disp; myhand.references[0] -= disp; //for (int i = 1; i < 5; i++){ // printf("%f\n", myhand.references[i - 1].distanceTo(myhand.references[i])); //} myhands.push_back(myhand); } if (record){ m_hands.clear(); for (int i = 0; i < myhands.size(); i++){ m_hands.push_back(myhands[i]); } } m_lastFrame = frame; }