void LeapHands::onFrame(const Controller& controller) { //Game::Instance()->PrintFloat("Hand children: ", childrenMap.size()); std::map<string, BoneData> tempBoneData; HandList hands = controller.frame().hands(); int handId = 0; hands[0].fingers()[(int) Finger::Type::TYPE_THUMB]; for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) { // Get the first hand const Hand hand = *hl; // Get fingers const FingerList fingers = hand.fingers(); int fingerId = 0; bool firstFinger = true; Finger previousFinger; stringstream ass; ass << "Arm: 0 Hand: " << handId; tempBoneData[ass.str()] = BoneData(ass.str(), LeapToGlVec3(hand.arm().wristPosition()), LeapToGlVec3(hand.arm().elbowPosition()), true); ass.clear(); glm::vec3 thumbBone = LeapToGlVec3(hand.fingers()[Finger::Type::TYPE_THUMB].bone(Bone::Type::TYPE_DISTAL).nextJoint()); glm::vec3 indexBone = LeapToGlVec3(hand.fingers()[Finger::Type::TYPE_INDEX].bone(Bone::Type::TYPE_DISTAL).nextJoint()); pinchDist = glm::length(thumbBone - indexBone); if (pinchDist < 5.0f) { pinch = true; } else { pinch = false; } for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl) { const Finger finger = *fl; // Get finger bones for (int b = 0; b < 4; ++b) { Bone::Type boneType = static_cast<Bone::Type>(b); Bone bone = finger.bone(boneType); stringstream ss; ss << "Hand: " << handId << " Finger: " << fingerId << " Bone: " << b; tempBoneData[ss.str()] = BoneData(ss.str(), LeapToGlVec3(bone.prevJoint()), LeapToGlVec3(bone.nextJoint()), true); } // Draw some other bits of the hand if (!firstFinger) { for (int b = 0; b < 2; ++b) { stringstream ss; ss << "Hand: " << handId << "Finger: " << (fingerId - 1) << "Finger: " << (fingerId) << " Bone: " << b; Bone startBone = previousFinger.bone(static_cast<Bone::Type>(b)); Bone endBone = finger.bone(static_cast<Bone::Type>(b)); if ((b == 1) && (fingerId == 1)) { tempBoneData[ss.str()] = BoneData(ss.str(), LeapToGlVec3(startBone.nextJoint()), LeapToGlVec3(endBone.prevJoint()), false); } else { tempBoneData[ss.str()] = BoneData(ss.str(), LeapToGlVec3(startBone.prevJoint()), LeapToGlVec3(endBone.prevJoint()), false); } } } const GestureList gestures = controller.frame().gestures(); for (int g = 0; g < gestures.count(); ++g) { Gesture gesture = gestures[g]; switch (gesture.type()) { case Gesture::TYPE_CIRCLE: { CircleGesture circle = gesture; if (gesture.durationSeconds() > 1) { if (circle.pointable().direction().angleTo(circle.normal()) <= PI / 2) { spawn = vehicle; } else { spawn = model; } } } } } previousFinger = finger; firstFinger = false; ++fingerId; } ++handId; } EnterCriticalSection(&criticalSection); trackedHands = handId; map<string, BoneData>::iterator it = tempBoneData.begin(); boneData = tempBoneData; LeaveCriticalSection(&criticalSection); }
//-------------------------------------------------------------- void testApp::recordArmXML (Hand & hand){ if (bRecordingThisFrame){ Arm arm = hand.arm(); if (arm.isValid()){ float armWidth = arm.width(); XML.setValue("AW", armWidth, lastTagNumber); ofPoint palmPt = leap.getofPoint ( hand.palmPosition()); ofPoint wristPt = leap.getofPoint ( arm.wristPosition()); ofPoint elbowPt = leap.getofPoint ( arm.elbowPosition()); ofPoint palmNorm = leap.getofPoint ( hand.palmNormal()); int palmPtTagNum = XML.addTag("PM"); XML.setValue("PM:X", palmPt.x, palmPtTagNum); XML.setValue("PM:Y", palmPt.y, palmPtTagNum); XML.setValue("PM:Z", palmPt.z, palmPtTagNum); int wristPtTagNum = XML.addTag("W"); XML.setValue("W:X", wristPt.x, wristPtTagNum); XML.setValue("W:Y", wristPt.y, wristPtTagNum); XML.setValue("W:Z", wristPt.z, wristPtTagNum); int elbowPtTagNum = XML.addTag("E"); XML.setValue("E:X", elbowPt.x, elbowPtTagNum); XML.setValue("E:Y", elbowPt.y, elbowPtTagNum); XML.setValue("E:Z", elbowPt.z, elbowPtTagNum); int palmNormTagNum = XML.addTag("PN"); XML.setValue("PN:X", palmNorm.x, palmNormTagNum); XML.setValue("PN:Y", palmNorm.y, palmNormTagNum); XML.setValue("PN:Z", palmNorm.z, palmNormTagNum); //--------------- // Export the hand basis matrix Leap::Matrix handMatrix = hand.basis(); ofPoint handBasisX = leap.getofPoint( handMatrix.xBasis); ofPoint handBasisY = leap.getofPoint( handMatrix.yBasis); ofPoint handBasisZ = leap.getofPoint( handMatrix.zBasis); int handMatrixTagNum = XML.addTag("HM"); if( XML.pushTag("HM", handMatrixTagNum) ){ XML.setValue("XX", handBasisX.x, handMatrixTagNum); XML.setValue("XY", handBasisX.y, handMatrixTagNum); XML.setValue("XZ", handBasisX.z, handMatrixTagNum); XML.setValue("YX", handBasisY.x, handMatrixTagNum); XML.setValue("YY", handBasisY.y, handMatrixTagNum); XML.setValue("YZ", handBasisY.z, handMatrixTagNum); XML.setValue("ZX", handBasisZ.x, handMatrixTagNum); XML.setValue("ZY", handBasisZ.y, handMatrixTagNum); XML.setValue("ZZ", handBasisZ.z, handMatrixTagNum); XML.popTag(); // pop HM (Hand Matrix) } //--------------- // Export the arm basis matrix Leap::Matrix armMatrix = arm.basis(); ofPoint armBasisX = leap.getofPoint( armMatrix.xBasis); ofPoint armBasisY = leap.getofPoint( armMatrix.yBasis); ofPoint armBasisZ = leap.getofPoint( armMatrix.zBasis); int armMatrixTagNum = XML.addTag("AM"); if( XML.pushTag("AM", armMatrixTagNum) ){ XML.setValue("XX", armBasisX.x, armMatrixTagNum); XML.setValue("XY", armBasisX.y, armMatrixTagNum); XML.setValue("XZ", armBasisX.z, armMatrixTagNum); XML.setValue("YX", armBasisY.x, armMatrixTagNum); XML.setValue("YY", armBasisY.y, armMatrixTagNum); XML.setValue("YZ", armBasisY.z, armMatrixTagNum); XML.setValue("ZX", armBasisZ.x, armMatrixTagNum); XML.setValue("ZY", armBasisZ.y, armMatrixTagNum); XML.setValue("ZZ", armBasisZ.z, armMatrixTagNum); XML.popTag(); // pop AM (Arm Matrix) } } } }
void LeapListener::onFrame(const Controller & controller) { // Get the most recent frame and report some basic information const Frame frame = controller.frame(); std::cout << "Frame id: " << frame.id() << ", timestamp: " << frame.timestamp() << ", hands: " << frame.hands().count() << ", extended fingers: " << frame.fingers().extended().count() << ", tools: " << frame.tools().count() << ", gestures: " << frame.gestures().count() << std::endl; HandList hands = frame.hands(); for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) { // Get the first hand const Hand hand = *hl; std::string handType = hand.isLeft() ? "Left hand" : "Right hand"; std::cout << std::string(2, ' ') << handType << ", id: " << hand.id() << ", 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 std::cout << std::string(2, ' ') << "pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; // Get the Arm bone Arm arm = hand.arm(); std::cout << std::string(2, ' ') << "Arm direction: " << arm.direction() << " wrist position: " << arm.wristPosition() << " elbow position: " << arm.elbowPosition() << std::endl; // Get fingers const FingerList fingers = hand.fingers(); for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl) { const Finger finger = *fl; std::cout << std::string(4, ' ') << fingerNames[finger.type()] << " finger, id: " << finger.id() << ", length: " << finger.length() << "mm, width: " << finger.width() << std::endl; // Get finger bones for (int b = 0; b < 4; ++b) { Bone::Type boneType = static_cast<Bone::Type>(b); Bone bone = finger.bone(boneType); std::cout << std::string(6, ' ') << boneNames[boneType] << " bone, start: " << bone.prevJoint() << ", end: " << bone.nextJoint() << ", direction: " << bone.direction() << std::endl; } } } // Get tools const ToolList tools = frame.tools(); for (ToolList::const_iterator tl = tools.begin(); tl != tools.end(); ++tl) { const Tool tool = *tl; std::cout << std::string(2, ' ') << "Tool, id: " << tool.id() << ", position: " << tool.tipPosition() << ", direction: " << tool.direction() << std::endl; } // 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/2) { 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; } std::cout << std::string(2, ' ') << "Circle id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", progress: " << circle.progress() << ", radius: " << circle.radius() << ", angle " << sweptAngle * RAD_TO_DEG << ", " << clockwiseness << std::endl; break; } case Gesture::TYPE_SWIPE: { SwipeGesture swipe = gesture; std::cout << std::string(2, ' ') << "Swipe id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", direction: " << swipe.direction() << ", speed: " << swipe.speed() << std::endl; break; } case Gesture::TYPE_KEY_TAP: { KeyTapGesture tap = gesture; std::cout << std::string(2, ' ') << "Key Tap id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", position: " << tap.position() << ", direction: " << tap.direction()<< std::endl; break; } case Gesture::TYPE_SCREEN_TAP: { ScreenTapGesture screentap = gesture; std::cout << std::string(2, ' ') << "Screen Tap id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", position: " << screentap.position() << ", direction: " << screentap.direction() << std::endl; break; } default: std::cout << std::string(2, ' ') << "Unknown gesture type." << std::endl; break; } } if (!frame.hands().isEmpty() || !gestures.isEmpty()) std::cout << std::endl; }
//-------------------------------------------------------------- void LeapVisualizer::drawArm (Hand & hand,ofxLeapMotion & leap){ // Draw the wrist and elbow points. Arm arm = hand.arm(); if (arm.isValid()){ ofPoint handPt = leap.getofPoint ( hand.palmPosition()); ofPoint handNorm = leap.getofPoint ( hand.palmNormal()); ofPoint wristPt = leap.getofPoint ( arm.wristPosition()); ofPoint elbowPt = leap.getofPoint ( arm.elbowPosition()); float basisLen = 50.0; if (bDrawSimple){ ofSetColor(ofColor::white); ofDrawSphere(handPt, 8.0); ofDrawSphere(wristPt, 8.0); ofDrawSphere(elbowPt, 8.0); ofLine(handPt, wristPt); ofLine(wristPt, elbowPt); ofLine(handPt, handPt+ basisLen*handNorm); ofDrawSphere(handPt+ basisLen*handNorm, 2.0); // draw the rotation vectors of the hand. { Leap::Matrix handMatrix = hand.basis(); ofPoint handBasisX = leap.getofPoint( handMatrix.xBasis); ofPoint handBasisY = leap.getofPoint( handMatrix.yBasis); ofPoint handBasisZ = leap.getofPoint( handMatrix.zBasis); glLineWidth(2.0); ofSetColor(ofColor::red ); ofLine(handPt, handPt + basisLen*handBasisX); ofSetColor(ofColor::green); ofLine(handPt, handPt + basisLen*handBasisY); ofSetColor(ofColor::blue ); ofLine(handPt, handPt + basisLen*handBasisZ); glLineWidth(1.0); // draw the identity of the hand (left or right) string whichHandString = "RIGHT"; if (hand.isLeft()){ whichHandString = "LEFT"; } // float handConfidence = hand.confidence(); // whichHandString += " " + ofToString(handConfidence); ofSetColor(ofColor::white); ofDrawBitmapString(whichHandString, (handPt + (basisLen*1.2)*handBasisY)); } // draw the rotation vectors of the arm. { Leap::Matrix armMatrix = arm.basis(); ofPoint armBasisX = leap.getofPoint( armMatrix.xBasis); ofPoint armBasisY = leap.getofPoint( armMatrix.yBasis); ofPoint armBasisZ = leap.getofPoint( armMatrix.zBasis); glLineWidth(2.0); ofSetColor(ofColor::red ); ofLine(wristPt, wristPt + basisLen*armBasisX); ofSetColor(ofColor::green); ofLine(wristPt, wristPt + basisLen*armBasisY); ofSetColor(ofColor::blue ); ofLine(wristPt, wristPt + basisLen*armBasisZ); glLineWidth(1.0); } } else { // Draw a cylinder between two points, properly oriented in space. float armWidth = arm.width(); float dx = wristPt.x - elbowPt.x; float dy = wristPt.y - elbowPt.y; float dz = wristPt.z - elbowPt.z; float dh = sqrt(dx*dx + dy*dy + dz*dz); ofPushMatrix(); { ofTranslate( (elbowPt.x+wristPt.x)/2, (elbowPt.y+wristPt.y)/2, (elbowPt.z+wristPt.z)/2 ); float theta = 90 - RAD_TO_DEG * asin(dz/dh); float phi = RAD_TO_DEG * atan2(dy,dx); ofRotate(phi, 0,0,1); ofRotate(theta, 0,1,0); ofRotate(90, 1,0,0); // Get the arm Matrix, which provides its orthogonal basis vectors. Leap::Matrix armMatrix = arm.basis(); ofPoint armBasisY = leap.getofPoint( armMatrix.yBasis); float ax = armBasisY.x; float ay = armBasisY.y; float az = armBasisY.z; // Compute the longitudinal rotation of the arm. // Sheesh, I really need to learn 3D matrix math. ofNode armBasisYNode; armBasisYNode.setPosition(armBasisY); armBasisYNode.rotateAround(0- phi, ofVec3f(0,0,1), ofVec3f(0,0,0)); armBasisYNode.rotateAround(0- theta, ofVec3f(0,1,0), ofVec3f(0,0,0)); armBasisYNode.rotateAround(0- 90, ofVec3f(1,0,0), ofVec3f(0,0,0)); ofPoint newArmBasisY = armBasisYNode.getPosition(); float armRotation = RAD_TO_DEG * atan2f(newArmBasisY.z, newArmBasisY.x); ofPushMatrix(); { ofRotate(armRotation, 0,-1,0); float armThicknessRatio = 0.6; glScalef(armThicknessRatio, 1.0, 1.0); ofSetColor(ofColor::magenta); // Oblate arm cylinder ofDrawCylinder (armWidth/2.0, dh); // Wrist endcap ofPushMatrix(); ofTranslate(ofPoint(0, dh/2,0)); glScalef(1.0, armThicknessRatio, 1.0); ofDrawSphere(armWidth/2.0); ofPopMatrix(); // Elbow endcap ofPushMatrix(); ofTranslate(ofPoint(0, -dh/2,0)); glScalef(1.0, armThicknessRatio, 1.0); ofDrawSphere(armWidth/2.0); ofPopMatrix(); } // Close popMatrix ofPopMatrix(); } // Close popMatrix ofPopMatrix(); } // Close if !drawSimple } // Close if arm isValid }
void QTVS_Leap::HandLogic() { //TODO: Fix this if (hands.count() == 1) { int iHandToFingerShift = hand.isLeft() ? 5 : 0; for (int iFingerCounter = iHandToFingerShift; iFingerCounter <= iHandToFingerShift + 4; iFingerCounter ++) QCoreApplication::postEvent(fingerTraces.at(iFingerCounter), new QHideEvent()); iHandToFingerShift = hand.isLeft() ? 0 : 5; if(ui.checkBox_ShowFingers->isChecked()) { for (int iFingerCounter = iHandToFingerShift; iFingerCounter <= iHandToFingerShift + 4; iFingerCounter ++) QCoreApplication::postEvent(fingerTraces.at(iFingerCounter), new QShowEvent()); } } else if (hands.isEmpty()) { foreach (FingerTraceWindow * fTrace, fingerTraces) QCoreApplication::postEvent(fTrace, new QHideEvent()); // QCoreApplication::postEvent(thumbTrace, new QHideEvent()); // QCoreApplication::postEvent(indexTrace, new QHideEvent()); // QCoreApplication::postEvent(middleTrace, new QHideEvent()); // QCoreApplication::postEvent(ringTrace, new QHideEvent()); // QCoreApplication::postEvent(pinkieTrace, new QHideEvent()); } else { if(ui.checkBox_ShowFingers->isChecked()) { foreach (FingerTraceWindow * fTrace, fingerTraces) QCoreApplication::postEvent(fTrace, new QShowEvent()); } // QCoreApplication::postEvent(thumbTrace, new QShowEvent()); // QCoreApplication::postEvent(indexTrace, new QShowEvent()); // QCoreApplication::postEvent(middleTrace, new QShowEvent()); // QCoreApplication::postEvent(ringTrace, new QShowEvent()); // QCoreApplication::postEvent(pinkieTrace, new QShowEvent()); } for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) { // Get the first hand hand = *hl; //TODO: Perhaps move this to gestures? if (ui.checkBox_Crunch->isChecked()) { if (hands.count() == 2) { // we check if one hand's dragging and the other's closed if (hand.isLeft()) { // if this hand is left, and the other hand (right) is dragging something.. if (debugWindowDrag_Right.left != -1) { debugDisplayString = QString::number(hand.grabStrength()); //pretty much closed if (hand.grabStrength() >= 0.7) { SendMessage(debugWindowHWND_Right, WM_SYSCOMMAND, SC_CLOSE, 0); // DestroyWindow(); } } } else { // if this hand is left, and the other hand (right) is dragging something.. if (debugWindowDrag_Left.left != -1) { //pretty much closed if (hand.grabStrength() >= 0.7) { // DestroyWindow(debugWindowHWND_Left); SendMessage(debugWindowHWND_Left, WM_SYSCOMMAND, SC_CLOSE, 0); } } } } } // std::string handType = hand.isLeft() ? "Left hand" : "Right hand"; // std::cout << std::string(2, ' ') << handType << ", id: " << hand.id() // << ", 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 // debugDisplayString = QString(", palm position: " + QString(hand.palmPosition().toString().data() )); // debugDisplayString = QString::number(hand.palmPosition().x); //20 // debugDisplayString.append("\n"); // debugDisplayString.append(QString::number(hand.palmPosition().y)); // 5 // debugDisplayString.append("\n"); // debugDisplayString.append(QString::number(hand.palmPosition().z)); // debugDisplayString.append("\n"); // debugDisplayString.append("roll:" + QString::number(normal.roll())); ///-------------------------------------------------- if (debug_extendedFingerCounter != 0 && ui.checkBox_palmMouse->isChecked()) HandCursorPosition(hand.stabilizedPalmPosition()); if (ui.checkBox_HandRollDrag->isChecked()) { if (bDebug_HandRollDrag) { if (normal.roll() > 0.7) { bDebug_HandRollDrag = false; if (debug_extendedFingerCounter != 0) MouseKeyboardEmulation::MouseLeftClickDown(); } } } if (!bDebug_HandRollDrag) { if (normal.roll() < 0.5) { bDebug_HandRollDrag = true; MouseKeyboardEmulation::MouseLeftClickUp(); } } ///----------------------------------------------- debug_extendedFingerCounter = 0; foreach (Finger finger, fingers) { if (finger.isExtended()) debug_extendedFingerCounter++; } // Fist Scrolling if (debug_extendedFingerCounter == 0 && ui.checkBox_palmScroll->isChecked()) { if (fFistPositionY == 0) fFistPositionY = hand.palmPosition().y; if (hand.palmPosition().y > fFistPositionY + 10) { float fDifference = hand.palmPosition().y - fFistPositionY + 10; fDifference /= 10; MouseKeyboardEmulation::MouseWheelUp(fDifference); } else if (hand.palmPosition().y < fFistPositionY - 10) { float fDifference = abs(hand.palmPosition().y - fFistPositionY - 10); fDifference /= 10; MouseKeyboardEmulation::MouseWheelUp(-1 * fDifference); } // debugDisplayString = QString::number(ThumbMiddleDifference_X); //20 // debugDisplayString.append("\n"); // debugDisplayString.append(QString::number(abs(middleFinger.stabilizedTipPosition().y - indexFinger.stabilizedTipPosition().y))); // 5 // debugDisplayString.append("\n"); // debugDisplayString.append(QString::number(debug_extendedFingerCounter)); //works // if(direction.pitch() * RAD_TO_DEG > 30) // MouseKeyboardEmulation::MouseWheelUp((direction.pitch() * RAD_TO_DEG)/10); // if(direction.pitch() * RAD_TO_DEG < 30) // MouseKeyboardEmulation::MouseWheelDown(5); } else { if (fFistPositionY != 0) fFistPositionY = 0; } // std::cout << std::string(2, ' ') << "pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " // << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " // << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; // Get the Arm bone Arm arm = hand.arm(); // std::cout << std::string(2, ' ') << "Arm direction: " << arm.direction() // << " wrist position: " << arm.wristPosition() // << " elbow position: " << arm.elbowPosition() << std::endl; // Get fingers fingers = hand.fingers(); FingerLogic(hand.isLeft() ? handLeft : handRight); } }