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

Augmented reality moebius strip

THIS AUGMENTED REALITY EXAMPLE DOESN'T NEED WEB-CAM
/////////////////////////////////////////////////////////
INSTRUCTIONS                     //
If you HAVE a web-cam: print and use this marker:      //
http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf//
//
If you DON'T HAVE a web-cam: use your mouse to rotate  //
the maker, the mouse wheel to move it closer or      //
farther and the arrow keys to move it around         //
/////////////////////////////////////////////////////////
Get Adobe Flash player
by Karl94 28 May 2010
/**
 * Copyright Karl94 ( http://wonderfl.net/user/Karl94 )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/8J5a
 */

// forked from Karl94's flash on 2010-5-8
//THIS AUGMENTED REALITY EXAMPLE DOESN'T NEED WEB-CAM
///////////////////////////////////////////////////////////
//                      INSTRUCTIONS                     //
//If you HAVE a web-cam: print and use this marker:      //
//http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf//
//                                                       //
//If you DON'T HAVE a web-cam: use your mouse to rotate  //
//  the maker, the mouse wheel to move it closer or      //
//  farther and the arrow keys to move it around         //
///////////////////////////////////////////////////////////

package{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.GraphicsBitmapFill;
	import flash.display.GraphicsSolidFill;
	import flash.display.GraphicsStroke;
	import flash.display.GraphicsTrianglePath;
	import flash.display.IGraphicsData;
	//import flash.display.TriangleCulling;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.StatusEvent;
	import flash.geom.Matrix3D;
	import flash.geom.Utils3D;
	import flash.geom.Vector3D;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.system.Security;
	import flash.system.SecurityPanel;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.ui.Keyboard;
	
	
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
	import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
	import org.libspark.flartoolkit.core.types.FLARIntSize;
	import org.libspark.flartoolkit.core.FLARCode;
	import org.libspark.flartoolkit.core.FLARMat;
	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
	
	[SWF(width=640, height=480, backgroundColor=0x808080, frameRate=30)]
	public class AR extends Sprite{
		private var _loader:URLLoader;
		private var _width:int = 640;
		private var _height:int = 480;
		private var _codeWidth:int = 80;
		
		private var _param:FLARParam;
		private var _code:FLARCode;
		private var _raster:FLARRgbRaster_BitmapData;
		private var _detector:FLARSingleMarkerDetector;
		
		private var _webcam:Camera;
		private var _video:Video;
		private var _marker:FLARCodeImage;
		private var _wrapper:Sprite = new Sprite();
		private var _container:Sprite = new Sprite();
		private var _capture:Bitmap;
		
		private var _resultMat:FLARTransMatResult = new FLARTransMatResult();
		private var _fr_mat:Matrix3D;
		
		private var mesh:Vector.<Number> = new Vector.<Number>();
		private var data:Vector.<IGraphicsData> = Vector.<IGraphicsData>([
			new GraphicsStroke(4, false, "normal", "none", "round", 1.0, new GraphicsSolidFill(0xFF0000, 0.7)),
			new GraphicsTrianglePath(new Vector.<Number>(), new Vector.<int>(), new Vector.<Number>())
		]);
		
		public function AR(){
			_container.x = _width/2;
			_container.y = _height/2;
			
			_loader = new URLLoader();
			_loader.dataFormat = URLLoaderDataFormat.BINARY;
			_loader.addEventListener(Event.COMPLETE, onLoadParam);
			_loader.load(new URLRequest("http://assets.wonderfl.net/static/flar/camera_para.dat"));
			
			createMoebius(40, 20, 25, 5, GraphicsTrianglePath(data[1]), mesh);
		}
		
		private function onLoadParam(e:Event):void {
			_loader.removeEventListener(Event.COMPLETE, onLoadParam);
			_param = new FLARParam();
			_param.loadARParam(_loader.data);
			_param.changeScreenSize(_width, _height);
			
			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 = new Matrix3D(Vector.<Number>([
				w, 0, 0, 0,
				0, h, 0, 0,
				0, 0, 1, 1,
				0, 0, 0, 0 ]
			));
			
			_loader.dataFormat = URLLoaderDataFormat.TEXT;
			_loader.addEventListener(Event.COMPLETE, onLoadCode);
			_loader.load(new URLRequest("http://assets.wonderfl.net/static/flar/flarlogo.pat"));
		}
		
		private function onLoadCode(e:Event):void {
			_code = new FLARCode(16, 16);
			_code.loadARPatt(_loader.data);
			
			_loader.removeEventListener(Event.COMPLETE, onLoadCode);
			_loader = null;
			
			_capture = new Bitmap(new BitmapData(_width, _height, false));
			
			_raster = new FLARRgbRaster_BitmapData(_capture.bitmapData);
			_detector = new FLARSingleMarkerDetector(_param, _code, _codeWidth);
			_detector.setContinueMode(true);
			
			_capture.width = stage.stageWidth;
			_capture.height = stage.stageHeight;
			addChild(_capture);
			addChild(_container);
			
			_webcam = Camera.getCamera();
			if (!_webcam) {
				noCamera();
			}else{
				_video = new Video(_width, _height);
				_video.attachCamera(_webcam);
				if(_webcam.muted){
					_webcam.addEventListener(StatusEvent.STATUS, onStatus);
				}else{
					camera();
				}
			}
		}
		
		private function camera():void{
			_webcam.setMode(_width, _height, 30);
			_wrapper.addChild(_video);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function noCamera():void{
			_marker = new FLARCodeImage(_code);
			_marker.x = _width/2;
			_marker.y = _height/2;
			_marker.z = 0;
			_marker.scaleX = _marker.scaleY = 2;
			_wrapper.addChild(_marker);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			onEnterFrame();
		}
		
		private function onStatus(e:StatusEvent):void{
			_webcam.removeEventListener(StatusEvent.STATUS, onStatus);
			if(e.code == "Camera.Muted"){
				noCamera();
			}else if(e.code == "Camera.Unmuted"){
				camera();
			}
		}
		
		private function onMouseMove(e:MouseEvent):void{
			_marker.transform.matrix3D.pointAt(new Vector3D(e.stageX, e.stageY, -300), new Vector3D(0, 0, -1), new Vector3D(0, -1, 0));
			onEnterFrame();
		}
		
		private function onMouseWheel(e:MouseEvent):void{
			_marker.transform.matrix3D.appendTranslation(0, 0, e.delta*5);
			onEnterFrame();
		}
		
		private function onKeyDown(e:KeyboardEvent):void{
			switch(e.keyCode){
				case Keyboard.UP: _marker.transform.matrix3D.appendTranslation(0, -10, 0);
					break;
				case Keyboard.DOWN: _marker.transform.matrix3D.appendTranslation(0, 10, 0);
					break;
				case Keyboard.RIGHT: _marker.transform.matrix3D.appendTranslation(10, 0, 0);
					break;
				case Keyboard.LEFT: _marker.transform.matrix3D.appendTranslation(-10, 0, 0);
					break;
			}
			onEnterFrame();
		}
		
		private function onEnterFrame(e:Event = null):void{
			if(_marker){
				_capture.bitmapData.fillRect(_capture.bitmapData.rect, 0xFFFFFF);
			}
			_capture.bitmapData.draw(_wrapper);
			
			if (_detector.detectMarkerLite(_raster, 80) && _detector.getConfidence() > 0.3){
				_detector.getTransformMatrix(_resultMat);
				var m:Matrix3D = new Matrix3D(Vector.<Number>([
					_resultMat.m01, _resultMat.m11, _resultMat.m21, 0,
					_resultMat.m00, _resultMat.m10, _resultMat.m20, 0,
					_resultMat.m02, _resultMat.m12, _resultMat.m22, 0,
					_resultMat.m03, _resultMat.m13, _resultMat.m23, 1]
				));
				
				m.append(_fr_mat);
				m.prependTranslation(0, 0, 20);
				
				Utils3D.projectVectors(m, mesh, GraphicsTrianglePath(data[1]).vertices, GraphicsTrianglePath(data[1]).uvtData);
				
				_container.graphics.clear();
				_container.graphics.drawGraphicsData(data);
				_container.alpha = 1;
			}else{
				_container.alpha = 0.3;
			}
		}
		
		private function createMoebius(radius:Number, width:Number, N:uint, S:uint, trianglePathOut:GraphicsTrianglePath, vertices3DOut:Vector.<Number>):void{
			for(var i:uint = 0; i<N; i++){
				for(var j:uint = 0; j<S; j++){
						vertices3DOut.push(
							(radius+(2*j/(S-1)-1)*width/2*Math.cos(Math.PI*i/N))*Math.cos(Math.PI*2*i/N),
							(radius+(2*j/(S-1)-1)*width/2*Math.cos(Math.PI*i/N))*Math.sin(Math.PI*2*i/N),
							(2*j/(S-1)-1)*width/2*Math.sin(Math.PI*i/N)
							);
						trianglePathOut.uvtData.push(i/N, j/(S-1), 1);
				}
			}
			for(i = S; i>0; i--){
				vertices3DOut.push(vertices3DOut[3*i-3], vertices3DOut[3*i-2], vertices3DOut[3*i-1]);
				trianglePathOut.uvtData.push(1, 1-(i-1)/(S-1), 1);
			}
			for(i = 0; i<N/*+1*/; i++){
				for(j = 0; j<S-1; j++){
					var n:uint = i*S+j;
					trianglePathOut.indices.push(n, n+1, n+S+1);
					trianglePathOut.indices.push(n, n+S+1, n+S);
				}
			}
		}
	}
}


import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import org.libspark.flartoolkit.core.FLARCode;

class FLARCodeImage extends Sprite{
	public function FLARCodeImage(code:FLARCode){
		var patBW:Array = code.getPatBW()[1];
		var pWidth:int = code.getWidth();
		var pHeight:int = code.getHeight();

		var bmp:BitmapData = new BitmapData(pWidth, pHeight);
		var bw:uint;
		for(var x:uint = 0; x < pWidth; x++){
			for(var y:uint = 0; y < pHeight; y++){
				bw = (255-((patBW[y][x] & 0xFF)+code.averageOfPattern)) & 0xFF;
				bmp.setPixel(x, y, (bw << 16) | (bw << 8) | bw);
			}
		}
		
		var shape:Shape = new Shape();
		var image:Bitmap = new Bitmap(bmp);
		image.width *= 3;
		image.height *= 3;
		image.x = -image.width/2;
		image.y = -image.height/2;
		
		shape.graphics.beginFill(0x000000);
		shape.graphics.drawRect(-image.width, -image.height, 2*image.width, 2*image.height);
		this.addChild(shape);
		this.addChild(image);
	}
}