カテゴリー別アーカイブ: openFrameworks

【openFrameworks】C++でLeapMotion

LeapMotionが届いたので早速openFrameworksから使ってみました。
leap

備忘録的に残してるだけなので、最適な使い方〜って感じではないと思います。
あと、描画にoFのところ使ってるだけで基本的にはC++での使い方になります。

開発環境
OSX 10.8.4
Xcode 4.6.3
openFrameworks 0074

1.SDKをダウンロードする
https://developer.leapmotion.com/dashboard
ここのMacOSXのやつをダウンロードします。
記事作成時点でのバージョンは【v.0.8.1.6221】です。

2.SDKをプロジェクトに追加する

oFのプロジェクトを作り、LeapSDKをプロジェクトに追加する。
ここではoFのプロジェクト名をLeapMotionにしてます
sdk追加

 

 

 

 

 

 

 

追加時にプロジェクトのsrcフォルダにコピーされる用に設定しました。

sdk追加2

 

 

 

 

 

 

 

 

ダウンロードしたまんまのLeapSDKのフォルダを追加するとjavaやらpythonやらobj-cのライブラリも追加されるので、添付の画像のように必要なものだけ残して プロジェクトから外す。
不要ファイルの除去

 

 

 

 

 

 

 

 

 

 

 

3.dylibをコピーする
ビルド後にlibLeap.dylibが無いと実行できないので、ビルド時にコピーされるように、Build Phaseのところで設定する。
Add Build Phase→DestinationをProducts Directoryに変更→libLeap.dylibを追加する。

dylib追加

 

 

 

 

 

 

 

4.いくつかソースを修正する

LeapMath.hの以下部分をコメントアウトする。
(oFの何かと干渉してるっぽいので…)

LeapMath.h

namespace Leap {

/** The constant pi as a single precision floating point number. */
//static const float PI          = 3.1415926536f;
/**
 * The constant ratio to convert an angle measure from degrees to radians.
 * Multiply a value in degrees by this constant to convert to radians.
 */
//static const float DEG_TO_RAD  = 0.0174532925f;
/**
 * The constant ratio to convert an angle measure from radians to degrees.
 * Multiply a value in radians by this constant to convert to degrees.
 */
//static const float RAD_TO_DEG  = 57.295779513f;

LeapUtil.hの以下の部分を修正

namespace LeapUtil {

///
/// LeapMath is not intended to be a full-function vector math library.
/// It defines a few useful classes that are needed to pass vector values around and do a few
/// basic spatial operations.  You are highly encouraged to use a complete and optimized
/// vector math library for any serious computation.
///

///
/// math utility functions
/// To minimize additional code requirements for Leap samples no external math library is used.
/// These utility functions provide extra functionality not available in LeapMath.
/// In general this code is designed for transparency and simplicity rather than speed.
/// It is a minimal subset of extra functionality needed to implement LeapScene and
/// the sample code.  It is not intended to be a complete vector math utility library.
///

static const float kfPi       = 3.1415926536f; //←ここ
static const float kf2Pi      = kfPi + kfPi;
static const float kfHalfPi   = kfPi * 0.5f;

 

5.リスナークラスを作る
とりあえず指先の座標を取るだけのモノを作る
LeapMotion.hとLeapMotion.cppを新たに作る
LeapMotion.h

#ifndef __LeapMotion__ofxLeap__
#define __LeapMotion__ofxLeap__

#include <iostream>

#include "../ofMain.h"
#include "Leap.h"

class LeapMotion : public Leap::Listener{
public:
    LeapMotion();
    ~LeapMotion();
    virtual void onInit(const Leap::Controller&);
    virtual void onConnect(const Leap::Controller&);
    virtual void onDisConnect(const Leap::Controller&);
    virtual void onFrame(const Leap::Controller&);
    virtual void onExit(const Leap::Controller&);

    vector<Leap::FingerList> getFingers();
private:
    Leap::HandList handList;
    vector<Leap::FingerList> fingers;

    Poco::FastMutex mutex;
};

#endif /* defined(__LeapMotion__ofxLeap__) */

LeapMotion.cpp

#include "LeapMotion.h"

LeapMotion::LeapMotion(){
}
//------------------------------------------------
LeapMotion::~LeapMotion(){
}

//------------------------------------------------

void LeapMotion::onInit(const Leap::Controller &controller){
    ofLogNotice("インスタンス化しました。");
}

//------------------------------------------------
void LeapMotion::onConnect(const Leap::Controller &controller){
    ofLogNotice("接続しました。");

    //アプリケーションがバックグラウンドでもフレームを更新するかどうか
    controller.setPolicyFlags(Leap::Controller::POLICY_BACKGROUND_FRAMES);
//    controller.setPolicyFlags(Leap::Controller::POLICY_DEFAULT);

}

//------------------------------------------------
void LeapMotion::onDisConnect(const Leap::Controller &controller){
    ofLogNotice("切断しました。");

}

//------------------------------------------------
void LeapMotion::onFrame(const Leap::Controller &controller){

    Leap::Frame frame = controller.frame();
    const Leap::GestureList gestureList = frame.gestures();

    //指などの位置
    if(mutex.tryLock(2000)){
        handList = frame.hands();
        fingers.clear();
        for(int cnt = 0; cnt < handList.count(); ++cnt){
            Leap::FingerList tmpfingerList =  handList[cnt].fingers();
            fingers.push_back(tmpfingerList);
        }

        mutex.unlock();
    }
}

//------------------------------------------------
void LeapMotion::onExit(const Leap::Controller &controller){
    ofLogNotice("切断・インスタンスが破棄されました");

}
//------------------------------------------------
vector<Leap::FingerList> LeapMotion::getFingers(){
    //もっといいやり方があるはず
    vector<Leap::FingerList> tmp;

    mutex.lock();
    tmp = fingers;
    mutex.unlock();

    return tmp;
}

6. testApp.cppとtestApp.hを書く

以下な感じ!

testApp.h

#pragma once

#include "ofMain.h"
#include "LeapMotion.h"

class testApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();
        void exit();

		void keyPressed  (int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

    LeapMotion leap;
    Leap::Controller leapController;

};

testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    ofSetFrameRate(60);
    ofSetVerticalSync(true);
    ofBackground(0, 0, 0);

    leapController.addListener(leap);

}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){
    ofSetWindowTitle(ofToString(ofGetFrameRate()));

    ofPushMatrix();
    ofTranslate(ofGetWidth()/2, ofGetHeight());
    ofSetColor(255, 255, 255);

    vector<Leap::FingerList> fingers = leap.getFingers();
    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();
                //なんとなく*2
                pt.x = pt.x*2;
                pt.y = (pt.y * -1)*2;// 座標軸を合わせるので-1をかける
                pt.z = pt.z*2;
                //ofCircle(pt.x, pt.y, 5);
                ofSphere(pt.x, pt.y, pt.z, 10);
            }
        }
    }
    ofPopMatrix();
}

//--------------------------------------------------------------
void testApp::exit(){
    leapController.removeListener(leap);
}

7.動いた\(^o^)/
leapmotion

次はジェスチャーとかも試してみようと思います。