void ExampleTool::onLeapFrame( Leap::Frame const &aFrame ) { mHands = aFrame.hands().count(); mFingers = 0; for( int i = 0; i < mHands; ++ i ) mFingers += aFrame.hands()[ i ].fingers().count(); }
void HandController::drawHands() { glPushMatrix(); glTranslatef(translation_); glScalef(scale_, scale_, scale_); Leap::Frame frame = controller_.frame(); for (int h = 0; h < frame.hands().count(); ++h) { Leap::Hand hand = frame.hands()[h]; for (int f = 0; f < hand.fingers().count(); ++f) { Leap::Finger finger = hand.fingers()[f]; // Draw first joint inside hand. Leap::Bone mcp = finger.bone(Leap::Bone::Type::TYPE_METACARPAL); drawJoint(mcp.prevJoint()); for (int b = 0; b < 4; ++b) { Leap::Bone bone = finger.bone(static_cast<Leap::Bone::Type>(b)); drawJoint(bone.nextJoint()); drawBone(bone); } } } glPopMatrix(); }
void LeapMotionFrame::copyFromFrame(const Leap::Frame& frame, const F32& maxHandAxisRadius) { // This also resets all counters clear(); // Retrieve frame information mFrameValid = frame.isValid(); mFrameId = frame.id(); mFrameTimeStamp = frame.timestamp(); mFrameInternalId = smNextInternalFrameId; ++smNextInternalFrameId; mFrameSimTime = Sim::getCurrentTime(); mFrameRealTime = Platform::getRealMilliseconds(); if(!mFrameValid) { return; } // Retrieve hand information mHandCount = frame.hands().count(); if(mHandCount > 0) { copyFromFrameHands(frame.hands(), maxHandAxisRadius); } // Retrieve pointable information mPointableCount = frame.pointables().count(); if(mPointableCount > 0) { copyFromFramePointables(frame.pointables()); } }
void Quickstart::onFrame(const Leap::Controller &controller) { // returns the most recent frame. older frames can be accessed by passing in // a "history" parameter to retrieve an older frame, up to about 60 // (exact number subject to change) const Leap::Frame frame = controller.frame(); // do nothing unless hands are detected if (frame.hands().empty()) return; // first detected hand const Leap::Hand firstHand = frame.hands()[0]; // first pointable object (finger or tool) const Leap::PointableList pointables = firstHand.pointables(); if (pointables.empty()) return; const Leap::Pointable firstPointable = pointables[0]; // print velocity on the X axis cout << "Pointable X velocity: " << firstPointable.tipVelocity()[0] << endl; const Leap::FingerList fingers = firstHand.fingers(); if (fingers.empty()) return; for (int i = 0; i < fingers.count(); i++) { const Leap::Finger finger = fingers[i]; std::cout << "Detected finger " << i << " at position (" << finger.tipPosition().x << ", " << finger.tipPosition().y << ", " << finger.tipPosition().z << ")" << std::endl; } }
void LeapController::CopyHandsData( LeapFrame & a_frame_internal, Leap::Frame & a_frame_external ) { const Leap::Device & device = m_ctrl.devices()[0]; a_frame_internal.hands.clear(); a_frame_internal.hands.resize(a_frame_external.hands().count()); a_frame_internal.fingers.clear(); for ( int i_hand = 0; i_hand < a_frame_external.hands().count(); ++i_hand ) { const Leap::Hand & hand_ext = a_frame_external.hands()[i_hand]; // setup hand LeapHand & hand = a_frame_internal.hands[i_hand]; hand.id = hand_ext.id(); hand.fingers_count = 0; hand.dir = toV3( hand_ext.direction() ); hand.palm_normal = toV3( hand_ext.palmNormal() ); hand.palm_pos = toV3( hand_ext.palmPosition() ) * LEAP_SCALE; hand.palm_vel = toV3( hand_ext.palmVelocity() ) * LEAP_SCALE; hand.sphere_center = toV3( hand_ext.sphereCenter() ) * LEAP_SCALE; hand.sphere_radius = hand_ext.sphereRadius() * LEAP_SCALE; hand.age = hand_ext.timeVisible(); hand.dist_to_boundary = device.distanceToBoundary( hand_ext.palmPosition() ) * LEAP_SCALE; int hand_ext_finger_count = hand_ext.fingers().count(); // clamp the number of fingers if LEAP bugs out and returns hand with more than 5 fingers hand_ext_finger_count = max( hand_ext_finger_count, LEAP_MAX_NUM_FINGERS_PER_HAND ); //ASSERT( hand_ext_finger_count <= LEAP_MAX_NUM_FINGERS_PER_HAND ); for( int i_finger = 0; i_finger < hand_ext_finger_count; ++i_finger ) { const Leap::Finger & finger_ext = hand_ext.fingers()[i_finger]; if ( finger_ext.isValid() ) { // alloc new finger a_frame_internal.fingers.resize( a_frame_internal.fingers.size()+1 ); LeapFinger &finger = a_frame_internal.fingers.back(); finger.id = finger_ext.id(); finger.hand_id = hand.id; finger.hand_index = (int)i_hand; finger.finger_size = v2( finger_ext.width(), finger_ext.length() ) * LEAP_SCALE; finger.dir = toV3( finger_ext.direction() ); finger.tip_pos = toV3( finger_ext.tipPosition() ) * LEAP_SCALE; finger.tip_vel = toV3( finger_ext.tipVelocity() ) * LEAP_SCALE; finger.age = finger_ext.timeVisible(); finger.tip_pos_stabilized = toV3( finger_ext.stabilizedTipPosition() ) * LEAP_SCALE; finger.dist_to_boundary = device.distanceToBoundary( finger_ext.tipPosition() ) * LEAP_SCALE; // add finger hand.fingers_index[hand.fingers_count] = (int)a_frame_internal.fingers.size()-1; ++hand.fingers_count; } } } }
void ManipTool::onLeapFrame( Leap::Frame const &aFrame ) { if( (aFrame.timestamp() - mLastExaminedFrame ) < 16*1000 ) return; if( aFrame.hands().count() > 2 ) return; mLastExaminedFrame = aFrame.timestamp(); U16 curFrame = getNextFrameNo( mLastStoredFrame ); Fingers &curFingers = mFingersPerFrame[ curFrame ]; U16 curFinger = 0; curFingers.clear(); curFingers.mTimestamp = mLastExaminedFrame; Leap::HandList hands = aFrame.hands(); for( int i = 0; i < hands.count(); ++i ) { for( int j = 0; j < hands[i].fingers().count(); ++j ) { Leap::Finger oFinger( hands[i].fingers()[j] ); Finger &oF = curFingers.mFingers[ curFinger++ ]; oF.mId = oFinger.id(); oF.mTimestamp = mLastExaminedFrame; copy( oFinger.direction(), oF.mDir ); copy( oFinger.tipPosition(), oF.mTip ); oF.mWidth = oFinger.width(); oF.mLength = oFinger.length(); } } curFingers.mStoredFingers = curFinger; if( mTotalStoredFrames > 0 ) { Fingers &prevFingers = mFingersPerFrame[ mLastStoredFrame ]; for( U16 i = 0; i < curFingers.mStoredFingers; ++i ) { Finger &curFinger = curFingers.mFingers[i]; Finger const *prevFinger = prevFingers.getFinger( curFinger.mId ); if( !prevFinger ) continue; subtract( curFinger.mTip, prevFinger->mTip, curFinger.mFromLast ); curFinger.mLenFromLast = normalize( curFinger.mFromLast ); } } mLastStoredFrame = curFrame; ++mTotalStoredFrames; }
pinch_list HandController::getPinches() { Leap::Frame frame = controller_.frame(); pinch_list pinches; for (int i = 0; i < frame.hands().count(); ++i) { float pinch_strength = frame.hands()[i].pinchStrength(); Leap::Vector tip = frame.hands()[i].fingers()[1].tipPosition(); Vec3f transformed_tip = scale_ * ToVec3f(tip) + translation_; pinches.push_back(std::pair<Vec3f, float>(transformed_tip, pinch_strength)); } return pinches; }
void MouseController::onFrame(const Leap::Controller &controller) { // get list of detected screens const Leap::ScreenList screens = controller.calibratedScreens(); // make sure we have a detected screen if (screens.empty()) return; const Leap::Screen screen = screens[0]; // find the first finger or tool const Leap::Frame frame = controller.frame(); const Leap::HandList hands = frame.hands(); if (hands.empty()) return; const Leap::PointableList pointables = hands[0].pointables(); if (pointables.empty()) return; const Leap::Pointable firstPointable = pointables[0]; // get x, y coordinates on the first screen const Leap::Vector intersection = screen.intersect( firstPointable, true, // normalize 1.0f // clampRatio ); // if the user is not pointing at the screen all components of // the returned vector will be Not A Number (NaN) // isValid() returns true only if all components are finite if (! intersection.isValid()) return; unsigned int x = screen.widthPixels() * intersection.x; // flip y coordinate to standard top-left origin unsigned int y = screen.heightPixels() * (1.0f - intersection.y); CGPoint destPoint = CGPointMake(x, y); CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, destPoint); }
void CinderProjectApp::draw() { // Clear window gl::setViewport( getWindowBounds() ); gl::clear( Colorf::black() ); gl::setMatrices( mCamera ); // Iterate through hands const Leap::HandList& hands = mFrame.hands(); for ( Leap::HandList::const_iterator handIter = hands.begin(); handIter != hands.end(); ++handIter ) { const Leap::Hand& hand = *handIter; // Draw palm gl::color(1, .2, .4, 1); gl::drawSphere(LeapMotion::toVec3f(hand.palmPosition()),20,12); // Pointables const Leap::PointableList& pointables = hand.pointables(); for ( Leap::PointableList::const_iterator pointIter = pointables.begin(); pointIter != pointables.end(); ++pointIter ) { const Leap::Pointable& pointable = *pointIter; Vec3f dir = LeapMotion::toVec3f( pointable.direction() ); float length = pointable.length(); Vec3f tipPos = LeapMotion::toVec3f( pointable.tipPosition() ); Vec3f basePos = tipPos + dir * length; gl::drawColorCube( tipPos, Vec3f( 20, 20, 20 ) ); gl::color( ColorAf::gray( 0.8f ) ); gl::drawLine( basePos, tipPos ); } } }
// Runs update logic void TracerApp::update() { // Update frame rate mFrameRate = getAverageFps(); // Process hand data const Leap::HandList& hands = mFrame.hands(); for ( Leap::HandList::const_iterator handIter = hands.begin(); handIter != hands.end(); ++handIter ) { const Leap::Hand& hand = *handIter; const Leap::PointableList& pointables = hand.pointables(); for ( Leap::PointableList::const_iterator pointIter = pointables.begin(); pointIter != pointables.end(); ++pointIter ) { const Leap::Pointable& pointable = *pointIter; int32_t id = pointable.id(); if ( mRibbons.find( id ) == mRibbons.end() ) { Vec3f v = randVec3f() * 0.01f; v.x = math<float>::abs( v.x ); v.y = math<float>::abs( v.y ); v.z = math<float>::abs( v.z ); Colorf color( ColorModel::CM_RGB, v ); Ribbon ribbon( id, color ); mRibbons[ id ] = ribbon; } float width = math<float>::abs( pointable.tipVelocity().y ) * 0.0025f; width = math<float>::max( width, 5.0f ); mRibbons[ id ].addPoint( LeapMotion::toVec3f( pointable.tipPosition() ), width ); } } // Update ribbons for ( RibbonMap::iterator iter = mRibbons.begin(); iter != mRibbons.end(); ++iter ) { iter->second.update(); } }
// Runs update logic void UiApp::update() { // Update frame rate mFrameRate = getAverageFps(); // Toggle fullscreen if ( mFullScreen != isFullScreen() ) { setFullScreen( mFullScreen ); } // Interact with first hand const Leap::HandList& hands = mFrame.hands(); if ( hands.isEmpty() ) { mCursorType = CursorType::NONE; } else { const Leap::Hand& hand = *hands.begin(); // Update cursor position mCursorPositionTarget = warpVector( hand.palmPosition() ); if ( mCursorType == CursorType::NONE ) { mCursorPosition = mCursorPositionTarget; } // Choose cursor type based on number of exposed fingers switch ( hand.fingers().count() ) { case 0: mCursorType = CursorType::GRAB; // Slider if ( mSlider.getBounds().contains( mCursorPosition - mSliderPosition ) ) { float x1 = mTrackPosition.x; float x2 = mTrackPosition.x + (float)( mTrack.getWidth() - mSlider.getWidth() ); mSliderPosition.x = math<float>::clamp( mCursorPosition.x, x1, x2 ); } break; case 1: mCursorType = CursorType::TOUCH; // Buttons mFingerTipPosition = warpPointable( *hand.fingers().begin() ); for ( size_t i = 0; i < 3; ++i ) { mButtonState[ i ] = false; if ( mButton[ 0 ].getBounds().contains( mFingerTipPosition - mButtonPosition[ i ] ) ) { mButtonState[ i ] = true; } } break; default: mCursorType = CursorType::HAND; break; } } // Smooth cursor animation mCursorPosition = mCursorPosition.lerp( 0.21f, mCursorPositionTarget ); }
void ClipController::clip2H(const Leap::Frame& frame) { Hand hand = frame.hands().rightmost(); Hand other_hand = frame.hands().leftmost(); if (other_hand.grabStrength() > 0.95f) { VolumeController& vc = MainController::getInstance().volumeController(); const Mat4& inv = vc.getCamera().viewInverse(); Vec3 n = inv * hand.palmNormal().toVector4<Vec4>(); Vec3 p = frame.interactionBox().normalizePoint(hand.palmPosition()).toVector4<Vec4>(); p = (p - 0.5f) * 2.0f * 0.75f; p = inv * Vec4(p.x, p.y, p.z, 0.0f); selectedPlane().normal(n); selectedPlane().point(p); vc.markDirty(); } }
static VALUE frame_hands(VALUE self) { Leap::Frame * f; Leap::HandList * list; Data_Get_Struct(self, Leap::Frame, f); list = new Leap::HandList(f->hands()); return WrapHandList(list); }
fdata get_finger_positions() { Leap::Frame frame = control.frame(); Leap::FingerList fingers = frame.fingers(); Leap::ToolList tools = frame.tools(); Leap::HandList hands = frame.hands(); //std::vector<std::pair<cl_float4, int>> positions; fdata hand_data; int p = 0; for(int i=0; i<40; i++) { hand_data.fingers[i] = 0.0f; } ///will explode if more than 2 for(int i=0; i<hands.count(); i++) { const Leap::Hand hand = hands[i]; Leap::FingerList h_fingers = hand.fingers(); float grab_strength = hand.grabStrength(); hand_data.grab_confidence[i] = grab_strength; for(int j=0; j<h_fingers.count(); j++) { const Leap::Finger finger = h_fingers[j]; float mfingerposx = finger.tipPosition().x; float mfingerposy = finger.tipPosition().y; float mfingerposz = finger.tipPosition().z; //cl_float4 ps = {mfingerposx, mfingerposy, mfingerposz, 0.0f}; //cl_float4 ps = {mfingerposx, mfingerposy, mfingerposz, 0.0f}; int id = finger.id(); hand_data.fingers[p++] = mfingerposx; hand_data.fingers[p++] = mfingerposy; hand_data.fingers[p++] = mfingerposz; hand_data.fingers[p++] = 0.0f; //positions.push_back(std::pair<cl_float4, int>(ps, id)); } } return hand_data; }
void Quickstart::onFrame(const Leap::Controller &controller) { // returns the most recent frame. older frames can be accessed by passing in // a "history" parameter to retrieve an older frame, up to about 60 // (exact number subject to change) const Leap::Frame frame = controller.frame(); // do nothing unless hands are detected if (frame.hands().empty()) return; // retrieve first pointable object (finger or tool) // from the frame const Leap::PointableList pointables = frame.hands()[0].pointables(); if (pointables.empty()) return; const Leap::Pointable firstPointable = pointables[0]; // print velocity on the X axis cout << "Pointable X velocity: " << firstPointable.tipVelocity()[0] << endl; }
void eleap::eleap_t::impl_t::onFrame(const Leap::Controller& controller) { const Leap::Frame frame = controller.frame(); if (frame.isValid()) { // send the known hands in this frame, this will handle hands coming and going const Leap::HandList hands = frame.hands(); { unsigned long long time_encoded = (0&0xffffffff)<<8 | (DATA_KNOWN_HANDS&0xff); float *f; unsigned char *dp; piw::data_nb_t d = ctx_.allocate_host(time_encoded,INT32_MAX,INT32_MIN,0,BCTVTYPE_INT,sizeof(int32_t),&dp,hands.count(),&f); memset(f,0,hands.count()*sizeof(int32_t)); *dp = 0; for(int i = 0; i < hands.count(); ++i) { const Leap::Hand hand = hands[i]; if(hand.isValid() && hand.fingers().count() > 1) { ((int32_t *)f)[i] = hand.id(); } } enqueue_fast(d,1); } // handle the actual data for the detected hands for(int i = 0; i < hands.count(); ++i) { const Leap::Hand hand = hands[i]; if(hand.isValid() && hand.fingers().count() > 1) { unsigned long long time_encoded = (hand.id()&0xffffffff)<<8 | (DATA_PALM_POSITION&0xff); const Leap::Vector palm_pos = hand.palmPosition(); float *f; unsigned char *dp; piw::data_nb_t d = ctx_.allocate_host(time_encoded,600,-600,0,BCTVTYPE_FLOAT,sizeof(float),&dp,3,&f); memset(f,0,3*sizeof(float)); *dp = 0; f[0] = piw::normalise(600,-600,0,palm_pos.x); f[1] = piw::normalise(600,-600,0,palm_pos.y); f[2] = piw::normalise(600,-600,0,palm_pos.z); enqueue_fast(d,1); } } } }
GestureFrame LMRecorder::prepareDataClone(const Leap::Frame frame, double timestamp) { GestureFrame outputFrame; outputFrame.setTimestamp(timestamp); Leap::HandList handsInFrame = frame.hands(); for(int handIndex=0; handIndex<handsInFrame.count(); handIndex++) { Leap::Hand currHand = handsInFrame[handIndex]; //create GestureHand GestureHand gestureHand( currHand.id(), Vertex(currHand.palmPosition().x, currHand.palmPosition().y, currHand.palmPosition().z), Vertex(0, 0, 0/*currHand.stabilizedPalmPosition().x, currHand.stabilizedPalmPosition().y, currHand.stabilizedPalmPosition().z*/), Vertex(currHand.palmNormal().x, currHand.palmNormal().y, currHand.palmNormal().z), Vertex(currHand.direction().x, currHand.direction().y, currHand.direction().z) ); gestureHand.setOrderValue(currHand.palmPosition().x); Vertex planeNormalVec = gestureHand.getDirection().crossProduct(gestureHand.getPalmNormal()).getNormalized(); Leap::FingerList fingersInCurrHand = currHand.fingers(); for (int fingerIndex=0; fingerIndex<fingersInCurrHand.count(); fingerIndex++) { Leap::Finger currFinger = fingersInCurrHand[fingerIndex]; Leap::Vector leapFingerTipPos = currFinger.tipPosition(); Vertex fingerTipPos(leapFingerTipPos.x, leapFingerTipPos.y, leapFingerTipPos.z); float distance = getPointDistanceFromPlane(fingerTipPos, gestureHand.getPalmPosition(), planeNormalVec); //create GestureFinger GestureFinger gestureFinger( currFinger.id(), fingerTipPos, Vertex(currFinger.stabilizedTipPosition().x, currFinger.stabilizedTipPosition().y, currFinger.stabilizedTipPosition(). z), Vertex(currFinger.direction().x, currFinger.direction().y, currFinger.direction().z), currFinger.length(), currFinger.width() ); gestureFinger.setOrderValue(distance); gestureHand.addFinger(gestureFinger); } gestureHand.sortFingers(); outputFrame.addHand(gestureHand); } outputFrame.sortHands(); }
virtual void onFrame (const Leap::Controller&) { const Leap::Frame frame(m_Controller.frame(0)); const Leap::Hand hand(frame.hands().rightmost()); if (!hand.isValid()) { m_LastNormalizedPos.reset(); return; } const Leap::Vector pos(hand.palmPosition()); m_LastNormalizedPos = frame.interactionBox().normalizePoint(pos); }
void BallGesture::recognizedControls(const Leap::Controller &controller, std::vector<ControlPtr> &controls) { Leap::Frame frame = controller.frame(); // hands detected? if (frame.hands().isEmpty()) return; for (int i = 0; i < frame.hands().count(); i++) { // gonna assume the user only has two hands. sometimes leap thinks otherwise. if (i > 1) break; Leap::Hand hand = frame.hands()[i]; double radius = hand.sphereRadius(); // in mm if (! radius) continue; BallRadiusPtr bc = make_shared<BallRadius>(radius, i); ControlPtr cptr = dynamic_pointer_cast<Control>(bc); controls.push_back(cptr); } }
virtual void onFrame(const Leap::Controller& controller) { Leap::Frame frame = controller.frame(); const Leap::HandList& hands = frame.hands(); if (hands.count() > 0) { Leap::Vector newTarget = hands[0].stabilizedPalmPosition(); cout << "New Target: " << newTarget << endl; if (inMotion) { //TODO: must merge with currentTarget, to account for if the //target hand moved...for now, do nothing } else { inMotion = true; currentTarget = WorldVector(newTarget, leapPos); } } }
void GestureApp::drawPointables() { gl::color( ColorAf::white() ); const Leap::HandList& hands = mFrame.hands(); for ( Leap::HandList::const_iterator handIter = hands.begin(); handIter != hands.end(); ++handIter ) { const Leap::Hand& hand = *handIter; const Leap::PointableList& pointables = hand.pointables(); for ( Leap::PointableList::const_iterator pointIter = pointables.begin(); pointIter != pointables.end(); ++pointIter ) { const Leap::Pointable& pointable = *pointIter; vec2 pos( warpPointable( pointable ) ); drawDottedCircle( pos, mPointableRadius, mDotRadius * 0.5f, mCircleResolution / 2 ); } } }
int StateKen::eventShake(StateContext& context, const Leap::Controller& controller) { std::cout << "けん\n" << std::endl; const Leap::Frame frame = controller.frame(); const Leap::Hand hand = frame.hands()[0]; Leap::Vector position = hand.palmPosition(); JankenApp::getInstance()->setShakeStartPosition(position); int ret = context.changeState(StatePon::getInstance()); return ret; }
bool ClipController::leapInput(const Leap::Controller& controller, const Leap::Frame& frame) { if (frame.hands().count() == 2) { clip2H(frame); return false; } v_pose_.update(frame); if (v_pose_.tracking()) { clip1H(frame); return false; } cam_control_.update(controller, frame); return false; }
void LeapMotionPlugin::processFrame(const Leap::Frame& frame) { // Default to uncontrolled. for (int i = 0; i < _joints.size(); i++) { _joints[i].position = glm::vec3(); } auto hands = frame.hands(); const int MAX_NUMBER_OF_HANDS = 2; for (int i = 0; i < hands.count() && i < MAX_NUMBER_OF_HANDS; i++) { auto hand = hands[i]; int sideSign = hand.isLeft() ? LEFT_SIDE_SIGN : RIGHT_SIDE_SIGN; int jointIndex = hand.isLeft() ? LeapMotionJointIndex::LeftHand : LeapMotionJointIndex::RightHand; // Hand. _joints[jointIndex].position = LeapVectorToVec3(hand.wristPosition()); _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, hand.basis()); // Fingers. // Leap Motion SDK guarantees full set of fingers and finger joints so can straightforwardly process them all. Leap::FingerList fingers = hand.fingers(); for (int j = Leap::Finger::Type::TYPE_THUMB; j <= Leap::Finger::Type::TYPE_PINKY; j++) { Leap::Finger finger; finger = fingers[j]; Leap::Bone bone; bone = finger.bone(Leap::Bone::Type::TYPE_PROXIMAL); jointIndex++; _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); bone = finger.bone(Leap::Bone::Type::TYPE_INTERMEDIATE); jointIndex++; _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); bone = finger.bone(Leap::Bone::Type::TYPE_DISTAL); jointIndex++; _joints[jointIndex].position = LeapVectorToVec3(bone.prevJoint()); _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); jointIndex++; _joints[jointIndex].position = LeapVectorToVec3(bone.nextJoint()); _joints[jointIndex].orientation = LeapBasisToQuat(sideSign, bone.basis()); } } }
void LeapMotionListener::onFrame(const Leap::Controller & controller) { const Leap::Frame frame = controller.frame(); Leap::HandList hands = frame.hands(); for (Leap::HandList::const_iterator hl = hands.begin(); hl!=hands.end();hl++) { const Leap::Hand hand = *hl; QString handType = hand.isLeft() ? "Left hand" : "Right hand"; qDebug()<<handType<<"id: "<<hand.id()<<"palm position: " <<hand.palmPosition().x<<hand.palmPosition().y<<hand.palmPosition().z; QFile f("share.dat"); if(!f.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&f); out<<QString("%1 %2 %3").arg(hand.palmPosition().x) .arg(hand.palmPosition().y).arg(hand.palmPosition().z); f.close(); } }
void jester::LeapMotionImpl::processLeapFrame(Leap::Frame frame) { Leap::HandList handList = frame.hands(); std::vector<Leap::Hand> hands; Leap::Hand right, left; bool foundRight = false, foundLeft = false; clearJointData(); //put all of the hands in a std::vector for (Leap::HandList::const_iterator handsIter = handList.begin(); handsIter != handList.end(); handsIter++) hands.push_back(*handsIter); std::sort(hands.begin(), hands.end(), finger_count_comparator); //search to see if last known hand Ids are still available, assign hand, and delete from available hands // also, delete any unknown hands that have no fingers for (unsigned int i = 0; i < hands.size(); i++) if (hands[i].id() == kRightHandId) { foundRight = true; right = hands[i]; hands.erase(hands.begin() + i); } else if (hands[i].id() == kLeftHandId) { foundLeft = true; left = hands[i]; hands.erase(hands.begin() + i); } else if (hands[i].fingers().count() == 0){ hands.erase(hands.begin() + i); } //figure out how many hands we need int neededHands = 0; if (!foundLeft) neededHands++; if (!foundRight) neededHands++; //assume that the highest finger count objects are the most likely to be hands //only keep as many hands as we need (bounded by the number actually available) hands.erase(hands.begin() + std::min((int) hands.size(), neededHands), hands.end()); //sort by x coordinate std::sort(hands.begin(), hands.end(), hand_x_coordinate_comparator); if (hands.size() == 0 || neededHands == 0) { //if we have or need no hands, do nothing here } else if (neededHands > (int) hands.size()) { //if we need two and only have 1 //assume left side is left, right side is right if (hands[0].palmPosition()[0] < 0) { foundLeft = true; left = hands[0]; kLeftHandId = left.id(); } else { foundRight = true; right = hands[0]; kRightHandId = right.id(); } } else if (foundLeft == false && neededHands == 1) { //if we need left foundLeft = true; left = hands[0]; kLeftHandId = left.id(); } else if (foundRight == false && neededHands == 1) { //if we need right foundRight = true; right = hands[hands.size() - 1]; kRightHandId = right.id(); } else { //if we need both and have two foundLeft = foundRight = true; left = hands[0]; kLeftHandId = left.id(); right = hands[1]; kRightHandId = right.id(); } if (foundLeft) processHand(left, LeapHand::LEFT); if (foundRight) processHand(right, LeapHand::RIGHT); kController->suggestJointInfo(this, kJointData); }
void LeapListener::onFrame(const Leap::Controller& controller) { // Get the most recent frame and report some basic information const Leap::Frame frame = controller.frame(); /*std::cout << "Frame id: " << frame.id() << ", timestamp: " << frame.timestamp() << ", hands: " << frame.hands().count() << ", fingers: " << frame.fingers().count() << ", tools: " << frame.tools().count() << ", gestures: " << frame.gestures().count(); */ if (!frame.hands().isEmpty()) { // Get the first hand const Leap::Hand hand = frame.hands()[0]; qDebug() << "Radius: " << hand.sphereRadius(); // Grab if(hand.sphereRadius() < 50.0 && hand.translationProbability(controller.frame(1)) > 0.6){ Leap::Vector v = hand.translation(controller.frame(1)); v = 0.1 * v; glwidget_->camera_.translate(v.x, v.y, v.z); glwidget_->update(); } qDebug() << "Hand pos" << hand.palmPosition().x << hand.palmPosition().y << hand.palmPosition().z; if(frame.fingers().count() > 200 && frame.hands().count() == 1){ Leap::Vector trans = hand.translation(controller.frame(1)); //int dir = trans.y > 0 ? 1 : -1; trans = 0.1 * trans; //glwidget_->camera_.translate(0, 0, dir*0.1); //Leap::Vector rot = hand.rotationAxis(controller.frame()); float yaw = hand.rotationAngle(controller.frame(1), Leap::Vector(1, 0, 0)); float pitch = hand.rotationAngle(controller.frame(1), Leap::Vector(1, 0, 0)); // works float roll = hand.rotationAngle(controller.frame(1), Leap::Vector(0, 0, 1)); //qDebug() << yaw << pitch << roll; glwidget_->camera_.rotate3D(yaw, pitch, roll); //glwidget_->camera_.rotate2D(0.01 * trans.x, 0.01 * trans.y); glwidget_->update(); } /* // Check if the hand has any fingers const Leap::FingerList fingers = hand.fingers(); if (!fingers.empty()) { // Calculate the hand's average finger tip position Leap::Vector avgPos; for (int i = 0; i < fingers.count(); ++i) { avgPos += fingers[i].tipPosition(); } avgPos /= (float)fingers.count(); std::cout << "Hand has " << fingers.count() << " fingers, average finger tip position" << avgPos<< std::endl; } // Get the hand's sphere radius and palm position std::cout << "Hand sphere radius: " << hand.sphereRadius() << " mm, palm position: " << hand.palmPosition() << std::endl; // Get the hand's normal vector and direction const Leap::Vector normal = hand.palmNormal(); const Leap::Vector direction = hand.direction(); // Calculate the hand's pitch, roll, and yaw angles std::cout << "Hand pitch: " << direction.pitch() * Leap::RAD_TO_DEG << " degrees, " << "roll: " << normal.roll() * Leap::RAD_TO_DEG << " degrees, " << "yaw: " << direction.yaw() * Leap::RAD_TO_DEG << " degrees"<< std::endl; } // Get gestures const Leap::GestureList gestures = frame.gestures(); for (int g = 0; g < gestures.count(); ++g) { Leap::Gesture gesture = gestures[g]; switch (gesture.type()) { case Leap::Gesture::TYPE_CIRCLE: { Leap::CircleGesture circle = gesture; std::string clockwiseness; if (circle.pointable().direction().angleTo(circle.normal()) <= M_PI/4) { clockwiseness = "clockwise"; } else { clockwiseness = "counterclockwise"; } // Calculate angle swept since last frame float sweptAngle = 0; if (circle.state() != Leap::Gesture::STATE_START) { Leap::CircleGesture previousUpdate = Leap::CircleGesture(controller.frame().gesture(circle.id())); sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * M_PI; } std::cout << "Circle id: " << gesture.id() << ", state: " << gesture.state() << ", progress: " << circle.progress() << ", radius: " << circle.radius() << ", angle " << sweptAngle * Leap::RAD_TO_DEG << ", " << clockwiseness << std::endl; break; } case Leap::Gesture::TYPE_SWIPE: { Leap::SwipeGesture swipe = gesture; std::cout << "Swipe id: " << gesture.id() << ", state: " << gesture.state() << ", direction: " << swipe.direction() << ", speed: " << swipe.speed() << std::endl; break; } case Leap::Gesture::TYPE_KEY_TAP: { Leap::KeyTapGesture tap = gesture; std::cout << "Key Tap id: " << gesture.id() << ", state: " << gesture.state() << ", position: " << tap.position() << ", direction: " << tap.direction()<< std::endl; break; } case Leap::Gesture::TYPE_SCREEN_TAP: { Leap::ScreenTapGesture screentap = gesture; std::cout << "Screen Tap id: " << gesture.id() << ", state: " << gesture.state() << ", position: " << screentap.position() << ", direction: " << screentap.direction()<< std::endl; break; } default: std::cout << "Unknown gesture type."; break; } */ } }
int main() { //Leap Motion Vairables Leap::Controller controller; Leap::Frame frame; Leap::HandList hands; Leap::Hand h1; Leap::FingerList fingers; Leap::Finger index; Leap::Finger thumb; Leap::PointableList pointables; float indexX = 0, indexY = 0, indexZ = 0, thumbX = 0, thumbY = 0, thumbZ = 0, sum = 0; unsigned long cycles = 0; // TCP Variables WSADATA wsaData; SOCKET connectSocket = INVALID_SOCKET; struct addrinfo* result = NULL; struct addrinfo* ptr = NULL; struct addrinfo hints; char cSendBuf[512][512]; char sSendBuf[512]; int iResult; int recvBufLen = DEFAULT_BUFLEN; int i = 0; iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } // Initialize all address info to 0 to start. SecureZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; // Doesn't matter if we use IPV4 or IPV6 hints.ai_socktype = SOCK_STREAM; // TCP Stream sockets hints.ai_protocol = IPPROTO_TCP; // Resolve the server address and port iResult = getaddrinfo("127.0.0.1", DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Attempt to connect to an address until one succeeds for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { // create a socket for connecting to the server connectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (connectSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } // Connect to the server iResult = connect(connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(connectSocket); connectSocket = INVALID_SOCKET; continue; } break; } // Deallocate the address info freeaddrinfo(result); if (connectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"); WSACleanup(); return 1; } // Setup serial port connection and needed variables. SerialPort.Open(PORT_NUM, BAUD); Controller[20].value = 9; //Verification Byte sent to make sure everything else ends up in the right location FillByteSize(); while (true) { cycles++; UpdateControllerState(); //Updates all values on the controller WORD wButtons = g_Controllers[CONTROLLER1].state.Gamepad.wButtons; //Stores all of the values from the controller into the controller structure Controller[0].value = g_Controllers[CONTROLLER1].state.Gamepad.sThumbRX; Controller[1].value = g_Controllers[CONTROLLER1].state.Gamepad.sThumbRY; Controller[2].value = g_Controllers[CONTROLLER1].state.Gamepad.sThumbLX; Controller[3].value = g_Controllers[CONTROLLER1].state.Gamepad.sThumbLY; Controller[4].value = (g_Controllers[CONTROLLER1].state.Gamepad.bRightTrigger); Controller[5].value = (g_Controllers[CONTROLLER1].state.Gamepad.bLeftTrigger); Controller[6].value = (wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); Controller[7].value = (wButtons & XINPUT_GAMEPAD_LEFT_THUMB); Controller[8].value = (wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER); Controller[9].value = (wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER); Controller[10].value = (wButtons & XINPUT_GAMEPAD_DPAD_UP); Controller[11].value = (wButtons & XINPUT_GAMEPAD_DPAD_DOWN); Controller[12].value = (wButtons & XINPUT_GAMEPAD_DPAD_LEFT); Controller[13].value = (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT); Controller[14].value = (wButtons & XINPUT_GAMEPAD_A); Controller[15].value = (wButtons & XINPUT_GAMEPAD_B); Controller[16].value = (wButtons & XINPUT_GAMEPAD_Y); Controller[17].value = (wButtons & XINPUT_GAMEPAD_X); Controller[18].value = (wButtons & XINPUT_GAMEPAD_START); Controller[19].value = (wButtons & XINPUT_GAMEPAD_BACK); CheckDeadZone(); if (controller.isConnected() == true) { sum = 0; frame = controller.frame(); hands = frame.hands(); h1 = hands[0]; fingers = frame.fingers(); thumb = fingers[0]; index = fingers[1]; pointables = frame.pointables(); Leapvalues[0].value = h1.palmVelocity().x; Leapvalues[1].value = h1.palmVelocity().y; Leapvalues[2].value = h1.palmVelocity().z; Leapvalues[3].value = h1.direction().pitch()*Leap::RAD_TO_DEG; Leapvalues[4].value = h1.direction().yaw()*Leap::RAD_TO_DEG; Leapvalues[5].value = h1.direction().roll()*Leap::RAD_TO_DEG; indexX = index.tipPosition().x; indexY = index.tipPosition().y; indexZ = index.tipPosition().z; thumbX = thumb.tipPosition().x; thumbY = thumb.tipPosition().y; thumbZ = thumb.tipPosition().z; Leapvalues[6].value = sqrt(pow((indexX - thumbX), 2) + pow((indexY - thumbY), 2) + pow((indexZ - thumbZ), 2)); leapConnected = true; CheckLeapDeadZone(); } for (i = 6; i < NUMBER_OF_BUTTONS; i++) //DO NOT SET TO <= NUMBER_OF_BUTTONS, NOT A MISTAKE. Verification bit should always keep its value { { Controller[i].value = AnalogToDigital(Controller[i].value); //converts all of the button presses on the controller to a binary value } } //turns all of the numerical values into buffers that can be passed to the arduino for (i = 0; i <= NUMBER_OF_BUTTONS; i++) { _itoa_s(Controller[i].value, Controller[i].passedValue, 10); } /* for (i = 0; i < NUMBER_OF_BUTTONS; i++) { _itoa_s(Controller[i].value, cSendBuf[i], 10); cSendBuf[i][strlen(cSendBuf[i])] = '\0'; iResult = send(connectSocket, cSendBuf[0], (int)strlen(cSendBuf[0]), 0); printf("String sent: %s\n", cSendBuf[0]); // Check for errors if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(connectSocket); WSACleanup(); return 1; } } // Try to send the packet iResult = send(connectSocket, "\n", (int)strlen("\n"), 0); //printf("String sent: %s\n", sendBuf); // Check for errors if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(connectSocket); WSACleanup(); return 1; }*/ if (leapConnected = true) { for (i = 0; i < NUMBER_OF_LEAP_INPUTS; i++) { _itoa_s(Leapvalues[i].value, Leapvalues[i].passedValue, 10); } } /*Values recieved in this order: 0) YAW 1) PITCH 2) ROLL 3) ACCELERATION ON X AXIS 4) ACCELERATION ON Y AXIS 5) ACCELERATION ON Z AXIS 6) SONAR SENSOR DISTANCE (IN METERS) */ if (SendData() == 1) { for (i = 0; i < 7; i++) { while (SerialPort.ReadDataWaiting() < 3) { } if (i > 2 && i < 6) SerialPort.ReadData(received[i], 5); else SerialPort.ReadData(received[i], 4); std::cout << received[i] << ' '; // Added this 6.25.14 strcpy(sSendBuf, received[i]); sSendBuf[strlen(sSendBuf)] = '\0'; iResult = send(connectSocket, sSendBuf, (int)strlen(sSendBuf), 0); printf("String sent: %s\n", sSendBuf); // Check for errors if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(connectSocket); WSACleanup(); return 1; } // Try to send the packet iResult = send(connectSocket, "\n", (int)strlen("\n"), 0); //printf("String sent: %s\n", sendBuf); // Check for errors if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(connectSocket); WSACleanup(); return 1; } } } //std::cout << recieved[0]; printf("\t%d", cycles); printf("\n"); //Sleep(500); <<'\t' << recieved[1] } closesocket(connectSocket); WSACleanup(); return 0; }
//-------------------------------------------------------------- void testApp::draw(){ ofSetWindowTitle(ofToString(ofGetFrameRate())); //camera.begin(); float r0 = 30; Leap::Vector ptp; Leap::Vector ptp0; Leap::Vector pNormal; ofPushMatrix(); ofTranslate(ofGetWidth()/2, ofGetHeight()); //ofSetColor(255, 255, 255); Leap::Frame frame = leapController.frame(); Leap::HandList hands = frame.hands(); if (!hands.isEmpty()) { //ofLogNotice("hand detected"); int count = hands.count(); for (int i = 0; i<count; i++) { if (i>1) break; Leap::Hand tempHand = hands[i]; pNormal = tempHand.palmNormal(); ofLogNotice("hand " +ofToString(i) + "normal", ofToString(pNormal.x) + " " + ofToString(pNormal.y) + " " + ofToString(pNormal.z)); } Leap::Hand hand = hands[0]; Leap::Hand hand1 = hands[1]; double r = hand.sphereRadius(); //ofLogNotice("r is" + ofToString(r)); r0 = r * 5; ptp = hand1.palmNormal(); ptp0 = hand.palmNormal(); ofLogNotice("distance is ", ofToString(abs(ptp.x)-abs(pNormal.x)) + " " + ofToString(abs(ptp.y)-abs(pNormal.y))); if (abs(abs(ptp.x)-abs(pNormal.x))<0.04 && abs(abs(ptp.y)-abs(pNormal.y))<0.04) { phase1=false; phase2=true; ofLogNotice("phase 2 triggered", ofToString(phase1)); } } if(phase1){ ofSphere(ptp.x,-ptp.y,ptp.z, r0); } vector<Leap::FingerList> fingers = leap.getFingers(); if (!fingers.empty() && phase1==false && phase2 == false && phase3==false && phase4==false && phase5==false && phase6 == false && phase7 == false) { //ofLogNotice("finger detected"); //ofBox(100, -200, 4, 40, 40, 40); phase1 = true; } if (!fingers.empty()) { for (int cnt = 0; cnt < fingers.size(); cnt++) { for (int fingerNum = 0; fingerNum < fingers[cnt].count(); fingerNum++) { Leap::Vector pt = fingers[cnt][fingerNum].tipPosition(); Leap::Vector vpt = fingers[cnt][fingerNum].tipVelocity(); pt.x = pt.x*2; pt.y = (pt.y * -1)*2; pt.z = pt.z *2; //ofLogNotice("finger number is " + ofToString(cnt) + ofToString(fingerNum)); //ofSphere(pt.x,pt.y,pt.z, 10); //ofBox(pt.x, pt.y, pt.z, 10, 10, 10); //ofLogNotice("position is " + ofToString(pt.x) + " " + ofToString(pt.y) + " " + ofToString(pt.z)); //ofLogNotice("velocity is " + ofToString(vpt.x) + " " + ofToString(vpt.y) + " " + ofToString(vpt.z)); drawSphere(pt, 10); } } Leap::Vector tpt = fingers[0][0].tipPosition(); } ofPopMatrix(); camera.end(); }
//Main Event driven tick void ULeapController::InterfaceEventTick(float DeltaTime) { //This is our tick event that is forwarded from the delegate, check validity if (!_private->interfaceDelegate) return; //Pointers Leap::Frame frame = _private->leap.frame(); Leap::Frame pastFrame = _private->leap.frame(1); //-Hands- //Hand Count int handCount = frame.hands().count(); if (_private->pastState.handCount != handCount) { ILeapEventInterface::Execute_HandCountChanged(_private->interfaceDelegate, handCount); //Zero our input mapping orientations (akin to letting go of a joystick) if (handCount == 0) { EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, 0, 0, 0); } } //Cycle through each hand for (int i = 0; i < handCount; i++) { Leap::Hand hand = frame.hands()[i]; LeapHandStateData pastHandState = _private->pastState.stateForId(hand.id()); //we use a custom class to hold reliable state tracking based on id's //Make a ULeapHand if (_private->eventHand == NULL) { _private->eventHand = NewObject<ULeapHand>(this); _private->eventHand->SetFlags(RF_RootSet); } _private->eventHand->setHand(hand); //Emit hand ILeapEventInterface::Execute_LeapHandMoved(_private->interfaceDelegate, _private->eventHand); //Left/Right hand forwarding if (hand.isRight()) { ILeapEventInterface::Execute_LeapRightHandMoved(_private->interfaceDelegate, _private->eventHand); //Input Mapping FRotator palmOrientation = _private->eventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, palmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, palmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, palmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } else if (hand.isLeft()) { ILeapEventInterface::Execute_LeapLeftHandMoved(_private->interfaceDelegate, _private->eventHand); //Input Mapping FRotator palmOrientation = _private->eventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, palmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, palmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, palmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } //Grabbing float grabStrength = hand.grabStrength(); bool grabbed = handClosed(grabStrength); if (grabbed) ILeapEventInterface::Execute_LeapHandGrabbing(_private->interfaceDelegate, grabStrength, _private->eventHand); if (grabbed && !pastHandState.grabbed) { ILeapEventInterface::Execute_LeapHandGrabbed(_private->interfaceDelegate, grabStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyDownEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); else EmitKeyDownEventForKey(EKeysLeap::LeapRightGrab, 0, 0); }else if (!grabbed && pastHandState.grabbed) { ILeapEventInterface::Execute_LeapHandReleased(_private->interfaceDelegate, grabStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyUpEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); else EmitKeyUpEventForKey(EKeysLeap::LeapRightGrab, 0, 0); } //Pinching float pinchStrength = hand.pinchStrength(); bool pinched = handPinched(pinchStrength); //While grabbing disable pinching detection, this helps to reduce spam as pose confidence plummets if (grabbed) pinched = pastHandState.pinched; else { if (pinched) ILeapEventInterface::Execute_LeapHandPinching(_private->interfaceDelegate, pinchStrength, _private->eventHand); if (pinched && !pastHandState.pinched) { ILeapEventInterface::Execute_LeapHandPinched(_private->interfaceDelegate, pinchStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyDownEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); else EmitKeyDownEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } else if (!pinched && pastHandState.pinched) { ILeapEventInterface::Execute_LeapHandUnpinched(_private->interfaceDelegate, pinchStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyUpEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); else EmitKeyUpEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } } //-Fingers- Leap::FingerList fingers = hand.fingers(); //Count int fingerCount = fingers.count(); if ((pastHandState.fingerCount != fingerCount)) ILeapEventInterface::Execute_FingerCountChanged(_private->interfaceDelegate, fingerCount); if (_private->eventFinger == NULL) { _private->eventFinger = NewObject<ULeapFinger>(this); _private->eventFinger->SetFlags(RF_RootSet); } Leap::Finger finger; //Cycle through each finger for (int j = 0; j < fingerCount; j++) { finger = fingers[j]; _private->eventFinger->setFinger(finger); //Finger Moved if (finger.isValid()) ILeapEventInterface::Execute_LeapFingerMoved(_private->interfaceDelegate, _private->eventFinger); } //Do these last so we can easily override debug shapes //Leftmost finger = fingers.leftmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapLeftMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //Rightmost finger = fingers.rightmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapRightMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //Frontmost finger = fingers.frontmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapFrontMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //touch only for front-most finger, most common use case float touchDistance = finger.touchDistance(); if (touchDistance <= 0.f) ILeapEventInterface::Execute_LeapFrontFingerTouch(_private->interfaceDelegate, _private->eventFinger); //Set the state data for next cycle pastHandState.grabbed = grabbed; pastHandState.pinched = pinched; pastHandState.fingerCount = fingerCount; _private->pastState.setStateForId(pastHandState, hand.id()); } _private->pastState.handCount = handCount; //Gestures for (int i = 0; i < frame.gestures().count(); i++) { Leap::Gesture gesture = frame.gestures()[i]; Leap::Gesture::Type type = gesture.type(); switch (type) { case Leap::Gesture::TYPE_CIRCLE: if (_private->eventCircleGesture == NULL){ _private->eventCircleGesture = NewObject<ULeapCircleGesture>(this); _private->eventCircleGesture->SetFlags(RF_RootSet); } _private->eventCircleGesture->setGesture(Leap::CircleGesture(gesture)); ILeapEventInterface::Execute_CircleGestureDetected(_private->interfaceDelegate, _private->eventCircleGesture); _private->eventGesture = _private->eventCircleGesture; break; case Leap::Gesture::TYPE_KEY_TAP: if (_private->eventKeyTapGesture == NULL) { _private->eventKeyTapGesture = NewObject<ULeapKeyTapGesture>(this); _private->eventKeyTapGesture->SetFlags(RF_RootSet); } _private->eventKeyTapGesture->setGesture(Leap::KeyTapGesture(gesture)); ILeapEventInterface::Execute_KeyTapGestureDetected(_private->interfaceDelegate, _private->eventKeyTapGesture); _private->eventGesture = _private->eventKeyTapGesture; break; case Leap::Gesture::TYPE_SCREEN_TAP: if (_private->eventScreenTapGesture == NULL) { _private->eventScreenTapGesture = NewObject<ULeapScreenTapGesture>(this); _private->eventScreenTapGesture->SetFlags(RF_RootSet); } _private->eventScreenTapGesture->setGesture(Leap::ScreenTapGesture(gesture)); ILeapEventInterface::Execute_ScreenTapGestureDetected(_private->interfaceDelegate, _private->eventScreenTapGesture); _private->eventGesture = _private->eventScreenTapGesture; break; case Leap::Gesture::TYPE_SWIPE: if (_private->eventSwipeGesture == NULL) { _private->eventSwipeGesture = NewObject<ULeapSwipeGesture>(this); _private->eventSwipeGesture->SetFlags(RF_RootSet); } _private->eventSwipeGesture->setGesture(Leap::SwipeGesture(gesture)); ILeapEventInterface::Execute_SwipeGestureDetected(_private->interfaceDelegate, _private->eventSwipeGesture); _private->eventGesture = _private->eventSwipeGesture; break; default: break; } //emit gesture if (type != Leap::Gesture::TYPE_INVALID) { ILeapEventInterface::Execute_GestureDetected(_private->interfaceDelegate, _private->eventGesture); } } //Image if (_private->allowImages && _private->imageEventsEnabled) { int imageCount = frame.images().count(); for (int i = 0; i < imageCount; i++) { Leap::Image image = frame.images()[i]; //Loop modification - Only emit 0 and 1, use two different pointers so we can get different images if (i == 0) { if (_private->eventImage1 == NULL) { _private->eventImage1 = NewObject<ULeapImage>(this); _private->eventImage1->SetFlags(RF_RootSet); } _private->eventImage1->setLeapImage(image); ILeapEventInterface::Execute_RawImageReceived(_private->interfaceDelegate, _private->eventImage1->Texture(), _private->eventImage1); } else if (i == 1) { if (_private->eventImage2 == NULL) { _private->eventImage2 = NewObject<ULeapImage>(this); _private->eventImage2->SetFlags(RF_RootSet); } _private->eventImage2->setLeapImage(image); ILeapEventInterface::Execute_RawImageReceived(_private->interfaceDelegate, _private->eventImage2->Texture(), _private->eventImage2); } } } }