TouchManagerOSC.as

お久しぶりです。今、マルチタッチディスプレイを作っている訳です。

一から作るほどの根気も時間もない訳で、既存のライブラリ、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);
		}
			
	}
}