static VALUE valid_p(VALUE self) { Leap::Pointable * pointer; Data_Get_Struct(self, Leap::Pointable, pointer); if (pointer->isValid()) return Qtrue; return Qfalse; }
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; } } } }
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)); }