In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

マルチマーカー対応FLARToolKit

from flartoolkit SimpleCube example
print this marker: http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf
flash.geom.* でFLAR使うテスト。あってるかな、、
座標系まちごうとったから変えた
/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/xTXe
 */

// forked from nutsu's FLARToolKit use flash.geom package test
// forked from mash's FLARToolKit SimpleCube sample
// from flartoolkit SimpleCube example
// print this marker: http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf
//flash.geom.* でFLAR使うテスト。あってるかな、、
//座標系まちごうとったから変えた
package  
{
	import flash.display.Sprite;
	
	[SWF( width=465, height=465, frameRate=30, backgroundColor=0x000000 )]
	public class Main extends Sprite
	{
		private var _mulitiMarker:MulitiMarker;
		public function Main() 
		{
			Wonderfl.capture_delay( 5 );
			_mulitiMarker = new MulitiMarker();
			this.addChild(_mulitiMarker);
		}
	}
}


//マルチマーカー用のAppBaseが無いので、作ってみた。
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.FLARSingleMarkerDetector;
import org.libspark.flartoolkit.detector.FLARMultiMarkerDetector;

[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")]

class ARMulitiAppBase extends Sprite {
	private var _loader:URLLoader;
	private var _cameraFile:String;
	private var _codeFile:String;
	private var _codeFiles:Array;
	private var _width:int;
	private var _height:int;
	private var _codeWidth:int;
	private var _codeWidthes:Array;
	
	protected var _param:FLARParam;
	protected var _raster:FLARRgbRaster_BitmapData;
	protected var _mulitiDetector:FLARMultiMarkerDetector;
	
	protected var _webcam:Camera;
	protected var _video:Video;
	protected var _capture:Bitmap;
	
	private var _multiLoader:MultiLoader;
	public var codeNum:int;
	
	public function ARMulitiAppBase() {
	}
	
	protected function init(cameraFile:String, codeFiles:Array, canvasWidth:int = 320, canvasHeight:int = 240, codeWidthes:Array = null):void {
		_cameraFile = cameraFile;
		_width = canvasWidth;
		_height = canvasHeight;
		_codeFiles = codeFiles.concat();
		codeNum = codeFiles.length;
		
		if (!codeWidthes) {
			codeWidthes = [];
			var n:int = codeFiles.length;
			for (var i:int = 0; i < n; i++) {
				codeWidthes[i] = 80;
			}
		}
		_codeWidthes = codeWidthes.concat();
		
		_loader = new URLLoader();
		_loader.dataFormat = URLLoaderDataFormat.BINARY;
		_loader.addEventListener(Event.COMPLETE, _onLoadParam);
		_loader.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
		_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
		_loader.load(new URLRequest(_cameraFile));
	}
	
	private function _onLoadParam(e:Event):void {
		_loader.removeEventListener(Event.COMPLETE, _onLoadParam);
		_loader.removeEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);
		_loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);
		
		_param = new FLARParam();
		_param.loadARParam(_loader.data);
		_param.changeScreenSize(_width, _height);
		_loader = null;
		
		_multiLoader = new MultiLoader("ARMulitiAppBase");
		var n:int = _codeFiles.length;
		for (var i:int = 0; i < n; i++) {
			_multiLoader.add(_codeFiles[i], { id:String(i) } );
		}
		_multiLoader.addEventListener(MultiLoader.COMPLETE, _onLoadCode);
		_multiLoader.start();
	}
	
	private function _onLoadCode(e:Event):void {
		var codes:Array = [];
		var n:int = codeNum;
		for (var i:int = 0; i < n; i++) {
			codes[i] = new FLARCode(16, 16);
			codes[i].loadARPatt(_multiLoader.getText(String(i)));
		}
		
		_webcam = Camera.getCamera();
		if (!_webcam) {
			throw new Error('No webcam!!!!');
		}
		_webcam.setMode(_width, _height, 30);
		_video = new Video(_width, _height);
		_video.attachCamera(_webcam);
		_capture = new Bitmap(new BitmapData(_width, _height, false, 0), PixelSnapping.AUTO, true);
		
		// setup ARToolkit
		_raster = new FLARRgbRaster_BitmapData(_capture.bitmapData);
		
		_mulitiDetector = new FLARMultiMarkerDetector(_param, codes, _codeWidthes, n);
		_mulitiDetector.setContinueMode(true);
		
		dispatchEvent(new Event(Event.INIT));
	}
	
	protected function onInit():void {
	}
}

