oFで純正マルチタッチ
2010.12.13 月曜日
Mac版openFrameworksで純正マルチタッチ入力を取得する方法について。
デバイスを一つしか使わない(MacBookのトラックパッドやiMacにMagicTrackpad)場合はopenFrameworks.jp forum 「MacBookProのトラックパッドでマルチタッチ」のサンプルとかリンク先を見てください。
ここではすでにトラックパッドが搭載されているMacBookにMagicTrackpadをつないでMagicTrackpad側を認識したい場合、など複数のデバイスを混在させoFで認識させる方法について書きます。基本は上のサンプルとほとんど同じで、デバイスの取得で使う関数がObjective-Cで動作させる必要があるので少し変更が必要です。下記コードの変更は24行目と78~82行目の部分がメイン。
まず、oFのemptyExampleをコピーして、addonsの「ofxVectorMath」とフレームワークの「MultitouchSupport.framework」を読み込みます。次に「testApp.cpp」を「testApp.mm」に名称変更し、右クリック>情報を見る>ファイルタイプで「sourcecode.cpp.cpp」を「sourcecode.cpp.objcpp」に変更します。そしてtestApp.mmには以下のコード。
#include "testApp.h"
#include "ofxVectorMath.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:
ofxVec2f pos;
float size;
int id;
bool enable;
float phase;
float freq, amp;
float trem_phase;
};
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;
}
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();
}
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 * ofGetWidth();
float yy = t.pos.y * ofGetHeight();
ofCircle(xx, yy, t.size * 50);
ofDrawBitmapString(ofToString(t.freq, 1), xx, yy);
}
}
void testApp::keyPressed(int key) {
}
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) {
}
Posted by tmdf|openFrameworks