openFrameworksでマルチタッチしてみた (Mac only)
Mac純正のマルチタッチフレームワークであるMultitouchSupport.frameworkを使ってマルチタッチをしてみる
参考サイトは死んでるので、覚えてる範囲で...
必要なもの
- openFrameworks本体
- ofxVectorMath (Addon)
- MultitouchSupport.framework (/System/Library/PrivateFrameworks/にある)
- ofxOsc (任意)
手順
- ofxVectorMath、MultitouchSupport.frameworkとofxOscをXcodeのプロジェクトに入れる...ドラッグするだけ
こんな感じになる
- testApp.cppをtestApp.mmに変更する
※ 一応、ファイルタイプがObjective-C++ Sourceになってるか確認 - コードを書く
#pragma once #include "ofMain.h" #include "ofxOsc.h" #define TUIOPORT 3333 class testApp : public ofBaseApp{ 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 windowResized(int w, int h); int width, height; ofxOscSender send; };
#include "testApp.h" #include "ofVectorMath.h" extern "C" { typedef struct { float x,y; } mtPoint; typedef struct { mtPoint pos,vel; } mtReadout; typedef struct { int frame; double timestamp; int identifier, state, foo3, foo4; mtReadout normalized; float size; int zero1; float angle, majorAxis, minorAxis; mtReadout mm; int zero2[2]; float unk2; } Finger; typedef void *MTDeviceRef; typedef int (*MTContactCallbackFunction)(int,Finger*,int,double,int); CFMutableArrayRef MTDeviceCreateList(void); void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); void MTDeviceStart(MTDeviceRef, int); } class TouchPoint { public: ofVec2f pos; ofVec2f vel; float size; int id; bool enable; float phase; float freq, amp; float trem_phase; int stat; }; vector<TouchPoint> touchPoints; int mtCallback(int device, Finger *data, int nFingers, double timestamp, int frame) { for (int i = 0; i < touchPoints.size(); i ++) { touchPoints[i].enable = false; } for (int i=0; i<nFingers; i++) { Finger *f = &data[i]; /* printf("Frame %7d: Angle %6.2f, ellipse %6.3f x%6.3f; " "position (%6.3f,%6.3f) vel (%6.3f,%6.3f) " "ID %d, state %d [%d %d?] size %6.3f, %6.3f?n", f->frame, f->angle * 90 / atan2(1,0), f->majorAxis, f->minorAxis, f->normalized.pos.x, f->normalized.pos.y, f->normalized.vel.x, f->normalized.vel.y, f->identifier, f->state, f->foo3, f->foo4, f->size, f->unk2); */ TouchPoint &t = touchPoints[f->identifier]; t.pos.x = f->normalized.pos.x; t.pos.y = 1 - f->normalized.pos.y; t.size = f->size; t.enable = true; t.id = f->identifier; t.vel.x = f->normalized.vel.x; t.vel.y = f->normalized.vel.y; t.stat = f->foo3; } return 0; } void testApp::setup() { touchPoints.resize(20); NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList(); for(int i = 0; i < [deviceList count]; i ++) { MTRegisterContactFrameCallback([deviceList objectAtIndex:i], mtCallback); MTDeviceStart([deviceList objectAtIndex:i], 0); } ofEnableSmoothing(); ofEnableAlphaBlending(); ofSetVerticalSync(true); ofSetFrameRate(60); ofHideCursor(); ofBackground(0, 0, 0); ofSetColor(255, 255, 255); ofNoFill(); width = ofGetWidth(); height = ofGetHeight(); send.setup("127.0.0.1", TUIOPORT); } void testApp::update() { } void testApp::draw() { for (int i = 0; i < touchPoints.size(); i++) { TouchPoint &t = touchPoints[i]; if (t.enable == false) { continue; } float xx = t.pos.x * width; float yy = t.pos.y * height; ofCircle(xx, yy, t.size * 50); ofDrawBitmapString("x: " + ofToString(t.pos.x*width), xx-10, yy-15); ofDrawBitmapString("y: " + ofToString(t.pos.y*height), xx-10, yy); ofDrawBitmapString("ID :" + ofToString(t.id), xx-10, yy+15); ofDrawBitmapString("ID :" + ofToString(t.id), xx-10, yy+15); cout << t.stat << endl; ofxOscMessage m; m.setAddress("/tuio/2Dcur"); m.addStringArg("set"); m.addIntArg(t.id); m.addFloatArg(t.pos.x); m.addFloatArg(t.pos.y); m.addFloatArg(t.vel.x); m.addFloatArg(t.vel.y); m.addFloatArg(t.vel.x * t.vel.y); send.sendMessage(m); } } void testApp::keyPressed(int key) { if(key == 'f') ofToggleFullscreen(); if (key == 'i') { width = ofGetWidth(); height = ofGetHeight(); } } void testApp::keyReleased(int key) { } void testApp::mouseMoved(int x, int y){ } void testApp::mouseDragged(int x, int y, int button) { } void testApp::mousePressed(int x, int y, int button) { } void testApp::mouseReleased(int x, int y, int button) { } void testApp::windowResized(int w, int h) { }
これを実行すればこんな感じになるはず...
メンバ変数をPrivateにしてないのは(ry
oFの仕様なのか、ofGetWidth()とかはofToggleFullscreen()を実行しても更新されないようです