Home / Away 3D 4 AwayPhysics ASFEAT /


So, the only way I found to both use in2ar and awayPhysics, it's to use 2 differents swf. Both in2ar and awayPhysic use 'alchemy's swc'. It appears when you use both in the same swf some memory conflic occurs. So here is my solution. I have on one side a swf contains AWAY3D 4.0 & IN2AR and on a other side a swf dealing physics. The second one is loaded by the first one via a Loader. Each swfs have their own ApplicationDomain. Here is the two class. It uses FP11.2 Beta, in2ar SDK, away3d 4 & awayPhysics. The first one build physic, the second integrate away3d & in2ar.


package
{
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import away3d.entities.Mesh;
	import away3d.lights.DirectionalLight;
	import away3d.lights.PointLight;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.ColorMaterial;
	import away3d.materials.methods.FilteredShadowMapMethod;
	import away3d.primitives.Cube;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.StageVideoAvailabilityEvent;
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.media.Camera;
	import flash.media.StageVideo;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	
	import ru.inspirit.asfeat.ASFEAT;
	import ru.inspirit.asfeat.IASFEAT;
	import ru.inspirit.asfeat.calibration.IntrinsicParameters;
	import ru.inspirit.asfeat.detect.ASFEATReference;
	import ru.inspirit.asfeat.event.ASFEATCalibrationEvent;
	import ru.inspirit.asfeat.event.ASFEATDetectionEvent;
	
	[SWF(width='1024',height='512',frameRate='60',backgroundColor='0xFFFFFF')]
	
	public class In2ARShadow extends Sprite
	{
		//3D
		[Embed(source="../assets/trans.png")]
		private var Skin : Class;
		private var view:View3D ;
		private var light :* ;
		private var isDir:Boolean = true ; 
		private var arrayAwSphere:Vector. = new Vector.() ; 
		private var container:Mesh = new Mesh() ; 
		
		
		// Physics
		private var objectPhysic:Object = new Object()
		private var loader:Loader = new Loader()  ; 
		
		//ASFEAT & CAM
		// embed your data file here
		[Embed(source = '../assets/def_data.ass', mimeType='application/octet-stream')]
		private static const data_ass:Class;
		private var _cambuff:BitmapData ;
		protected var _cam:Camera;
		protected var stageVideo:StageVideo ; 
		public var asfeat:ASFEAT;
		public var asfeatLib:IASFEAT;
		public var intrinsic:IntrinsicParameters;
		public var camWidth:int = 1024;
		public var camHeight:int = 512;
		public var downScaleRatio:Number = 1;
		public var srcWidth:int = 1024; // should be the same as camera size untill downscale is used
		public var srcHeight:int = 512;
		public var maxPointsToDetect:int = 250; // max point to allow on the screen
		public var maxReferenceObjects:int = 1; // max reference objects to be used
		protected var _cambuff_rect:Rectangle;
		protected var _cam_mtx:Matrix;
		protected var _buff_rect:Rectangle;
		protected var _buff_mtx:Matrix;
		protected var _buffer:BitmapData;
		public var ram:ByteArray;	
		public var applicationDomain:ApplicationDomain = ApplicationDomain.currentDomain;
		public var maxTransformError:Number = 10 * 10;

		
		public function In2ARShadow()
		{					
			if(stage) onAddedToStage();
			else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		protected function onAddedToStage(e:Event = null):void
		{			
			removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
			
			ini3D() ;
			
			iniSpheres() ;
			
			loadSwfPhysic() ;				
		}
		
		
		////////////////////////////////////////////StageVideo - Cam - ASFEAT /////////////////////////////////////////////////////////
		
		
		private function preInitASFEAT():void {
			
			asfeat = new ASFEAT(null);
			asfeat.addEventListener( Event.INIT, init ); 
			
		}
		
		protected function initStage():void
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
		}
		
		protected function init(e:Event = null):void
		{
			initStage();

			//			
			srcWidth = camWidth * downScaleRatio;
			srcHeight = camHeight * downScaleRatio;
			
			
			// DIFFERENT OBJECTS USED TO WORK WITH WEB CAMERA 
			_cambuff_rect = _cambuff.rect;
			_cam_mtx = new Matrix(-1.0, 0, 0, 1.0, camWidth);
			
			_buffer = new BitmapData( srcWidth, srcHeight, false, 0x00 );
			_buff_rect = _buffer.rect;
			_buff_mtx = new Matrix(downScaleRatio, 0, 0, downScaleRatio);
			//
			
			// INITIATE ASFEAT/IN2AR LIB
			initASFEAT();
			
			
		}
		
		protected function initASFEAT():void
		{
			trace("Ini ASFEAT") ; 
			
			asfeat.removeEventListener( Event.INIT, init );
			asfeatLib = asfeat.lib;
			
			// just believe me
			ram = new ByteArray();
			ram.endian = Endian.LITTLE_ENDIAN;
			ram.length = asfeatLib.calcRequiredChunkSize(srcWidth, srcHeight, maxPointsToDetect, maxReferenceObjects);
			ram.position = 0;
			applicationDomain.domainMemory = ram;
			
			// init our engine
			asfeatLib.init( ram, 0, srcWidth, srcHeight, maxPointsToDetect, maxReferenceObjects, maxTransformError, stage );
			
			// add reference object
			asfeatLib.addReferenceObject( ByteArray( new data_ass ) );
			
			
			// add event listeners
			asfeatLib.addListener( ASFEATCalibrationEvent.COMPLETE, onCalibDone );
			asfeatLib.addListener( ASFEATDetectionEvent.DETECTED, onModelDetected );
			
		
			
			asfeatLib.setSingleReferenceMode(true);
			
			// indexing reference data will result in huge
			// speed up during matching (see docs for more info)
			asfeatLib.indexReferenceData(16, 12);
			
			// u can repform geometric calibration
			// during detection/tracking (see onCalibDone method)
			asfeatLib.startGeometricCalibration();
			
			intrinsic = asfeatLib.getIntrinsicParams();
			
			
			
		}
		
		protected function onModelDetected(e:ASFEATDetectionEvent):void
		{
			trace("MODEL DETECT") ; 
			
			var refList:Vector. = e.detectedReferences;
			var ref:ASFEATReference;			
			
				ref = refList[0];					
				
				var m:Matrix3D = new Matrix3D() ; 
				m = get3DMatrixLH(ref.rotationMatrix , ref.translationVector) ; 
				m.prependRotation(180,Vector3D.Y_AXIS) ; 
				m.prependRotation(180,Vector3D.Z_AXIS) ; 
				m.prependRotation(-90,Vector3D.X_AXIS) ;
				try{
					container.transform = m ; 
				} catch (e:Error) {}
						
		}
		
		public function get3DMatrixLH(R:Vector., t:Vector.):Matrix3D
		{
			var data:Vector. = new Vector. ;			
			
				data[0] = R[0];
				data[1] = -R[3];
				data[2] = R[6];
				data[3] = 0.0;
				data[4] = R[1];
				data[5] = -R[4];
				data[6] = R[7];
				data[7] = 0.0;
				data[8] = -R[2];
				data[9] = R[5];
				data[10] = -R[8];
				data[11] = 0.0;
				data[12] = t[0];
				data[13] = -t[1];				
				data[14] = t[2]-00; // tZ				
				data[15] = 1.0;				
			
			return new Matrix3D(data) ;
		}
		
		protected function onCalibDone(e:ASFEATCalibrationEvent):void
		{
			trace("ASFEAT Calibration") ;
			
			var fx:Number = (e.fx + e.fy) * 0.5;
			var fy:Number = fx;			
			
			
			intrinsic.update(fx, fy, intrinsic.cx, intrinsic.cy);
			
			asfeatLib.updateIntrinsicParams();						
			
		}
		
		
		private function onStageVideoAvailability(e:StageVideoAvailabilityEvent):void {
			
			if ( stageVideo == null ) 
			{				
				stageVideo = stage.stageVideos [ 0 ] ;				
				//stageVideo.viewPort = new Rectangle ( 0 , 0 , 1024 , 512 ) ;
			}
			
			stageVideo.attachCamera(_cam) ; 
			trace("StageVideo ok") ; 
			addListernerAway3D_ObjectPhysic() ;
			preInitASFEAT() ;
			_cam.addEventListener(Event.VIDEO_FRAME , newFrame) ; 

		}
		
		
		private function getCam(w:int = 1024, h:int = 512, fps:int = 25):void {
			
			_cambuff = new BitmapData( w, h, true, 0x0 );
			_cam = Camera.getCamera(); 			
			_cam.setMode( 1024, 512,25, true );				
			
			trace("Cam ok") ;
			
		}
		
		private function newFrame(e:Event):void {
			
			_cam.drawToBitmapData(_cambuff) ; 			
			asfeatLib.detect( _cambuff );
		    view.backgroundImage = _cambuff ; 			
		}
		
		
		
		///////////////////////////////////////////Away3D & AwayPhysics ////////////////////////////////////////////////////
		
		
		private function loadSwfPhysic():void {
			
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfPhysicIsLoaded);
			loader.load(new URLRequest("TestASFeadPhysic.swf")) ; 
		}
		
		private function swfPhysicIsLoaded(e:Event):void {
			
			trace("Physic is Loaded") ; 
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,swfPhysicIsLoaded) ; 			
			objectPhysic = e.target.content ; 
			
			// ini cam & stageVideo
			getCam() ;			
			stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoAvailability);
			
			
		}
		
		private function addListernerAway3D_ObjectPhysic():void {
			
			stage.addEventListener(Event.ENTER_FRAME,render) ; 
			stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler);
			stage.addEventListener( KeyboardEvent.KEY_UP, keyUpHandler);
		}
		
		private function ini3D():void  {
			
			trace("INI3D")  ; 
			view = new View3D();			
			
			if(!isDir) {
				
				trace("Point Light") ;
				light = new PointLight();
				light.y = 0;
				light.z = -1000;
				view.scene.addChild(light);
				
				view.camera.lens.far = 10000;		
				view.camera.y = light.y;
				view.camera.z = light.z;
			} else {			
				
				trace("Directional light") ; 								
				light = new DirectionalLight(-1, -1, 1);
				light.color = 0xffffee;
				light.position=new Vector3D(1000,1000,1000);				
				view.scene.addChild(light);
				
				view.camera.lens.far = 10000;
				view.camera.z=-2000;
				view.camera.y=1000;
				view.camera.x=0;
				view.camera.lookAt(new Vector3D(0,0,0));
				
			}
			
			//stats
			var ds:DisplayObject  ; 
			ds = new AwayStats(view) ; 
			ds.x = 95 ; 
			this.addChild(ds) ;
			
			addChild(view);
			
		}
		
		private function iniSpheres():void {
			
			var material : ColorMaterial = new ColorMaterial(0xff0000);
			material.shadowMethod = new FilteredShadowMapMethod(light);
			
			material.lights = [light];
			
			var n:int = 0
			for (var i:int = 0 ;i<4 ; i++) {
				
				for (var j:int = 0 ;j<4 ; j++) {
					
					for (var k:int = 0 ;k<4 ; k++) {						
						
						var sphere : AwSphere = new AwSphere(material) ;
						arrayAwSphere[n] = sphere ;
						container.addChild(arrayAwSphere[n].getAwSphere()) ;		
						
						n++
					}
				}
			}			
			
			trace("3D spheres created") ; 
			
			// add a box
			var materialBox : ColorMaterial = new ColorMaterial(0xffffff);
			
			materialBox.shadowMethod = new FilteredShadowMapMethod(light);			
			materialBox.lights = [light];
			materialBox.ambientColor = 0x000000;
			materialBox.ambient = 1;
			materialBox.alpha = 0.05 ; 
			
			var box:Mesh = new Cube(materialBox,20000,10,20000) ; 
			container.addChild(box) ; 
			
			view.scene.addChild(container) ;
		}		
		
		private function keyDownHandler(event:KeyboardEvent):void
		{			
			objectPhysic.keyDownHandler(event) ; 			
		}
		
		private function keyUpHandler(event:KeyboardEvent):void
		{			
			objectPhysic.keyUpHandler(event) ; 			
		}
		
		private function retrievePhysics():void {
			
			for(var j:int = 0 ; j = new Vector.() ; 
		public var v:Vector. = new Vector.
		
		
		
		
		public function TestASFeadPhysic()
		{			
			
			physicsWorld = AWPDynamicsWorld.getInstance();
			physicsWorld.initWithDbvtBroadphase();			
			
			// create box
			var awpB:AWPBoxShape = new AWPBoxShape(20000,10,20000) ;
			var box:AWPRigidBody = new AWPRigidBody(awpB,null,0) ;
			physicsWorld.addRigidBody(box) ; 			
			
			// create sphere
			
			var n:int = 0
			for (var i:int = 0 ;i<4 ; i++) {
				
				for (var j:int = 0 ;j<4 ; j++) {
					
					for (var k:int = 0 ;k<4 ; k++) {
						
						var sphereShape1:AWPSphereShape = new AWPSphereShape(100);				
						
						var s:AWPRigidBody=new AWPRigidBody(sphereShape1,null,2) ;
						s.position = new Vector3D(-300 + i * 200, 100+ k * 200, j * 200) ; 
						s.restitution = 0.7 ;
						s.friction = 1 ; 
						vRb.push(s) ;
						
						physicsWorld.addRigidBody(vRb[n]) ; 
						//trace("crea =" +n) ;
						
						n++ ; 
						
					}					
				}				
			}
			
			trace("physic's sphere created")  ; 
			this.addEventListener(Event.ENTER_FRAME, go) ;
			
		}
		
		public function keyDownHandler(event:KeyboardEvent):void
		{
			trace("down : "+event.keyCode) ;
			
			switch(event.keyCode)
			{
				case Keyboard.UP:
					keyForward = true;
					keyReverse = false;
					break;
				
				case Keyboard.DOWN:
					keyReverse = true;
					keyForward = false;
					break;
				
				case Keyboard.LEFT:
					keyLeft = true;
					keyRight = false;
					break;
				
				case Keyboard.RIGHT:
					keyRight = true;
					keyLeft = false;
					break;
			}
		}
		
		public function keyUpHandler(event:KeyboardEvent):void
		{
			trace("up : "+event.keyCode) ;
			
			switch(event.keyCode)
			{
				case Keyboard.UP:
					keyForward = false;
					break;
				
				case Keyboard.DOWN:
					keyReverse = false;
					break;
				
				case Keyboard.LEFT:
					keyLeft = false;
					break;
				
				case Keyboard.RIGHT:
					keyRight = false;
					break;
			}
		}
		
		
		
		private function go(e:Event):void {
			
			
			if(keyLeft)
			{
				vRb[5].applyCentralForce(new Vector3D( -50, 0, 0));
			}
			if(keyRight)
			{
				vRb[5].applyCentralForce(new Vector3D( 50, 0, 0));
			}
			if(keyForward)
			{
				vRb[5].applyCentralForce(new Vector3D( 0, 0, 50));
			}
			if(keyReverse)
			{
				vRb[5].applyCentralForce(new Vector3D( 0, 0, -50));
			}
			
			getVecs3D() ;
			physicsWorld.step(0.04,1,0.04) ; 
			
		}
		
		public  function getVecs3D():void{			
			
			for(var i :int = 0 ; i
Tags : AS3, In2ar, AwayPhysics, Away3D
comments powered by Disqus