Getting Started with Augmented Reality / FLARToolKit

Create Your First Project with Augmented Reality

Setup a View Class

The FLARManager comes with a Simple Cubes example that allows you to use multiple markers and display a different object on each cube, we are going to take a bit of a different approach. You can do this anywhere you like but I am just going to create a views folder in the root of the src and then a class in there named HelloFlarView.as .

Now we are going to copy most of what was in the Simple Cubes Example with a couple small changes/modifications. Open up the class you just created and past the following into it.

package views {
	// flash
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;
	// flartoolkit
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.pv3d.FLARCamera3D;
	// pv3d
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.render.LazyRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.stats.StatsView;
	import org.papervision3d.view.Viewport3D;
	// flarmanager
	import com.transmote.utils.geom.FLARPVGeomUtils;
	import com.transmote.flar.FLARMarker;

	/**
	 * ...
	 * @author Marc Pelland
	 */
	public class HelloFlarView extends Sprite {

		private static const CUBE_SIZE:Number = 40;
		private var viewport3D:Viewport3D;
		private var camera3D:FLARCamera3D;
		private var scene3D:Scene3D;
		private var renderEngine:LazyRenderEngine;
		private var pointLight3D:PointLight3D;
		private var statsView:StatsView;
		private var stats:Boolean = true;		// display the stats view
		private var marker:FLARMarker;
		private var container:DisplayObject3D;

		/**
		 * create your view
		 * @param	cameraParams
		 * @param	viewportWidth
		 * @param	viewportHeight
		 */
		public function HelloFlarView(cameraParams:FLARParam, viewportWidth:Number, viewportHeight:Number) {
			init3D(cameraParams, viewportWidth, viewportHeight);
		}

		/**
		 * initialize the 3d scene
		 * @param	cameraParams
		 * @param	viewportWidth
		 * @param	viewportHeight
		 */
		private function init3D(cameraParams:FLARParam, viewportWidth:Number, viewportHeight:Number) :void {
			// instantiate the container for the FLAR based scene
			container = new DisplayObject3D();
			scene3D = new Scene3D();
			camera3D = new FLARCamera3D(cameraParams);
			viewport3D = new Viewport3D(viewportWidth, viewportHeight);
			addChild(viewport3D);
			// start the render engine
			renderEngine = new LazyRenderEngine(scene3D, camera3D, viewport3D);
			// create the global light for the scene
			pointLight3D = new PointLight3D();
			pointLight3D.x = 1000;
			pointLight3D.y = 1000;
			pointLight3D.z = -1000;
			// create the stats view
			statsView = new StatsView(renderEngine);
			addChild(statsView);
			// add an enterframe listener to update teh scene and renderer
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		/**
		 * show and hide the stats view
		 */
		public function toggleStatsView():void {
			if (stats) {
				removeChild(statsView);
				stats = false;
			} else {
				addChild(statsView);
				stats = true;
			}
		}

		/**
		 * take the marker and build the scene on it
		 * @param	ARG_marker
		 */
		public function addMarker (ARG_marker:FLARMarker) :void {
			// store marker
			marker = ARG_marker
			// build the 3d scene within the container
			buildScene();
			// add the container to the scene
			scene3D.addChild(container);
		}

		/**
		 * build the 3d scene and add it to the container
		 */
		private function buildScene():void {
			// create a new Cube, and place it inside a container (DisplayObject3D) for manipulation
			var materialsList:MaterialsList = new MaterialsList({all: new FlatShadeMaterial(pointLight3D, 0xffffff, 0x000000)});
			var cube:Cube = new Cube(materialsList, CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
			cube.z = 20;
			// add the cube to the container
			container.addChild(cube);
		}

		/**
		 * clear the marker and remove all the content
		 * @param	marker
		 */
		public function removeMarker (marker:FLARMarker) :void {
			// find and remove marker
			marker = null;
			// find and remove corresponding container
			for (var i:String in container.children) {
				trace(container.children[i]);
				container.removeChild(container.children[i]);
			}
			// remove the container
			scene3D.removeChild(container);
		}

		private function onEnterFrame (evt:Event) :void {
			// update the scene
			updateScene();
			// tell the renderer to render
			renderEngine.render();
		}

		private function updateScene () :void {
			// update all Cube containers according to the transformation matrix in their associated FLARMarkers
			if (marker != null) container.transform = FLARPVGeomUtils.translateFLARMatrixToPVMatrix(marker.transformMatrix);
		}
	}
}

Read the documentation with that file to understand just what I did. It is really close to the SimpleCubes demo, but I removed a couple things that I didn’t really think were needed. I also removed all the references for multiple markers which we are not going to need.

If you would like to customize the 3d scene in any way, check out the buildScene function in the view.

Connect the Controller to Your Class

The controller class that comes with FLARManager is ideal if you are looking to have multiple patterns in the scene, but we just removed that functionality from our view so we will now remove it from the Manager. Paste the following code over your controller:

package {
	import views.HelloFlarView;
	import flash.events.KeyboardEvent;
	import com.transmote.flar.FLARCameraSource;
	import com.transmote.flar.FLARLoaderSource;
	import com.transmote.flar.FLARManager;
	import com.transmote.flar.FLARMarkerEvent;
	import com.transmote.flar.FLARPattern;
	import flash.display.Sprite;
	import flash.events.Event;
	/**
	 * standard FLARToolkit Papervision3D example, with our friends the Cubes.
	 * code is borrowed heavily from Saqoosha, Mikko Haapoja, and Squidder.
	 * http://saqoosha.net/en/flartoolkit/start-up-guide/
	 * http://www.mikkoh.com/blog/?p=182
	 * http://www.squidder.com/2009/03/06/flar-how-to-multiple-instances-of-multiple-markers/#more-285
	 *
	 * @author	Eric Socolofsky
	 * @url		http://transmote.com/flar
	 * @see		updated by marc pelland (www.marcpelland.com)
	 */
	[SWF(width="640", height="480", frameRate="30", backgroundColor="#FFFFFF")]
	public class FLARManagerTest_PV3D extends Sprite {

		private static const CAMERA_PARAMS_PATH:String = "../resources/flar/FLARparams.dat";
		private static const PATTERN_PATH:String = "../resources/flar/patterns/";
		private static const PATTERN_RESOLUTION:uint = 16;

		private var pattern:FLARPattern;
		private var flarManager:FLARManager;
		private var flarLoader:FLARLoaderSource;
		private var helloFlarView:HelloFlarView;

		public function FLARManagerTest_PV3D () {
			init();
		}

		private function init () :void {
			// build list of FLARPatterns for FLARToolkit to detect
			var patterns:Vector.<FLARPattern> = new Vector.<FLARPattern>();
			patterns.push(new FLARPattern(PATTERN_PATH+"pattern.patt", PATTERN_RESOLUTION));
			pattern = patterns[0];
			// use Camera (default)
			flarManager = new FLARManager(CAMERA_PARAMS_PATH, patterns);
			addChild(FLARCameraSource(flarManager.flarSource));
			// begin listening for FLARMarkerEvents
			flarManager.addEventListener(FLARMarkerEvent.MARKER_ADDED, onMarkerAdded);
			flarManager.addEventListener(FLARMarkerEvent.MARKER_REMOVED, onMarkerRemoved);
			// the flar manager fires an init when it is ready
			flarManager.addEventListener(Event.INIT, onFlarManagerInited);
		}

		/**
		 * key listener
		 * @param	ARG_evt
		 */
		private function onKeyDown(ARG_evt:KeyboardEvent):void {
			// if the user hit the S key
			if (ARG_evt.keyCode == 83) {
				helloFlarView.toggleStatsView();
			}
		}

		/**
		 * when the flar manager has been initiated, initiate your custom view
		 * @param	evt
		 */
		private function onFlarManagerInited (evt:Event) :void {
			helloFlarView = new HelloFlarView(flarManager.cameraParams, stage.stageWidth, stage.stageHeight);
			addChild(helloFlarView);
		}

		/**
		 * function triggered when a marker has been discovered
		 * @param	evt
		 */
		private function onMarkerAdded (evt:FLARMarkerEvent) :void {
			helloFlarView.addMarker(evt.marker);
		}

		/**
		 * triggered when the marker is no longer being discovered in the camera view
		 * @param	evt
		 */
		private function onMarkerRemoved (evt:FLARMarkerEvent) :void {
			helloFlarView.removeMarker(evt.marker);
		}
	}
}

** there is a line : var patterns:Vector.<FLARPattern> = new Vector.<FLARPattern>(); that isn’t displaying properly in the code block and i can’t figure it out… replace it with this previous line.

If you followed along in the documentation you will notice that I am doing a couple basic things, creating the pattern detection and listening for when that is found and lost. I have also added a key listener to add and remove a stats view from you Papervision scene to get a little more detail for debugging.

Now you are ready to test out the scene. I get pretty good results from such a simple setup, when it gets a little bit more complex you will notice a steady decline in frame rate. On the next page we will have a look at optimization.

Leave a Reply

Your email address will not be published. Required fields are marked *