static VALUE length(VALUE self) { Leap::Pointable * pointer; Data_Get_Struct(self, Leap::Pointable, pointer); return DBL2NUM(pointer->length()); }
static VALUE touch_distance(VALUE self) { Leap::Pointable * pointer; Data_Get_Struct(self, Leap::Pointable, pointer); return DBL2NUM(pointer->touchDistance()); }
static VALUE pointable_id(VALUE self) { Leap::Pointable * pointer; const char * string; Data_Get_Struct(self, Leap::Pointable, pointer); return INT2NUM(pointer->id()); }
VALUE MakePointable(Leap::Pointable pointable) { if (pointable.isFinger()) return WrapFinger(new Leap::Finger(pointable)); if (pointable.isTool()) return WrapTool(new Leap::Tool(pointable)); return WrapPointable(new Leap::Pointable(pointable)); }
static VALUE direction(VALUE self) { Leap::Pointable * pointer; Leap::Vector * vector; Data_Get_Struct(self, Leap::Pointable, pointer); vector = new Leap::Vector(pointer->direction()); return WrapVector(vector); }
static VALUE tip_velocity(VALUE self) { Leap::Pointable * pointer; Leap::Vector * vector; Data_Get_Struct(self, Leap::Pointable, pointer); vector = new Leap::Vector(pointer->tipVelocity()); return WrapVector(vector); }
static VALUE stabilized_tip_position(VALUE self) { Leap::Pointable * pointer; Leap::Vector * vector; Data_Get_Struct(self, Leap::Pointable, pointer); vector = new Leap::Vector(pointer->stabilizedTipPosition()); return WrapVector(vector); }
static VALUE hand(VALUE self) { Leap::Pointable * pointer; Leap::Hand * hand; Data_Get_Struct(self, Leap::Pointable, pointer); hand = new Leap::Hand(pointer->hand()); return WrapHand(hand); }
static VALUE valid_p(VALUE self) { Leap::Pointable * pointer; Data_Get_Struct(self, Leap::Pointable, pointer); if (pointer->isValid()) return Qtrue; return Qfalse; }
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; } }
static VALUE touch_zone(VALUE self) { Leap::Pointable * pointer; Data_Get_Struct(self, Leap::Pointable, pointer); switch(pointer->touchZone()) { case(Leap::Pointable::ZONE_NONE): return ID2SYM(rb_intern("none")); case(Leap::Pointable::ZONE_HOVERING): return ID2SYM(rb_intern("hovering")); case(Leap::Pointable::ZONE_TOUCHING): return ID2SYM(rb_intern("touching")); }; return Qfalse; }
void convertPointableRotation(const Leap::Pointable& pointable, MatrixF& outRotation) { // We need to convert from Motion coordinates to // Torque coordinates. The conversion is: // // Motion Torque // a b c a b c a -c b // d e f --> -g -h -i --> -g i -h // g h i d e f d -f e Leap::Vector pointableFront = -pointable.direction(); Leap::Vector pointableRight = Leap::Vector::up().cross(pointableFront); Leap::Vector pointableUp = pointableFront.cross(pointableRight); outRotation.setColumn(0, Point4F( pointableRight.x, -pointableRight.z, pointableRight.y, 0.0f)); outRotation.setColumn(1, Point4F( -pointableFront.x, pointableFront.z, -pointableFront.y, 0.0f)); outRotation.setColumn(2, Point4F( pointableUp.x, -pointableUp.z, pointableUp.y, 0.0f)); outRotation.setPosition(Point3F::Zero); }
void LeapSample03App::draw() { gl::clear( Color( .97, .93, .79 ) ); Leap::PointableList pointables = leap.frame().pointables(); Leap::InteractionBox iBox = leap.frame().interactionBox(); for ( int p = 0; p < pointables.count(); p++ ) { Leap::Pointable pointable = pointables[p]; #if 1 // ここから追加 // 伸びている指、ツール以外は無視する if ( !pointable.isExtended() ) { continue; } // ここまで追加 #endif Leap::Vector normalizedPosition = iBox.normalizePoint( pointable.stabilizedTipPosition() ); float x = normalizedPosition.x * windowWidth; float y = windowHeight - normalizedPosition.y * windowHeight; // ホバー状態 if ( (pointable.touchDistance() > 0) && (pointable.touchZone() != Leap::Pointable::Zone::ZONE_NONE) ) { gl::color(0, 1, 0, 1 - pointable.touchDistance()); } // タッチ状態 else if ( pointable.touchDistance() <= 0 ) { gl::color(1, 0, 0, -pointable.touchDistance()); } // タッチ対象外 else { gl::color(0, 0, 1, .05); } gl::drawSolidCircle( Vec2f( x, y ), 40 ); } }
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 DefaultQtLeapMouseHandler::onFrame(const Leap::Frame &frame) { /////// MOUSE EVENTS ///////// // MOUSE BUTTON PRESSED // MOUSE BUTTON RELEASED // MOUSE MOVE if (this->listeners.empty()) return ; Leap::Pointable pointer = frame.pointable(this->savedMousePointableId); if (!pointer.isValid()) { pointer = frame.pointables().frontmost(); this->savedMousePointableId = pointer.id(); } bool forceRelease = (frame.pointables().count() == 0 && this->mousePressed); QMouseEvent::Type frameMouseEvent = QMouseEvent::None; QPointF globalPointerPos = QtLeapUtils::convertPointablePosToScreenPos(frame.interactionBox(), pointer); Qt::MouseButton button = Qt::NoButton; Qt::MouseButtons buttons = Qt::NoButton; // FINGER TOUCHING AND NO PREVIOUS PRESS -> SETTING BUTTON PRESS if (pointer.touchDistance() <= 0 && pointer.touchZone() == Leap::Pointable::ZONE_TOUCHING && !this->mousePressed) { this->mousePressed = true; frameMouseEvent = QMouseEvent::MouseButtonPress; button = Qt::LeftButton; } else if (this->mousePressed && (pointer.touchDistance() > 0 || pointer.touchZone() == Leap::Pointable::ZONE_NONE || forceRelease)) // FINGER NOT TOUCHING AND PREVIOUS PRESS -> RELEASING BUTTON PRESS { frameMouseEvent = QMouseEvent::MouseButtonRelease; this->mousePressed = false; button = Qt::LeftButton; } else if (frameMouseEvent == QMouseEvent::None && // FINGER IN TOUCHING OR HOVERING ZONE AND NO BUTTON PRESS / RELEASE CHANGE -> MouseMove pointer.touchZone() != Leap::Pointable::ZONE_NONE && globalPointerPos.toPoint() != this->previousPos) { frameMouseEvent = QMouseEvent::MouseMove; this->previousPos = globalPointerPos.toPoint(); QCursor::setPos(this->previousPos); } if (this->mousePressed) buttons |= Qt::LeftButton; if (frameMouseEvent != QMouseEvent::None) foreach (QObject *listener, this->listeners) QCoreApplication::postEvent(listener, new QMouseEvent(frameMouseEvent, QtLeapUtils::convertGlobalPosToLocalPos(listener, globalPointerPos), globalPointerPos, button, buttons, Qt::NoModifier)); }
void Scene::updateInteraction( const Frame& frame ) { static const uint8_t kMaxContactMissedFrames = 64; (void)frame; for (size_t i=0; i < m_uiNumObjects; i++) { const SceneObjectPtr& pObj = m_apObjects[i]; if (!pObj->HasInitialContact() && pObj->GetNumContacts() == 0 && pObj->GetNumPointing() == 0) { pObj->m_fTotalHitTime = 0.0f; } /// selection state change from not selected to selected else if ( !pObj->IsSelected() && pObj->m_fTotalHitTime >= m_fSelectHitTime ) { SceneInteraction selection; selection.m_uiFlags = kIT_SelectionChange | kIT_IsSelected; selection.m_pObject = pObj; queueInteraction( selection ); } /// possible manipulation else if ( pObj->IsSelected() ) { if ( pObj->HasInitialContact() ) { const SceneContactPoint& initContact = pObj->m_initialContactPoint; Leap::Pointable contactPointable = frame.pointable(initContact.m_iPointableID); if ( contactPointable.isValid() ) { const Vector vPointablePos = TransformFramePoint(contactPointable.tipPosition()); const Vector vTrans = (vPointablePos - pObj->GetCenter()); SceneInteraction translation; translation.m_mtxTransform.origin = vTrans; translation.m_uiFlags |= kIT_Translation; translation.m_pObject = pObj; queueInteraction( translation ); pObj->m_uiHasInitialContact = kMaxContactMissedFrames; } else { pObj->m_uiHasInitialContact--; if ( !pObj->m_uiLastNumContacts ) { pObj->ClearHits(); } } } else { if ( pObj->GetNumContacts() ) { pObj->m_initialContactPoint = *(pObj->GetContactPoint(0)); pObj->m_initialContactPoint.m_vPoint -= pObj->GetCenter(); pObj->m_uiHasInitialContact = kMaxContactMissedFrames; } else if ( pObj->GetLastNumContacts() ) { pObj->m_initialContactPoint = *(pObj->GetLastContactPoint(0)); pObj->m_initialContactPoint.m_vPoint -= pObj->GetCenter(); pObj->m_uiHasInitialContact = kMaxContactMissedFrames; } } /// multi touch if (pObj->GetLastNumContacts() >= 2 && pObj->GetNumContacts() >= 2) { const SceneContactPoint& lastContact0 = *(pObj->GetLastContactPoint(0)); const SceneContactPoint& lastContact1 = *(pObj->GetLastContactPoint(1)); const SceneContactPoint* pCurContact0 = pObj->GetContactPointByPointableID( lastContact0.m_iPointableID ); const SceneContactPoint* pCurContact1 = pObj->GetContactPointByPointableID( lastContact1.m_iPointableID ); if ( pCurContact0 && pCurContact1 ) { const Vector lastVec = (lastContact1.m_vPoint - lastContact0.m_vPoint); const Vector newVec = (pCurContact1->m_vPoint - pCurContact0->m_vPoint); if ( !IsNearEqual(lastVec, newVec) && !IsNearZero(lastVec) ) { const float fLastDist = lastVec.magnitude(); const float fNewDist = newVec.magnitude(); /// scale by change in pinch distance const float fScale = fNewDist/fLastDist; /// rotate by tilt of fingers const Vector vLastDir = lastVec * 1.0f/fLastDist; const Vector vNewDir = newVec * 1.0f/fNewDist; const Vector vAxis = vNewDir.cross(vLastDir); const float fAngle = acosf( vNewDir.dot(vLastDir) ); /// translate by average movement const Vector vTrans = ( (pCurContact0->m_vPoint - lastContact0.m_vPoint) + (pCurContact1->m_vPoint - lastContact1.m_vPoint) ) * 0.5f; SceneInteraction interaction; if ( !IsNearZero(fAngle) ) { interaction.m_mtxTransform.setRotation( vAxis, fAngle ); interaction.m_uiFlags |= kIT_Rotation; } if ( !IsNearEqual(fScale, 1.0f) ) { interaction.m_fScale = fScale; interaction.m_uiFlags |= kIT_Scale; } if ( !IsNearZero( vTrans ) ) { interaction.m_mtxTransform.origin = vTrans; interaction.m_uiFlags |= kIT_Translation; } if ( interaction.m_uiFlags ) { interaction.m_pObject = pObj; queueInteraction( interaction ); } } } } } pObj->rotateContactPoints(); pObj->m_uiNumPointing = 0; } }
void ZirkLeap::onFrame(const Leap::Controller& controller) { if(controller.hasFocus()) { Leap::Frame frame = controller.frame(); if (mPointableId >= 0) { ourProcessor->setSelectedSource(mEditor->getCBSelectedSource()-1); Leap::Pointable p = frame.pointable(mPointableId); if (!p.isValid() || !p.isExtended()) { mPointableId = -1; mLastPositionValid = false; } else { Leap::Vector pos = p.tipPosition(); const float zPlane1 = 50; // 5 cm const float zPlane2 = 100; // 10 cm if (pos.z < zPlane2) { if (mLastPositionValid) { //Leap Motion mouvement are calculated from the last position in order to have something dynamic and ergonomic Leap::Vector delta = pos- mLastPosition; float scale = 3; if (pos.z > zPlane1) { float s = 1 - (pos.z - zPlane1) / (zPlane2 - zPlane1); scale *= s; } int src = ourProcessor->getSelectedSource(); float fX, fY; ourProcessor->getSources()[src].getXY(fX, fY); fX += delta.x * scale; fY -= delta.y * scale; //clamp coordinates to circle float fCurR = hypotf(fX, fY); if ( fCurR > ZirkOscAudioProcessor::s_iDomeRadius){ float fExtraRatio = ZirkOscAudioProcessor::s_iDomeRadius / fCurR; fX *= fExtraRatio; fY *= fExtraRatio; } mEditor->move(src, fX, fY); } else { //std::cout << "pointable last pos not valid" << std::endl; } mLastPosition = pos; mLastPositionValid = true; } else { //std::cout << "pointable not touching plane" << std::endl; mLastPositionValid = false; } } } if (mPointableId < 0) { Leap::PointableList pl = frame.pointables().extended(); if (pl.count() > 0) { mPointableId = pl[0].id(); //std::cout << "got new pointable: " << mPointableId << std::endl; } } } }