お久しぶりです。今、マルチタッチディスプレイを作っている訳です。
一から作るほどの根気も時間もない訳で、既存のライブラリ、APIを大活用。
方式は最近流行りのFTIRを採用。
tBetaっていうサイトで公開されている、"Community Core Vision"通称CCVってソフトをつかう。かなり使い勝手が良さそうで、TUIOプロトコルをOSCで吐いてくれる。しかも最新のバージョンではFlash向けに直接TCPパケットでも出してくれている。
折角なのでGUI部分はFlashで実装しようと思い、sparkで公開されているマルチタッチライブラリを試してみる。今までXMLSocketしか使えなかったので、直接Socket通信できるようになったため、かなり早いらしい。
のだが、どうにもうまくいかない、、、。
TouchManager.asの
function onData()のところで永遠ループしてしまう、、、。なにか使い方が間違っているだと思う。直そうにも、直接パケットいじっているのでよくわからん。よってそのクラスだけ、XMLSocketをつかう既存のOSCライブラリを埋め込んで、同じ実装にしてみた。よくわからんが、とりあえず動いたので公開。
TouchManagerOSC.as
package multitouch { import flash.display.Stage; import flash.events.Event; import flash.events.ErrorEvent; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; // OSC libraly import org.fwiidom.osc.OSCConnection; import org.fwiidom.osc.OSCConnectionEvent; import org.fwiidom.osc.OSCPacket; public class TouchManagerOSC extends EventDispatcher{ private var _stage:Stage; private var _osc:OSCConnection; private var _currentType:int; private var _currentLev:int; private var _fingers:Object; private var _enableMouse:Boolean; private var _mouseFinger:Finger; private var _mouseFingerId:int = -1; public function TouchManagerOSC(stage:Stage) { _stage = stage; _fingers = new Object(); _enableMouse = false; } public function enableMouse():void { if(!_enableMouse) { _stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); _enableMouse = true; } } public function disableMouse():void { if(_enableMouse) { _stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); _enableMouse = false; } } public function connect(host:String="127.0.0.1", port:int=3000):void { _osc = new OSCConnection(host, port); _osc.connect(); _osc.addEventListener(OSCConnectionEvent.ON_CONNECT, onConnect); _osc.addEventListener(OSCConnectionEvent.ON_PACKET_IN, onData); } private function onConnect(e:Event):void { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_CONNECT, null)); } private function onClose(e:Event):void { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_CLOSE, null)); } private function onMouseDown(e:MouseEvent):void { _mouseFinger = new Finger(_mouseFingerId--); _mouseFinger.x = _stage.mouseX; _mouseFinger.y = _stage.mouseY; dispatchEvent(new TouchEvent(TouchEvent.TOUCH_START, _mouseFinger)); _stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); _stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function onMouseMove(e:MouseEvent):void { _mouseFinger.x = _stage.mouseX; _mouseFinger.y = _stage.mouseY; if(e.buttonDown) { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_MOVE, _mouseFinger)); } else { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_END, _mouseFinger)); } } private function onMouseUp(e:MouseEvent):void { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_END, _mouseFinger)); _stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); _stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function onData(e:OSCConnectionEvent):void { //trace("on data"); var packet:OSCPacket = e.data as OSCPacket; //trace("name is ", packet.name); //trace("data is ", packet.data); // set figer if(packet.data[0] == "set"){ // id var fingerId:int = packet.data[1]; var finger:Finger = _fingers[fingerId]; var exists:Boolean = true; if (finger == null) { // finger is new exists = false; finger = new Finger(fingerId); _fingers[fingerId] = finger; } // X finger.x = int(packet.data[2] * _stage.stageWidth); // Y finger.y = int(packet.data[3] * _stage.stageHeight); // MOTION X // MOTION Y // ACCERELATION if(exists) { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_MOVE, finger)); } else { dispatchEvent(new TouchEvent(TouchEvent.TOUCH_START, finger)); } } // no fingers on stage else if(packet.data[0] == "alive"){ for each( finger in _fingers) { delete _fingers[finger.fingerId]; finger.alive = false; dispatchEvent(new TouchEvent(TouchEvent.TOUCH_END, finger)); } } } private function onError(e:ErrorEvent):void { trace("osc error", e.text); } } }