bool isTransient(const Pointable& pointable) { // Used to detect fast movement on other axis than vertical in order to avoid accidental scrolls int v = (int)(pointable.tipVelocity()[0]); if(v > TRANSIENT_THRESHOLD) { // std::cout << "Transient movement X" << std::endl; return true; } if(v < -TRANSIENT_THRESHOLD) { // std::cout << "Transient movement X" << std::endl; return true; } v = (int)(pointable.tipVelocity()[2]); if(v > TRANSIENT_THRESHOLD) { // std::cout << "Transient movement Z" << std::endl; return true; } if(v < -TRANSIENT_THRESHOLD) { // std::cout << "Transient movement Z" << std::endl; return true; } return false; }
bool inBound(const Pointable& pointable) { // Detect if the finger is into a good range from the device if(pointable.stabilizedTipPosition()[1] > (float)Y_BOUND) { return false; } if(pointable.stabilizedTipPosition()[0] < -((float)X_BOUND)) { return false; } if(pointable.stabilizedTipPosition()[0] > (float)X_BOUND) { return false; } if(pointable.stabilizedTipPosition()[2] < -((float)Z_BOUND)) { return false; } if(pointable.stabilizedTipPosition()[2] > (float)Z_BOUND) { return false; } return true; }
//get current clicking event from leap bool CPianoMelody::OccurGesture(const KeyTapGesture &keyTap) { Pointable pt = keyTap.pointable(); Vector v= pt.tipVelocity(); Vector pos = pt.tipPosition(); int xPos = pos.x; if(xPos <= -210) { xPos = -210; } else if(xPos >= 210) { xPos = 210; } int musicNum = (pos.x + 210)/30;//get the key num SetKeyPress(musicNum); return false; }
//-------------------------------------------------------------- void ofApp::draw(){ string touchStatus; stringstream info; cam.begin(); ofDrawGrid(500, 5, true); light1.enable(); light2.enable(); ofSetColor(255, 215, 0); Frame frame = controller.frame(); for (int i=0; i < frame.hands().count(); i++) { Hand hand = frame.hands()[i]; for (int j = 0; j < hand.fingers().count(); j ++) { if (j == 0) { Finger finger = frame.fingers()[j]; ofSpherePrimitive sphere; sphere.setPosition(finger.tipPosition().x, finger.tipPosition().y, finger.tipPosition().z); sphere.draw(); info << "Finger position x : " << finger.tipPosition().x << " y : " << finger.tipPosition().y << " z : " << finger.tipPosition().z << endl; } } } cam.end(); PointableList pointables = controller.frame().pointables(); InteractionBox iBox = controller.frame().interactionBox(); for (int p = 0; p < pointables.count(); p++) { Pointable pointable = pointables[p]; Vector normalizedPosition = iBox.normalizePoint(pointable.stabilizedTipPosition()); float x = normalizedPosition.x * ofGetWidth(); float y = ofGetHeight() - normalizedPosition.y * ofGetHeight(); if (pointable.touchDistance() > 0 && pointable.touchZone() != Leap::Pointable::ZONE_NONE) { ofSetColor(0, 255, 0); touchStatus = "Hover"; } else if (pointable.touchDistance() <= 0) { ofSetColor(255, 0, 0); touchStatus = "Touch"; } else { ofSetColor(0, 0, 255); touchStatus = "None"; } ofCircle(x, y, 30); info << "Point Number : " << p << endl; info << "Touch distance : " << ofToString(pointable.touchDistance()) << endl; info << "Circle x : " << x << " y : " << y << endl; } ofDrawBitmapString("Touch Status : " + touchStatus, 20, 20); ofDrawBitmapString(info.str(), 20, 40); }
int main() { uinput_setup(); // Create a listener and controller Controller controller; // int64_t LastFrameID = 0; unsigned int time = DEFAULT_RATE; // Main loop for(;;) { time = DEFAULT_RATE; if(controller.isConnected()) { Frame frame = controller.frame(); if(frame.isValid() /*&& (frame.id() != LastFrameID)*/) { // LastFrameID = frame.id(); Pointable pointable = frame.pointables().frontmost(); if(pointable.isValid()) { if(inBound(pointable) && pointable.isFinger() && !isTransient(pointable)) { if((pointable.hand().fingers().count() == 2) || ((pointable.hand().fingers().count() == 3) && (pointable.hand().fingers().rightmost().length() < (float)THIRD_FINGER_LENGTH))) { // Sometime happen that a third short finger is misdetected, if the third finger is short we ignore it, if it is long no scroll happen float vy = pointable.tipVelocity()[1]; scroll((int)vy); time = computeTime(std::abs(vy)); // std::cout << "time: " << time << std::endl << std::endl; } } } } } else { time = SLOW_RATE; } usleep(time); } // Close HID device uinput_close(); return 0; }
void SampleListener::onFrame(const Controller& controller) { // This function needs to be broken up, it's way too long const Frame frame = controller.frame(); //int currid = 1; //check if we already processed this frame if (frame.id() == this->lastFrameID) return; this->lastFrameID = frame.id(); //stop activity if we've not been used for ACTIVETIMEOUT if ((ACTIVETIMEOUT + this->lastEvent) < time(0) && this->active) { std::cout << "auto deactivated" << std::endl; this->active = false; } if (frame.fingers().count() == 2) { GestureList gestures = frame.gestures(); for (int it = 0; it < gestures.count(); ++it) { if (gestures[it].type() != Gesture::TYPE_KEY_TAP) continue; if ((this->lastToggle + TOGGLE_FRAME_LIMIT) > frame.id()) //avoid detecting the same tap twice continue; KeyTapGesture gesture = gestures[it]; Vector v = gesture.direction(); this->active = !this->active; this->lastToggle = frame.id(); this->lastEvent = time(0); std::cout << (this->active ? "activated" : "deactivated") << std::endl; break; //make sure we don't accidentally use the same list twice } } if (!this->active) return; if (frame.fingers().count() == 1 & side != 2) { PointableList pointables = frame.pointables(); InteractionBox iBox = frame.interactionBox(); for (int p = 0; p < pointables.count(); ++p) { Pointable pointable = pointables[p]; Vector normalizedPosition = iBox.normalizePoint(pointable.stabilizedTipPosition()); float distance = pointable.touchDistance(); float x = normalizedPosition.x * (Mouse->w_width+250); float y = (Mouse->w_height + 250) - normalizedPosition.y * (Mouse->w_height + 250); if (side == 0) { Mouse->move((int)x, (int)y); pressedDelay = 0; } if (distance < 0) { clickcount++; side = 1; if (clickcount > sensibility) { if (pressstate == 0) { Mouse->leftPress(); pressstate = 1; } else { if (clickcount >= 30) { if (rclick == 0) Mouse->move((int)x,(int)y); std::cout << "move side: "<< side << std::endl; clickcount = 20; } } } } else if (side == 1) { Mouse->leftRelease(); std::cout << "released side: " << side << std::endl; side = 0; pressstate = 0; pressedDelay = 0; clickcount = 0; rclick = 0; } } this->lastEvent = time(0); } else if (frame.fingers().count() > 1 & side != 1) { clickcount = 0; std::cout << "active side: " << side << 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; if (gesture.state() == 3 & circle.progress() > 1) { side = 0; rclick = 1; Mouse->rightPress(); Mouse->rightRelease(); } break; } case Gesture::TYPE_SWIPE : { side = 2; SwipeGesture swipe = gesture; Vector d = swipe.direction(); // std::cout << "Swipe id: " << d(1) << std::endl; if (d[1] > 0.8) { this->mystate = 1; //up // std::cout << "wheel up " <<std::endl; } else if (d[1] < -0.8) { this->mystate = 2; //down //std::cout << "wheel down " <<std::endl; } if (swipe.state() == 3) { if (this->mystate == 1) { side = 0; this->mystate = 0; Mouse->wheelUp(); } else if (this->mystate == 2) { side = 0; this->mystate = 0; Mouse->wheelDown(); } } break; } default: //std::cout << "Unknown gesture type." << std::endl; break; } } this->lastEvent = time(0); } }
FREObject LNLeapDevice::getFrame() { Frame frame = controller->frame(); // TODO: Only continue with valid Frame? FREObject freCurrentFrame; FRENewObject( (const uint8_t*) "com.leapmotion.leap.Frame", 0, NULL, &freCurrentFrame, NULL); FREObject freFrameId; FRENewObjectFromInt32((int32_t) frame.id(), &freFrameId); FRESetObjectProperty(freCurrentFrame, (const uint8_t*) "id", freFrameId, NULL); const Vector frameTranslation = frame.translation(lastFrame); FRESetObjectProperty(freCurrentFrame, (const uint8_t*) "translationVector", createVector3(frameTranslation.x, frameTranslation.y, frameTranslation.z), NULL); const Matrix frameRotation = frame.rotationMatrix(lastFrame); FRESetObjectProperty(freCurrentFrame, (const uint8_t*) "rotation", createMatrix( createVector3(frameRotation.xBasis[0], frameRotation.xBasis[1], frameRotation.xBasis[2]), createVector3(frameRotation.yBasis[0], frameRotation.yBasis[1], frameRotation.yBasis[2]), createVector3(frameRotation.zBasis[0], frameRotation.zBasis[1], frameRotation.zBasis[2]), createVector3(frameRotation.origin[0], frameRotation.origin[1], frameRotation.origin[2]) ), NULL); FREObject freFrameScaleFactor; FRENewObjectFromDouble(frame.scaleFactor(lastFrame), &freFrameScaleFactor); FRESetObjectProperty(freCurrentFrame, (const uint8_t*) "scaleFactorNumber", freFrameScaleFactor, NULL); FREObject freTimestamp; FRENewObjectFromInt32((int32_t) frame.timestamp(), &freTimestamp); FRESetObjectProperty(freCurrentFrame, (const uint8_t*) "timestamp", freTimestamp, NULL); std::map<int, FREObject> freHandsMap; if (!frame.hands().empty()) { FREObject freHands; FREGetObjectProperty(freCurrentFrame, (const uint8_t*) "hands", &freHands, NULL); for(int i = 0; i < frame.hands().count(); i++) { const Hand hand = frame.hands()[i]; FREObject freHand; FRENewObject( (const uint8_t*) "com.leapmotion.leap.Hand", 0, NULL, &freHand, NULL); FRESetObjectProperty(freHand, (const uint8_t*) "frame", freCurrentFrame, NULL); FRESetObjectProperty(freHand, (const uint8_t*) "direction", createVector3(hand.direction()[0], hand.direction()[1], hand.direction()[2]), NULL); FREObject freHandId; FRENewObjectFromInt32(hand.id(), &freHandId); FRESetObjectProperty(freHand, (const uint8_t*) "id", freHandId, NULL); FRESetObjectProperty(freHand, (const uint8_t*) "palmNormal", createVector3(hand.palmNormal()[0], hand.palmNormal()[1], hand.palmNormal()[2]), NULL); FRESetObjectProperty(freHand, (const uint8_t*) "palmPosition", createVector3(hand.palmPosition()[0], hand.palmPosition()[1], hand.palmPosition()[2]), NULL); FRESetObjectProperty(freHand, (const uint8_t*) "palmVelocity", createVector3(hand.palmVelocity()[0], hand.palmVelocity()[1], hand.palmVelocity()[2]), NULL); const Matrix rotation = hand.rotationMatrix(lastFrame); FRESetObjectProperty(freHand, (const uint8_t*) "rotation", createMatrix( createVector3(rotation.xBasis[0], rotation.xBasis[1], rotation.xBasis[2]), createVector3(rotation.yBasis[0], rotation.yBasis[1], rotation.yBasis[2]), createVector3(rotation.zBasis[0], rotation.zBasis[1], rotation.zBasis[2]), createVector3(rotation.origin[0], rotation.origin[1], rotation.origin[2]) ), NULL); FREObject freScaleFactor; FRENewObjectFromDouble(hand.scaleFactor(lastFrame), &freScaleFactor); FRESetObjectProperty(freHand, (const uint8_t*) "scaleFactorNumber", freScaleFactor, NULL); FRESetObjectProperty(freHand, (const uint8_t*) "sphereCenter", createVector3(hand.sphereCenter()[0], hand.sphereCenter()[1], hand.sphereCenter()[2]), NULL); FREObject freSphereRadius; FRENewObjectFromDouble(hand.sphereRadius(), &freSphereRadius); FRESetObjectProperty(freHand, (const uint8_t*) "sphereRadius", freSphereRadius, NULL); const Vector translation = hand.translation(lastFrame); FRESetObjectProperty(freHand, (const uint8_t*) "translationVector", createVector3(translation.x, translation.y, translation.z), NULL); FRESetArrayElementAt(freHands, i, freHand); freHandsMap[hand.id()] = freHand; } } std::map<int, FREObject> frePointablesMap; if(!frame.pointables().empty()) { FREObject frePointables; FREGetObjectProperty(freCurrentFrame, (const uint8_t*) "pointables", &frePointables, NULL); for(int i = 0; i < frame.pointables().count(); i++) { const Pointable pointable = frame.pointables()[i]; FREObject frePointable; if(pointable.isTool()) { FRENewObject( (const uint8_t*) "com.leapmotion.leap.Tool", 0, NULL, &frePointable, NULL); } else { FRENewObject( (const uint8_t*) "com.leapmotion.leap.Finger", 0, NULL, &frePointable, NULL); } FRESetObjectProperty(frePointable, (const uint8_t*) "frame", freCurrentFrame, NULL); FREObject frePointableId; FRENewObjectFromInt32(pointable.id(), &frePointableId); FRESetObjectProperty(frePointable, (const uint8_t*) "id", frePointableId, NULL); FREObject frePointableLength; FRENewObjectFromDouble(pointable.length(), &frePointableLength); FRESetObjectProperty(frePointable, (const uint8_t*) "length", frePointableLength, NULL); FREObject frePointableWidth; FRENewObjectFromDouble(pointable.width(), &frePointableWidth); FRESetObjectProperty(frePointable, (const uint8_t*) "width", frePointableWidth, NULL); FRESetObjectProperty(frePointable, (const uint8_t*) "direction", createVector3(pointable.direction().x, pointable.direction().y, pointable.direction().z), NULL); FRESetObjectProperty(frePointable, (const uint8_t*) "tipPosition", createVector3(pointable.tipPosition().x, pointable.tipPosition().y, pointable.tipPosition().z), NULL); FRESetObjectProperty(frePointable, (const uint8_t*) "tipVelocity", createVector3(pointable.tipVelocity().x, pointable.tipVelocity().y, pointable.tipVelocity().z), NULL); //map to hand & back if(pointable.hand().isValid()) { FREObject freHand = freHandsMap[pointable.hand().id()]; FRESetObjectProperty(frePointable, (const uint8_t*) "hand", freHand, NULL); FREObject frePointables; FREGetObjectProperty(freHand, (const uint8_t*) "pointables", &frePointables, NULL); uint32_t numPointables; FREGetArrayLength(frePointables, &numPointables); FRESetArrayElementAt(frePointables, numPointables, frePointable); FREObject freSpecificHandPointables; if(pointable.isTool()) { FREGetObjectProperty(freHand, (const uint8_t*) "tools", &freSpecificHandPointables, NULL); } else { FREGetObjectProperty(freHand, (const uint8_t*) "fingers", &freSpecificHandPointables, NULL); } uint32_t numSpecificHandTools; FREGetArrayLength(freSpecificHandPointables, &numSpecificHandTools); FRESetArrayElementAt(freSpecificHandPointables, numSpecificHandTools, frePointable); } //push it in current frame FRESetArrayElementAt(frePointables, i, frePointable); //specific FREObject freSpecificPointables; if(pointable.isTool()) { FREGetObjectProperty(freCurrentFrame, (const uint8_t*) "tools", &freSpecificPointables, NULL); } else { FREGetObjectProperty(freCurrentFrame, (const uint8_t*) "fingers", &freSpecificPointables, NULL); } uint32_t numSpecificTools; FREGetArrayLength(freSpecificPointables, &numSpecificTools); FRESetArrayElementAt(freSpecificPointables, numSpecificTools, frePointable); frePointablesMap[pointable.id()] = frePointable; } } if(!frame.gestures().empty()) { FREObject freGestures; FREGetObjectProperty(freCurrentFrame, (const uint8_t*) "gesturesVector", &freGestures, NULL); for(int i = 0; i < frame.gestures().count(); i++) { const Gesture gesture = frame.gestures()[i]; int state; switch (gesture.state()) { case Gesture::STATE_INVALID: state = 0; break; case Gesture::STATE_START: state = 1; break; case Gesture::STATE_UPDATE: state = 2; break; case Gesture::STATE_STOP: state = 3; break; default: break; } int type; FREObject freGesture; switch (gesture.type()) { case Gesture::TYPE_SWIPE: { type = 5; SwipeGesture swipe = gesture; FRENewObject( (const uint8_t*) "com.leapmotion.leap.SwipeGesture", 0, NULL, &freGesture, NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "direction", createVector3(swipe.direction().x, swipe.direction().y, swipe.direction().z), NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "position", createVector3(swipe.position().x, swipe.position().y, swipe.position().z), NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "startPosition", createVector3(swipe.startPosition().x, swipe.startPosition().y, swipe.startPosition().z), NULL); FREObject freSwipeGestureSpeed; FRENewObjectFromDouble(swipe.speed(), &freSwipeGestureSpeed); FRESetObjectProperty(freGesture, (const uint8_t*) "speed", freSwipeGestureSpeed, NULL); break; } case Gesture::TYPE_CIRCLE: { type = 6; CircleGesture circle = gesture; FRENewObject( (const uint8_t*) "com.leapmotion.leap.CircleGesture", 0, NULL, &freGesture, NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "center", createVector3(circle.center().x, circle.center().y, circle.center().z), NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "normal", createVector3(circle.normal().x, circle.normal().y, circle.normal().z), NULL); FREObject freCircleGestureProgress; FRENewObjectFromDouble(circle.progress(), &freCircleGestureProgress); FRESetObjectProperty(freGesture, (const uint8_t*) "progress", freCircleGestureProgress, NULL); FREObject freCircleGestureRadius; FRENewObjectFromDouble(circle.radius(), &freCircleGestureRadius); FRESetObjectProperty(freGesture, (const uint8_t*) "radius", freCircleGestureRadius, NULL); FREObject frePointable = frePointablesMap[circle.pointable().id()]; if(frePointable != NULL) { FRESetObjectProperty(freGesture, (const uint8_t*) "pointable", frePointable, NULL); } break; } case Gesture::TYPE_SCREEN_TAP: { type = 7; ScreenTapGesture screentap = gesture; FRENewObject( (const uint8_t*) "com.leapmotion.leap.ScreenTapGesture", 0, NULL, &freGesture, NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "direction", createVector3(screentap.direction().x, screentap.direction().y, screentap.direction().z), NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "position", createVector3(screentap.position().x, screentap.position().y, screentap.position().z), NULL); break; } case Gesture::TYPE_KEY_TAP: { type = 8; KeyTapGesture tap = gesture; FRENewObject( (const uint8_t*) "com.leapmotion.leap.KeyTapGesture", 0, NULL, &freGesture, NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "direction", createVector3(tap.direction().x, tap.direction().y, tap.direction().z), NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "position", createVector3(tap.position().x, tap.position().y, tap.position().z), NULL); break; } default: { type = 4; FRENewObject( (const uint8_t*) "com.leapmotion.leap.Gesture", 0, NULL, &freGesture, NULL); break; } } FREObject freGestureState; FRENewObjectFromInt32(state, &freGestureState); FRESetObjectProperty(freGesture, (const uint8_t*) "state", freGestureState, NULL); FREObject freGestureType; FRENewObjectFromInt32(type, &freGestureType); FRESetObjectProperty(freGesture, (const uint8_t*) "type", freGestureType, NULL); FREObject freGestureDuration; FRENewObjectFromInt32((int32_t) gesture.duration(), &freGestureDuration); FRESetObjectProperty(freGesture, (const uint8_t*) "duration", freGestureDuration, NULL); FREObject freGestureDurationSeconds; FRENewObjectFromDouble(gesture.durationSeconds(), &freGestureDurationSeconds); FRESetObjectProperty(freGesture, (const uint8_t*) "durationSeconds", freGestureDurationSeconds, NULL); FRESetObjectProperty(freGesture, (const uint8_t*) "frame", freCurrentFrame, NULL); FREObject freGestureId; FRENewObjectFromInt32(gesture.id(), &freGestureId); FRESetObjectProperty(freGesture, (const uint8_t*) "id", freGestureId, NULL); if (!gesture.hands().empty()) { FREObject freGestureHands; FREGetObjectProperty(freGesture, (const uint8_t*) "hands", &freGestureHands, NULL); for(int i = 0; i < gesture.hands().count(); i++) { const Hand hand = gesture.hands()[i]; FREObject freHand = freHandsMap[hand.id()]; FRESetArrayElementAt(freGestureHands, i, freHand); } } if (!gesture.pointables().empty()) { FREObject freGesturePointables; FREGetObjectProperty(freGesture, (const uint8_t*) "pointables", &freGesturePointables, NULL); for(int i = 0; i < gesture.pointables().count(); i++) { const Pointable pointable = gesture.pointables()[i]; FREObject frePointable = frePointablesMap[pointable.id()]; FRESetArrayElementAt(freGesturePointables, i, frePointable); } } //push it in current gesture vector FRESetArrayElementAt(freGestures, i, freGesture); } } lastFrame = frame; return freCurrentFrame; }