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 //
/////////////////////////////////////////////////////////
/**
* 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);
}
}