//class fileがひとつだと、ドキュメントクラスに継承できないので、別クラス化
//MulitiMarker
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.geom.Utils3D;
import org.libspark.flartoolkit.core.FLARMat;
import org.libspark.flartoolkit.core.param.FLARParam;
import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
import org.libspark.flartoolkit.core.types.FLARIntSize;
import org.libspark.flartoolkit.example.ARAppBase;
import org.libspark.flartoolkit.detector.FLARMultiMarkerDetector;
class MulitiMarker extends ARMulitiAppBase {
	private var _base:Sprite;
	private var _fr_mat:Matrix3D;
	private var _projmat:Matrix3D;
	private var _projectMatrixes:Vector.<Matrix3D>;
	private var _view:View;
	
	public function MulitiMarker() 
	{
		addEventListener(Event.INIT, _onInit);
		init('http://assets.wonderfl.net/static/flar/camera_para.dat', ['http://assets.wonderfl.net/static/flar/flarlogo.pat','http://mztm.heteml.jp/umhr/wonderfl/gap.pat','http://mztm.heteml.jp/umhr/wonderfl/uniqlo.pat']);
	}
	
	private function _onInit(e:Event):void 
	{
		addChild( _base = new Sprite() );
		
		//
		_capture.width = 640;
		_capture.height = 480;
		_base.addChild(_capture);
		//
		
		_view = new View();
		_view.x = 320;
		_view.y = 240;
		_view.scaleX = _view.scaleY = 2;
		this.addChild(_view);
		//
		_fr_mat = new Matrix3D();
		initCamera( this._param );
		
		_projectMatrixes = new Vector.<Matrix3D>();
		var n:int = this.codeNum;
		for ( var i:int = 0; i < n; i++ ) {
			_projectMatrixes[i] = new Matrix3D();
		}
		
		//
		_projmat = new Matrix3D();
		
		//
		stage.addEventListener(Event.ENTER_FRAME, _onEnterFrame);
	}
	
	private function _onEnterFrame(e:Event):void 
	{
		_capture.bitmapData.draw(_video);
		var i_indexFromIndex:Array = [];
		var n:int = this.codeNum;
		var detectedes:Array = [];
		for (var i:int = 0; i < n; i++) {
			detectedes[i] = -1;
			i_indexFromIndex[i] = -1;
		}
		var detected:Boolean = false;
		try {
			var m:int = _mulitiDetector.detectMarkerLite(_raster, 80);
			if (m > 0) {
				for (i = 0; i < m; i++) {
					var j:int = _mulitiDetector.getARCodeIndex(i);
					var conf:Number = _mulitiDetector.getConfidence(i);
					if (conf > detectedes[j]) {
						if (conf > 0.5) {
							i_indexFromIndex[i] = j;
							detectedes[j] = conf;
							detected = true;
						}
					}
				}
			}
		} catch (e:Error) {}

		if (detected) {
			for (i = 0; i < n; i++) {
				j = i_indexFromIndex[i];
				if (j == -1) { continue };
				var rmatrixes:FLARTransMatResult = new FLARTransMatResult();
				_mulitiDetector.getTransmationMatrix(i, rmatrixes);
				var de_mat:Matrix3D = new Matrix3D();
				de_mat.rawData = Vector.<Number>(
					[  rmatrixes.m00,   rmatrixes.m10,   rmatrixes.m20, 0,
					   rmatrixes.m01,   rmatrixes.m11,   rmatrixes.m21, 0,
					   rmatrixes.m02,   rmatrixes.m12,   rmatrixes.m22, 0,
					   rmatrixes.m03,   rmatrixes.m13,   rmatrixes.m23, 1 ]
				);
				_projectMatrixes[j].rawData = Vector.<Number>([0,1,0,0, 1,0,0,0, 0,0,1,0, 0,0,0,1]);
				_projectMatrixes[j].append( de_mat );
				_projectMatrixes[j].append( _fr_mat );
			}
			_view.drawObjects(detectedes, _projectMatrixes);
			_view.visible = true;
		} else {
			_view.visible = false;
		}
	}
	
