«

»

10月 08

FLARToolKit その2 マルチマーカー

このエントリーを含むはてなブックマークはてなブックマーク - FLARToolKit その2 マルチマーカー Googleブックマークに追加 このエントリをつぶやくこのWebページのtweets

今回はFLARToolKitのマルチマーカーをやってみました。

デモ
マーカーはこちらで公開されているものを使っています。

ソース

package {
	
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import org.libspark.betweenas3.BetweenAS3;
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.materials.special.Letter3DMaterial;
	import org.papervision3d.typography.Font3D;
	import org.papervision3d.typography.Text3D;
	import org.papervision3d.typography.VectorLetter3D;
	import org.papervision3d.typography.fonts.HelveticaBold;
	
	[SWF(width=640, height=480, backgroundColor=0x0, frameRate=30)]
	
	public class AR_sample02 extends PV3DARApp {
		
		public function AR_sample02() {
			this.init('Data/camera_para.dat', 'Data/flarlogo.pat');
		}
		
		protected override function onInit():void {
			super.onInit();

			
			this.addEventListener(Event.ENTER_FRAME, this._onEnterFrame);
		}
		
		
		private function _onEnterFrame(e:Event):void {
		}
	}
}
package {
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	
	import flashx.textLayout.conversion.PlainTextExporter;
	
	import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
	import org.libspark.flartoolkit.support.pv3d.FLARBaseNode;
	import org.libspark.flartoolkit.support.pv3d.FLARCamera3D;
	import org.papervision3d.core.effects.BitmapLayerEffect;
	import org.papervision3d.core.effects.utils.BitmapClearMode;
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.LazyRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.view.layer.BitmapEffectLayer;
	
	public class PV3DARApp extends ARAppBase {
		
		protected var _base:Sprite;
		protected var _viewport:Viewport3D;
		protected var _camera3d:org.libspark.flartoolkit.support.pv3d.FLARCamera3D;
		protected var _scene:Scene3D;
		protected var _renderer:LazyRenderEngine;
		protected var _baseNode:org.libspark.flartoolkit.support.pv3d.FLARBaseNode;
		protected var _baseNodes:Array = [];
		
		protected var _resultMat:Array = [];
		protected var planes:Array = [];
		private var _layer:BitmapEffectLayer;
		
		private var _enableDetection:Boolean = true;
		private var _count:int = 0;
		public static const colorAry:Array = [16711680,16712704,16713728,16715008,16716032,16717056,16718080,16719360,16720384,16721408,16722432,16723712,16724736,16725760,16727040,16728064,16729088,16730112,16731392,16732416,16733440,16734464,16735744,16736768,16737792,16738816,16740096,16741120,16742144,16743168,16744448,16745472,16746496,16747520,16748800,16749824,16750848,16751872,16753152,16754176,16755200,16756224,16757504,16758528,16759552,16760576,16761856,16762880,16763904,16764928,16766208,16767232,16768256,16769280,16770560,16771584,16772608,16773632,16774912,16775936,16776960,16514816,16187136,15924992,15662848,15400704,15073024,14810880,14548736,14286592,13958912,13696768,13434624,13172480,12844800,12582656,12320512,12058368,11796224,11468544,11206400,10944256,10682112,10354432,10092288,9830144,9568000,9240320,8978176,8716032,8453888,8126208,7864064,7601920,7339776,7012096,6749952,6487808,6225664,5897984,5635840,5373696,5111552,4783872,4521728,4259584,3997440,3669760,3407616,3145472,2883328,2555648,2293504,2031360,1769216,1441536,1179392,917248,655104,327424,65280,65284,65288,65293,65297,65301,65306,65310,65314,65318,65322,65327,65331,65335,65340,65344,65348,65352,65356,65361,65365,65369,65374,65378,65382,65386,65390,65395,65399,65403,65408,65412,65416,65420,65425,65429,65433,65437,65442,65446,65450,65454,65459,65463,65467,65471,65475,65480,65484,65488,65493,65497,65501,65505,65509,65514,65518,65522,65527,65531,65535,64511,63487,62207,61183,60159,58879,57855,56831,55807,54783,53503,52479,51455,50175,49151,48127,47103,46079,44799,43775,42751,41727,40447,39423,38399,37375,36095,35071,34047,33023,31743,30719,29695,28415,27391,26367,25343,24319,23039,22015,20991,19711,18687,17663,16639,15615,14335,13311,12287,11007,9983,8959,7935,6911,5631,4607,3583,2303,1279,255,262399,524543,852223,1114367,1376511,1638655,1966335,2228479,2490623,2818303,3080447,3342591,3604735,3932415,4194559,4456703,4718847,4980991,5308671,5570815,5832959,6095103,6422783,6684927,6947071,7274751,7536895,7799039,8061183,8388863,8651007,8913151,9175295,9437439,9765119,10027263,10289407,10617087,10879231,11141375,11403519,11731199,11993343,12255487,12517631,12779775,13107455,13369599,13631743,13893887,14221567,14483711,14745855,15073535,15335679,15597823,15859967,16187647,16449791,16711935,16711931,16711927,16711922,16711918,16711914,16711910,16711905,16711901,16711897,16711892,16711888,16711884,16711880,16711875,16711871,16711867,16711863,16711859,16711854,16711850,16711846,16711842,16711837,16711833,16711829,16711824,16711820,16711816,16711812,16711808,16711803,16711799,16711795,16711791,16711786,16711782,16711778,16711773,16711769,16711765,16711761,16711756,16711752,16711748,16711744,16711740,16711735,16711731,16711727,16711723,16711718,16711714,16711710,16711705,16711701,16711697,16711693,16711688,16711684];
		
		public function PV3DARApp() {
		}
		
		protected override function onInit():void {
			super.onInit();
			
			this._base = this.addChild(new Sprite()) as Sprite;
			
			this._capture.width = 640;
			this._capture.height = 480;
			this._base.addChild(this._capture);
			
			this._viewport = this._base.addChild(new Viewport3D(320, 240)) as Viewport3D;
			this._viewport.scaleX = 640 / 320;
			this._viewport.scaleY = 480 / 240;
			this._viewport.x = -4; // 4pix ???
			
			this._camera3d = new FLARCamera3D(this._param);
			
			this._scene = new Scene3D();
			
			for(var i:int = 0; i < 2; i++){
				var node:FLARBaseNode = new FLARBaseNode();
				_baseNodes.push(node);
				_scene.addChild(node);
			}
			
			this._renderer = new LazyRenderEngine(this._scene, this._camera3d, this._viewport);
			
			//			_layer = new BitmapEffectLayer(_viewport, 640, 480, true, 0x000000, BitmapClearMode.CLEAR_PRE, true);
			//			_layer.addEffect(new BitmapLayerEffect(new BlurFilter(8, 8, 4), false));
			//			_viewport.containerSprite.addLayer(_layer);
			
			this.addEventListener(Event.ENTER_FRAME, this._onEnterFrame);
		}
		
		private function _onEnterFrame(e:Event = null):void {
			this._capture.bitmapData.draw(this._video);
			
			// マーカー認識
			var numSquare:int = _detector.detectMarkerLite(_raster, 128);
			var detectedMarker:Array = [];
			var i:int;
			for (i = 0; i < numSquare; i++) {
				// 認識度 0.5 以上をマーカーとみなす
				if (_detector.getConfidence(i) > 0.3) {
					// i 個目の変換行列保存オブジェクトは存在する?
					if (!_resultMat[i]) {
						// なかったら作る
						_createNew(i);
					}
					// 変換行列をとりだして、
					_detector.getTransformMatrix(i, _resultMat[i]);
					// マーカーノードにセット。
					_baseNodes[i].setTransformMatrix(_resultMat[i]);
					detectedMarker.push(_baseNodes[i]);
				}
			}
			
			if(detectedMarker.length >= 1){
				for(i = 0; i < 2; i++){
					var m:ColorMaterial = new ColorMaterial(colorAry[_count]);
					_count = (_count+2)%360;
					m.doubleSided = true;
					var p:Plane = new Plane(m, 5, 5);
					p.x = detectedMarker[0].x;
					p.y = detectedMarker[0].y;
					p.z = detectedMarker[0].z;
					p.useOwnContainer = true;
					p.filters = [new BlurFilter(4, 4, 4)];
					
					var localRot:Matrix3D = Matrix3D.euler2matrix(new Number3D(0, 180, 90));
					var rot:Number3D = Matrix3D.matrix2euler(Matrix3D.multiply3x3(detectedMarker[0].transform, localRot));
					p.rotationX = rot.x;
					p.rotationY = rot.y;
					p.rotationZ = rot.z;
					
					var vec:Number3D = new Number3D(Math.random()*5-2.5, Math.random()*5-2.5, -16);
					Matrix3D.multiplyVector3x3(detectedMarker[0].transform, vec);
					p.extra = vec;
					planes.push(p);
					_scene.addChild(p);
				}
			}
			
			i = planes.length;
			while(i--){
				p = planes[i] as Plane;
				p.x += p.extra.x;
				p.y += p.extra.y;
				p.z += p.extra.z;
				p.material.fillAlpha -= 0.01;
				
				if(detectedMarker.length >= 2){
					var vx:Number = detectedMarker[1].x-p.x, vy:Number = detectedMarker[1].y-p.y, vz:Number = detectedMarker[1].z-p.z;
					var s:Number = Math.sqrt(vx*vx + vy*vy + vz*vz);
					
					p.extra.x += vx/s*1.2;
					p.extra.y += vy/s*1.2;
					p.extra.z += vz/s*1.2;
					
					s = Math.sqrt(p.extra.x*p.extra.x + p.extra.y*p.extra.y + p.extra.z*p.extra.z);
					p.extra.x = p.extra.x/s*10;
					p.extra.y = p.extra.y/s*10;
					p.extra.z = p.extra.y/s*20;
				}
				
				if(p.material.fillAlpha <= 0){
					planes.splice(i, 1);
					_scene.removeChild(p);
				}
			}
			
			this._renderer.render();
		}
		
		// 新しい変換行列保存オブジェクトとマーカーノードをつくる。
		private function _createNew(index:int):void {
			_resultMat[index] = new FLARTransMatResult();
			_baseNodes[index] = _scene.addChild(new FLARBaseNode(FLARBaseNode.AXIS_MODE_PV3D));
			_baseNodes[index].visible = false;
			_baseNodes[index].name = index;
		}
		
		public function set mirror(value:Boolean):void {
			if (value) {
				this._base.scaleX = -1;
				this._base.x = 640;
			} else {
				this._base.scaleX = 1;
				this._base.x = 0;
			}
		}
		
		public function get mirror():Boolean {
			return this._base.scaleX < 0;
		}
		
		public function get enableDetection():Boolean {
			return this._enableDetection;
		}
		
		public function set enableDetection(value:Boolean):void {
			this._enableDetection = value;
		}
	}
}
package {
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	
	import org.libspark.flartoolkit.core.FLARCode;
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
	import org.libspark.flartoolkit.detector.FLARMultiMarkerDetector;
	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
	
	[Event(name="init",type="flash.events.Event")]
	[Event(name="init",type="flash.events.Event")]
	[Event(name="ioError",type="flash.events.IOErrorEvent")]
	[Event(name="securityError",type="flash.events.SecurityErrorEvent")]
	
	public class ARAppBase extends Sprite {
		
		private var _loader:URLLoader;
		private var _cameraFile:String;
		private var _codeFile:String;
		private var _width:int;
		private var _height:int;
		private var _codeWidth:int;
		
		protected var _param:FLARParam;
		protected var _code:FLARCode;
		protected var _raster:FLARRgbRaster_BitmapData;
		protected var _detector:FLARMultiMarkerDetector;
		
		protected var _webcam:Camera;
		protected var _video:Video;
		protected var _capture:Bitmap;
		
		public function ARAppBase() {
		}
		
		protected function init(cameraFile:String, codeFile:String, canvasWidth:int = 320, canvasHeight:int = 240, codeWidth:int = 80):void {
			this._cameraFile = cameraFile;
			this._width = canvasWidth;
			this._height = canvasHeight;
			this._codeFile = codeFile;
			this._codeWidth = codeWidth;
			
			this._loader = new URLLoader();
			this._loader.dataFormat = URLLoaderDataFormat.BINARY;
			this._loader.addEventListener(Event.COMPLETE, this._onLoadParam);
			this._loader.addEventListener(IOErrorEvent.IO_ERROR, this.dispatchEvent);
			this._loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.dispatchEvent);
			this._loader.load(new URLRequest(this._cameraFile));
		}
		
		private function _onLoadParam(e:Event):void {
			this._loader.removeEventListener(Event.COMPLETE, this._onLoadParam);
			this._param = new FLARParam();
			this._param.loadARParam(this._loader.data);
			this._param.changeScreenSize(this._width, this._height);
			
			this._loader.dataFormat = URLLoaderDataFormat.TEXT;
			this._loader.addEventListener(Event.COMPLETE, this._onLoadCode);
			this._loader.load(new URLRequest(this._codeFile));
		}
		
		private function _onLoadCode(e:Event):void {
			this._code = new FLARCode(16, 16);
			this._code.loadARPatt(this._loader.data);
			
			this._loader.removeEventListener(Event.COMPLETE, this._onLoadCode);
			this._loader.removeEventListener(IOErrorEvent.IO_ERROR, this.dispatchEvent);
			this._loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.dispatchEvent);
			this._loader = null;
			
			// setup webcam
			this._webcam = Camera.getCamera();
			if (!this._webcam) {
				throw new Error('No webcam!!!!');
			}
			this._webcam.setMode(this._width, this._height, 30);
			this._video = new Video(this._width, this._height);
			this._video.attachCamera(this._webcam);
			this._capture = new Bitmap(new BitmapData(this._width, this._height, false, 0), PixelSnapping.AUTO, true);
			
			// setup ARToolkit
			this._raster = new FLARRgbRaster_BitmapData(this._capture.bitmapData);
			var v1:Vector.=new Vector., v2:Vector. = new Vector.;
			v1.push(_code); v2.push(_codeWidth);
			this._detector = new FLARMultiMarkerDetector(this._param, v1, v2, 1);
			
			this.onInit();
		}
		
		protected function onInit():void {
		}
	}
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次の HTMLタグおよび属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>