WindowsのopenFrameworksでLeap Motionを使えるようにする
手軽にまとまった記事がないのでここでまとめて記載する。
1. Visual C++で必要な処理
2. oFで必要な処理
の二点にわかれる。
1. VC++に関して
下記記事を参考
www.naturalsoftware.jp
2. oFに関して
下記記事を参照
gndo.blogspot.jp
Macの記事だけど基本的にoFと名前が被っているところをどうにかするだけ。
サンプルコードも
testApp::drawSphere(Vector vector, float radius) { //を ofApp::drawSphere(Vector vector, float radius) { //に変える
だけです。簡単!
ただWindowsにまとまったサイトがなかったのでここを参照してくださいということで。
下記サンプルは実験するには冗長なので、軽く遊びたいだけなら上記サイトを見てください。
でサンプルコードと合わせて球を表示させつつなんかコンソールにむっちゃ表示させるようにした。
//ofApp.h #pragma once #include "ofMain.h" #include "Leap.h" using namespace Leap; class ofApp : public ofBaseApp, public Listener{ public: void setup(); void update(); void draw(); 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 mouseEntered(int x, int y); void mouseExited(int x, int y); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); // Leap Motionのコントローラー Controller leap; // カメラ ofCamera camera; // 球体の描画処理 void drawSphere(Vector vector, float radius); //----- 一過性のイベントだけListnerから取得 ----------------------------// //----- フレームの処理はdraw()で行う -----------------------------------// void onConnect(const Controller&) { cout << __FUNCTION__ << endl; } void onDisconnect(const Controller&) { cout << __FUNCTION__ << endl; } void onFocusGained(const Controller&) { cout << __FUNCTION__ << endl; } void onFocusLost(const Controller&) { cout << __FUNCTION__ << endl; } void onServiceConnect(const Controller&) { cout << __FUNCTION__ << endl; } void onServiceDisconnect(const Controller&) { cout << __FUNCTION__ << endl; } //------------------------------------------------------------// };
//ofApp.cpp #include "ofApp.h" const std::string fingerNames[] = { "Thumb", "Index", "Middle", "Ring", "Pinky" }; const std::string boneNames[] = { "Metacarpal", "Proximal", "Middle", "Distal" }; const std::string stateNames[] = { "STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END" }; //-------------------------------------------------------------- void ofApp::setup(){ // カメラの初期位置と方向を指定 camera.setFov(60); camera.setPosition(0, 200, ofGetWidth() / 3); camera.lookAt(ofVec3f(0, 200, 0)); //ofSetFrameRate(1); } //-------------------------------------------------------------- void ofApp::update(){ const Frame frame = leap.frame(); std::cout << "Frame id: " << frame.id() << ", timestamp: " << frame.timestamp() << ", hands: " << frame.hands().count() << ", extended fingers: " << frame.fingers().extended().count() << ", tools: " << frame.tools().count() << ", gestures: " << frame.gestures().count() << std::endl; HandList hands = frame.hands(); for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) { // Get the first hand const Hand hand = *hl; std::string handType = hand.isLeft() ? "Left hand" : "Right hand"; std::cout << std::string(2, ' ') << handType << ", id: " << hand.id() << ", palm position: " << hand.palmPosition() << std::endl; // Get the hand's normal vector and direction const Vector normal = hand.palmNormal(); const Vector direction = hand.direction(); // Calculate the hand's pitch, roll, and yaw angles std::cout << std::string(2, ' ') << "pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; // Get the Arm bone Arm arm = hand.arm(); std::cout << std::string(2, ' ') << "Arm direction: " << arm.direction() << " wrist position: " << arm.wristPosition() << " elbow position: " << arm.elbowPosition() << std::endl; // Get fingers const FingerList fingers = hand.fingers(); for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl) { const Finger finger = *fl; std::cout << std::string(4, ' ') << fingerNames[finger.type()] << " finger, id: " << finger.id() << ", length: " << finger.length() << "mm, width: " << finger.width() << std::endl; // Get finger bones for (int b = 0; b < 4; ++b) { Bone::Type boneType = static_cast<Bone::Type>(b); Bone bone = finger.bone(boneType); std::cout << std::string(6, ' ') << boneNames[boneType] << " bone, start: " << bone.prevJoint() << ", end: " << bone.nextJoint() << ", direction: " << bone.direction() << std::endl; } } } // Get tools const ToolList tools = frame.tools(); for (ToolList::const_iterator tl = tools.begin(); tl != tools.end(); ++tl) { const Tool tool = *tl; std::cout << std::string(2, ' ') << "Tool, id: " << tool.id() << ", position: " << tool.tipPosition() << ", direction: " << tool.direction() << 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; std::string clockwiseness; if (circle.pointable().direction().angleTo(circle.normal()) <= PI / 2) { clockwiseness = "clockwise"; } else { clockwiseness = "counterclockwise"; } // Calculate angle swept since last frame float sweptAngle = 0; if (circle.state() != Gesture::STATE_START) { CircleGesture previousUpdate = CircleGesture(leap.frame(1).gesture(circle.id())); sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI; } std::cout << std::string(2, ' ') << "Circle id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", progress: " << circle.progress() << ", radius: " << circle.radius() << ", angle " << sweptAngle * RAD_TO_DEG << ", " << clockwiseness << std::endl; break; } case Gesture::TYPE_SWIPE: { SwipeGesture swipe = gesture; std::cout << std::string(2, ' ') << "Swipe id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", direction: " << swipe.direction() << ", speed: " << swipe.speed() << std::endl; break; } case Gesture::TYPE_KEY_TAP: { KeyTapGesture tap = gesture; std::cout << std::string(2, ' ') << "Key Tap id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", position: " << tap.position() << ", direction: " << tap.direction() << std::endl; break; } case Gesture::TYPE_SCREEN_TAP: { ScreenTapGesture screentap = gesture; std::cout << std::string(2, ' ') << "Screen Tap id: " << gesture.id() << ", state: " << stateNames[gesture.state()] << ", position: " << screentap.position() << ", direction: " << screentap.direction() << std::endl; break; } default: std::cout << std::string(2, ' ') << "Unknown gesture type." << std::endl; break; } } if (!frame.hands().isEmpty() || !gestures.isEmpty()) { std::cout << std::endl; } } //-------------------------------------------------------------- void ofApp::draw(){ camera.begin(); // 背景を黒に塗りつぶし ofBackground(0, 0, 0); // フレームを取得 Frame frame = leap.frame(); // Handをあるだけ列挙 for (int i = 0; i<frame.hands().count(); i++) { Hand hand = frame.hands()[i]; // てのひらの位置に球体を描画 drawSphere(hand.palmPosition(), 20); // Hand内のFingerをあるだけ描画 for (int j = 0; j<hand.fingers().count(); j++) { Finger finger = frame.fingers()[j]; drawSphere(finger.tipPosition(), 8); //drawSphere(finger.jointPosition(), 2); } } camera.end(); } void ofApp::drawSphere(Vector vector, float radius) { // 球体の描画処理 ofNoFill(); ofPushMatrix(); ofPoint point = ofPoint(vector.x, vector.y, vector.z); ofTranslate(point); ofRotateX(point.x); ofRotateY(point.y); ofRotateZ(point.z); ofSetColor(0xCC, 0, 0, 255); ofSphere(radius); ofPopMatrix(); }
コメントもそのまま残っていて草はえますね。
これを描くとコンソールにむっちゃ言葉が出てきて追いきれません。位置とかを送ってそうですね(雑な理解)