	//無駄あったから整理した
	private function initCamera( param:FLARParam ):void
	{
		var  size:FLARIntSize = param.getScreenSize();
		var  width:int  = size.w;
		var  height:int = size.h;
		var  tMat:FLARMat = new FLARMat (3, 4);
		var  iMat:FLARMat = new FLARMat (3, 4);
		param.getPerspectiveProjectionMatrix().decompMat(iMat, tMat);
		var icpara:Array = iMat.getArray();
		for (var i:int = 0; i < 4; i++) {
			icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];
		}
		var w:Number = icpara[0][0] / icpara[2][2];
		var h:Number = -icpara[1][1] / icpara[2][2];
		_fr_mat.rawData = Vector.<Number>(
			[ w,  0,  0,  0,
			  0,  h,  0,  0,
			  0,  0,  1,  1,
			  0,  0,  0,  0 ]
		);
	}
}

//立方体を描画
import flash.display.Sprite;
class View extends Sprite {
	private var _view:Shape;
	private var g:Graphics;
	private var vert1:Vector.<Number>;
	private var uvt1:Vector.<Number>;
	private var vert2:Vector.<Number>;
	private var uvt2:Vector.<Number>;
	private var vout:Vector.<Number>;
	public function View():void {
		
		_view = new Shape();
		this.addChild(_view);
		g = _view.graphics;
		initARObjects();
	}
	private function initARObjects():void
	{
		// Create Plane with same size of the marker.
		vert1 = new Vector.<Number>();
		uvt1  = new Vector.<Number>();
		var w:Number = 40;
		vert1.push( 0, 0, 0, 
					-w, -w, 0, w, -w, 0, w, w, 0, -w, w, 0,
					w, 0, 0, 0, w, 0, 0, 0, w );
		for ( var i:int = 0; i < vert1.length; i++ ) {
			uvt1.push( 0 );
		}
		
		//cube
		vert2 = new Vector.<Number>();
		uvt2  = new Vector.<Number>();
		w /= 2;
		vert2.push( -w, -w, -w,   w, -w, -w,   w, w, -w,   -w, w, -w,
					-w, -w,  w,   w, -w,  w,   w, w,  w,   -w, w,  w );
		for ( i = 0; i < vert1.length; i++ ) {
			uvt1.push( 0 );
		}
		
		vout = new Vector.<Number>();
	}
	public function drawObjects(detectedes:Array, projectMatrixes:Vector.<Matrix3D>):void
	{
		g.clear();
		var colors:Array = [0x00FF00, 0x0000FF, 0xFF0000];
		var n:int = detectedes.length;
		for (var i:int = 0; i < n; i++) {
			if (detectedes[i] == -1) { continue };
			vout.length = 0;
			Utils3D.projectVectors( projectMatrixes[i], vert1, vout, uvt1 );
			g.lineStyle( 2, 0xffffff );
			g.beginFill( colors[i], 0.2 );
			quad( vout[2], vout[3], vout[4], vout[5], vout[6], vout[7], vout[8], vout[9] );
			g.endFill();
			//x axis
			g.lineStyle( 2, 0xff0000 );
			line( vout[0], vout[1], vout[10], vout[11] );
			//y axis
			g.lineStyle( 2, 0x0000ff );
			line( vout[0], vout[1], vout[12], vout[13] );
			//z axis
			g.lineStyle( 2, 0x00ff00 );
			line( vout[0], vout[1], vout[14], vout[15] );
			
			//cube
			var mat:Matrix3D = new Matrix3D();
			mat.appendTranslation( 0, 0, 20 );
			var vert2t:Vector.<Number> = new Vector.<Number>();
			mat.transformVectors( vert2, vert2t );
			vout.length = 0;
			Utils3D.projectVectors( projectMatrixes[i], vert2t, vout, uvt2 );
			g.lineStyle( 1, colors[i] );
			quad( vout[0], vout[1], vout[2], vout[3], vout[4], vout[5], vout[6], vout[7] );
			quad( vout[8], vout[9], vout[10], vout[11], vout[12], vout[13], vout[14], vout[15] );
			line( vout[0], vout[1], vout[8], vout[9] );
			line( vout[2], vout[3], vout[10], vout[11] );
			line( vout[4], vout[5], vout[12], vout[13] );
			line( vout[6], vout[7], vout[14], vout[15] );
		}
	}
	
