Example #1
0
static VALUE tip_position(VALUE self)
{
  Leap::Pointable * pointer;
  Leap::Vector * vector;

  Data_Get_Struct(self, Leap::Pointable, pointer);

  vector = new Leap::Vector(pointer->tipPosition());

  return WrapVector(vector);
}
Example #2
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;
            }
        }
    }
}
Example #3
0
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;
  }
}