	private function line( x0:Number, y0:Number, x1:Number, y1:Number ):void
	{
		g.moveTo( x0, y0 );
		g.lineTo( x1, y1 );
	}
	
	private function quad( x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number ):void
	{
		g.moveTo( x0, y0 );
		g.lineTo( x1, y1 );
		g.lineTo( x2, y2 );
		g.lineTo( x3, y3 );
		g.lineTo( x0, y0 );
	}
}

/*
* Fileローダー
* */
	
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.utils.Dictionary;

class MultiLoader{
	public static var IMAGE_EXTENSIONS:Array = ["swf", "jpg", "jpeg", "gif", "png"];
	public static var TEXT_EXTENSIONS:Array = ["txt", "js", "xml", "php", "asp", "pat"];
	public static const COMPLETE:String = "complete";
	private var _listener:Function = function(event:Event):void{};
	private var _loads:Dictionary;
	private var _keyFromId:Dictionary;
	private var _loadCount:int;
	private var _itemsLoaded:int;
	public var items:Array;
	public function MultiLoader(name:String){
		_loads = new Dictionary();
		_keyFromId = new Dictionary();
		_itemsLoaded = 0;
		items = [];
	}
	public function add(url:String, props:Object = null):void {	
		var loadingItem:LoadingItem = new LoadingItem();
		loadingItem.url = new URLRequest(url);
		loadingItem.type = getType(url);
		if(props){
			if(props.context){
				loadingItem.context = props.context;
			}
			if (props.id) {
				_keyFromId[props.id] = url;
			}
		}
		items.push(loadingItem); 
	}
	private function getType(url:String):String{
		var i:int;
		var extension:String;
		var n:int = IMAGE_EXTENSIONS.length;
		var result:String = "";
		for (i = 0; i < n; i++) {
			extension = IMAGE_EXTENSIONS[i];
			if(extension == url.substr(-extension.length).toLowerCase()){
				result = "image";
				break;
			}
		}
		if(result == ""){
			n = TEXT_EXTENSIONS.length;
			for (i = 0; i < n; i++) {
				extension = TEXT_EXTENSIONS[i];
				if(extension == url.substr(-extension.length).toLowerCase()){
					result = "text";
					break;
				}
			}
		}
		return result;
	}
	
	public function start():void{
		var n:int = items.length;
		for (var i:int = 0; i < n; i++) {
			var type:String = items[i].type;
			if(type == "image"){
				_loads[items[i].url.url] = loadImage(items[i].url,items[i].context);
			}if(type == "text"){
				_loads[items[i].url.url] = loadText(items[i].url);
			}
			
		}
	}
	public function addEventListener(type:String,listener:Function):void{
		_listener = listener;
	}
	public function getBitmap(key:String):Bitmap{
		key = keyMatching(key);
		var bitmap:Bitmap = _loads[key].content;
		return bitmap;
	}
	public function getBitmapData(key:String):BitmapData{
		key = keyMatching(key);
		var bitmap:Bitmap = getBitmap(key);
		var bitmapData:BitmapData = new BitmapData(bitmap.width,bitmap.height);
		bitmapData.draw(bitmap);
		return bitmapData;
	}
	private function loadImage(url:URLRequest, context:LoaderContext = null):Loader {
		var loader:Loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
		loader.load(url,context);
		return loader;
	}
	public function getText(key:String):String {
		key = keyMatching(key);
		return _loads[key].data;
	}
	private function keyMatching(key:String):String {
		return _loads[key]?key:_keyFromId[key];
	}
	
	private function loadText(url:URLRequest):URLLoader{
		var loader:URLLoader = new URLLoader();
		loader.addEventListener(Event.COMPLETE,onComp);
		loader.load(url);
		return loader;
	}
	private function onComp(event:Event):void{
		_itemsLoaded ++;
		if(_itemsLoaded == items.length){
			_listener(event);
		}
	}
	public function get itemsTotal():int{
		return items.length;
	}
	public function get itemsLoaded():int{
		return _itemsLoaded;
	}
	public function get loadedRatio():Number {
		return _itemsLoaded/items.length;
	}
}
class LoadingItem{
	public var url:URLRequest;
	public var type:String;
	public var status:String;
	public var context:LoaderContext;
	public function LoadingItem(){};
}