Away3D 4 and FlarToolKit early test
Here is an early test using Flar and Away 3D 4.0. I still have to work on the projection matrix... I broadcast the webcam on a 3D plane to counter the fact stage3D is behind the stage. Check this page later, for the source code. Need to improve it ! Update : Here is the source code, no more 3D plane to display webcam. As in2ar demo, it uses fp11.2 and the new feature cam.drawToBitmapData(bmpData) . This source code is not perfect. I don t use a projection matrix when I should use one.
package
{
import away3d.animators.SkeletonAnimator;
import away3d.animators.SmoothSkeletonAnimator;
import away3d.animators.data.AnimationStateBase;
import away3d.animators.data.SkeletonAnimation;
import away3d.animators.data.SkeletonAnimationSequence;
import away3d.animators.data.SkeletonAnimationState;
import away3d.animators.skeleton.JointPose;
import away3d.animators.skeleton.SkeletonJoint;
import away3d.animators.skeleton.SkeletonPose;
import away3d.cameras.SpringCam;
import away3d.containers.View3D;
import away3d.debug.AwayStats;
import away3d.entities.Mesh;
import away3d.entities.SegmentSet;
import away3d.errors.AbstractMethodError;
import away3d.events.AnimatorEvent;
import away3d.events.AssetEvent;
import away3d.events.LoaderEvent;
import away3d.events.MouseEvent3D;
import away3d.library.AssetLibrary;
import away3d.library.assets.AssetType;
import away3d.lights.DirectionalLight;
import away3d.lights.PointLight;
import away3d.loaders.Loader3D;
import away3d.loaders.misc.AssetLoaderContext;
import away3d.loaders.parsers.MD5AnimParser;
import away3d.loaders.parsers.MD5MeshParser;
import away3d.loaders.parsers.OBJParser;
import away3d.materials.BitmapMaterial;
import away3d.materials.ColorMaterial;
import away3d.materials.methods.BasicDiffuseMethod;
import away3d.materials.methods.BasicSpecularMethod;
import away3d.materials.methods.FilteredShadowMapMethod;
import away3d.materials.methods.FresnelSpecularMethod;
import away3d.materials.methods.SubsurfaceScatteringDiffuseMethod;
import away3d.primitives.Cube;
import away3d.primitives.LineSegment;
import away3d.primitives.Plane;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
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.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.ui.Keyboard;
import flash.utils.ByteArray;
import jp.nyatla.as3utils.NyMultiFileLoader;
import jp.nyatla.nyartoolkit.as3.core.types.matrix.NyARDoubleMatrix34;
import org.libspark.flartoolkit.core.FLARCode;
import org.libspark.flartoolkit.core.analyzer.raster.threshold.FLARRasterThresholdAnalyzer_SlidePTile;
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.detector.FLARSingleMarkerDetector;
import org.libspark.flartoolkit.support.pv3d.FLARBaseNode;
import org.libspark.flartoolkit.support.pv3d.FLARCamera3D;
[SWF(width="1024", height="512", frameRate="60")]
public class AwayFlareHead extends Sprite
{
//Flare
protected var captureWidth:int;
protected var captureHeight:int;
protected var canvasWidth:int;
protected var canvasHeight:int;
protected var codeWidth:int;
protected var cameraParamFile:String;
protected var markerPatternFile:String;
protected var cameraParam:FLARParam;
protected var markerPatternCode:FLARCode;
private var capture:Bitmap;
private var raster:FLARRgbRaster_BitmapData;
private var detector:FLARSingleMarkerDetector;
private var _threshold:int = 110;
private var _threshold_detect:FLARRasterThresholdAnalyzer_SlidePTile;
//protected var camera3d:FLARCamera3D;
protected var markerNode:FLARBaseNode;
protected var resultMat:FLARTransMatResult = new FLARTransMatResult();
// away 3D 4.0
private var view : View3D ;
private var light : PointLight ;
private var mesh:Mesh ;
private var bmpData:BitmapData = new BitmapData(512,256,false) ;
private var bmpMaterial:BitmapMaterial = new BitmapMaterial ;
// anim mdsMesh
private var animationController : SmoothSkeletonAnimator;
private var controller : SmoothSkeletonAnimator;
[Embed(source="assets/av.jpg")]
private var Skin : Class;
[Embed(source="assets/no.jpg")]
private var Norm : Class;
// stageVideo
private var stageVideo:StageVideo ;
//camera
private var cam:Camera ;
//debug
private var xx:int ;
private var yy:int ;
private var zz:int ;
private var x1:int ;
private var y1:int ;
private var z1:int ;
private var tf:TextField ;
[Embed(source="/../embeds/head/head.obj", mimeType="application/octet-stream")]
private var OBJData : Class;
[Embed(source="/../embeds/head/Images/Map-COL.jpg")]
private var Albedo : Class;
[Embed(source="/../embeds/head/Images/Map-spec.jpg")]
private var Specular : Class;
[Embed(source="/../embeds/head/Images/Infinite-Level_02_Tangent_NoSmoothUV.jpg")]
private var Normal : Class;
private var _subsurfaceMethod : SubsurfaceScatteringDiffuseMethod;
private var _diffuseMethod : BasicDiffuseMethod;
private var _material : BitmapMaterial;
private var _fresnelMethod : FresnelSpecularMethod;
private var _specularMethod : BasicSpecularMethod;
public function AwayFlareHead()
{
// ini Cam
getCam() ;
// ini stageVideo and after flar_
stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoAvailability);
stage.addEventListener( KeyboardEvent.KEY_UP, keyUpHandler);
}
private function onStageVideoAvailability(e:StageVideoAvailabilityEvent):void {
if ( stageVideo == null )
{
//set _stageVideo to reference the first of our
//available StageVideo objects (up to 8 available on desktops)
stageVideo = stage.stageVideos [ 0 ] ;
//size and position our _stageVideo with a new Rectangle
//stageVideo.viewPort = new Rectangle ( 0 , 0 , 1024 , 512 ) ;
}
stageVideo.attachCamera(cam) ;
cam.addEventListener(Event.VIDEO_FRAME, newFrame) ;
// ini flar_engine
ini3D() ;
}
private function newFrame(e:Event):void {
cam.drawToBitmapData(bmpData) ;
view.backgroundImage = bmpData ;
//sVideo?cam.drawToBitmapData(bmpData):this.capture.bitmapData.draw(this.video);
// Marker detect
var detected:Boolean = false;
try {
detected = this.detector.detectMarkerLite(this.raster, this._threshold) && this.detector.getConfidence() > 0.5;
} catch (e:Error) {}
if (detected) {
this.dispatchEvent(new MarkerEvent(MarkerEvent.MARKER_ADDED));
} else {
this.dispatchEvent(new MarkerEvent(MarkerEvent.MARKER_REMOVED));
var th:int=this._threshold_detect.analyzeRaster(this.raster);
this._threshold=(this._threshold+th)/2;
}
view.render() ;
}
protected function iniFlare():void
{
trace("INI Flar") ;
captureWidth = 512;
captureHeight = 256;
canvasWidth = 1024 ;
canvasHeight = 512;
this.codeWidth = 80;
this.cameraParamFile = '../resources/Data/camera_para_16x9.dat';
this.markerPatternFile = '../resources/Data/flarlogo.pat';
this.paramLoad();
}
private function paramLoad():void
{
trace("flare paramLoad") ;
var mf:NyMultiFileLoader=new NyMultiFileLoader();
mf.addTarget(
this.cameraParamFile, URLLoaderDataFormat.BINARY,
function(data:ByteArray):void
{
cameraParam = new FLARParam();
cameraParam.loadARParam(data);
cameraParam.changeScreenSize(captureWidth, captureHeight);
});
mf.addTarget(
this.markerPatternFile, URLLoaderDataFormat.TEXT,
function(data:String):void
{
markerPatternCode = new FLARCode(16, 16);
markerPatternCode.loadARPattFromFile(data);
}
);
mf.addEventListener(Event.COMPLETE, initializationWithStageVideo) ;
mf.multiLoad();
return;
}
private function initializationWithStageVideo(e:Event): void
{
trace("initialization with stageVideo") ;
removeEventListener(Event.COMPLETE, initializationWithStageVideo);
bmpData = new BitmapData(captureWidth,captureHeight) ;
cam.drawToBitmapData(bmpData) ;
raster = new FLARRgbRaster_BitmapData(bmpData) ;
// setup Single marker detector
this.detector = new FLARSingleMarkerDetector( this.cameraParam,
this.markerPatternCode,
this.codeWidth);
this.detector.setContinueMode(true);
// this.detector.setAreaRange( 40000, 900);
this._threshold_detect=new FLARRasterThresholdAnalyzer_SlidePTile(15,4);
dispatchEvent(new Event(Event.INIT));
trace("fin init") ;
addFlarListener() ;
}
protected function addFlarListener():void
{
trace("START") ;
this.addEventListener(MarkerEvent.MARKER_ADDED, this.onMarkerAdded);
this.addEventListener(MarkerEvent.MARKER_REMOVED, this.onMarkerRemoved);
}
public function onMarkerAdded(e:Event=null):void
{
var m1:Matrix3D = new Matrix3D
//trace("add") ;
material.alpha = 1 ;
this.detector.getTransformMatrix(this.resultMat);
var m:Matrix3D=new Matrix3D() ;
m = convertNyARMatrixToFlashMatrix3D(this.resultMat) ;
var vx:Vector.<Vector3D> = new Vector.<Vector3D>;
var mt:Matrix3D = new Matrix3D ;
vx = m.decompose("quaternion");
var vr:Vector3D = new Vector3D ;
vr.x = vx[1].x ;
vr.y = vx[1].y ;
vr.z = -vx[1].z ;
vr.w = -vx[1].w ;
vx[1] = vr ;
mt.recompose(vx,"quaternion") ;
head.transform = mt ;
head.position = new Vector3D(this.resultMat.m03*10,this.resultMat.m13/2,this.resultMat.m23*10) ;
}
public static function convertNyARMatrixToFlashMatrix3D (mat:NyARDoubleMatrix34, bMirror:Boolean=true) :Matrix3D {
return new Matrix3D (Vector.<Number>([
-mat.m00, mat.m10, mat.m20, 0,
mat.m02, -mat.m12, -mat.m22, 0,
mat.m01, -mat.m11, -mat.m21, 0,
-mat.m03, mat.m13, mat.m23, 1
]))
}
public function onMarkerRemoved(e:Event=null):void
{
material.alpha = 0 ;
}
private var material : ColorMaterial
private function ini3D():void {
trace("INI3D") ;
view = new View3D();
//this.addChild(_view);
this.addChild(new AwayStats(view));
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;
material = new ColorMaterial(0xff0000);
material.lights = [light];
//bmpMaterial = new BitmapMaterial() ;
//mesh = new Cube(material, 100,200,100);
// view.scene.addChild(mesh) ;
//var plane:Plane = new Plane(bmpMaterial,1024,512) ;
//bmpMaterial.alpha = 1 ;
//plane.rotationX = -90 ;
//view.scene.addChild(plane) ;
initMesh() ;
addChild(view);
}
private var _loader:Loader3D ;
private function initMesh() : void
{
Loader3D.enableParser(OBJParser);
_loader = new Loader3D();
_loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
_loader.parse(OBJData, null, new AssetLoaderContext(false));
_loader.y = -50;
view.scene.addChild(_loader);
_material = new BitmapMaterial(new Albedo().bitmapData);
_subsurfaceMethod = new SubsurfaceScatteringDiffuseMethod(2048, 2);
_diffuseMethod = new BasicDiffuseMethod();
_fresnelMethod = new FresnelSpecularMethod(true);
_specularMethod = new BasicSpecularMethod();
_material.normalMap = new Normal().bitmapData;
_material.specularMap = new Specular().bitmapData;
_material.lights = [ light ];
_material.gloss = 10;
_material.specular = 3;
_material.ambientColor = 0x303040;
_material.ambient = 1;
_subsurfaceMethod.scatterColor = 0xff7733; //0xff9966;
_subsurfaceMethod.scattering = .05;
_subsurfaceMethod.translucency = 4;
_material.diffuseMethod = _subsurfaceMethod;
_material.specularMethod = _fresnelMethod;
}
private var head:Mesh ;
private function onResourceComplete(event : LoaderEvent) : void
{
for (var i : int = 0; i < _loader.numChildren; ++i) {
head = Mesh(_loader.getChildAt(i));
head.geometry.scale(200);
head.material = _material
}
iniFlare() ;
}
private function getCam():void {
cam = Camera.getCamera();
cam.setMode( 512, 256,25, true );
}
private function keyUpHandler(event:KeyboardEvent):void
{
var i:int ;
switch(event.keyCode)
{
case Keyboard.X:
(xx==10)? xx=0:null;
x1=-360+(xx*90) ;
xx++
break;
case Keyboard.Y:
(yy==10)? yy=0:null;
y1=-360+(yy*90) ;
yy++
break;
case Keyboard.Z:
(zz==10)? zz=0:null;
z1=-360+(zz*90) ;
zz++
break;
}
trace("x1:"+x1) ;
trace("y1:"+y1) ;
trace("z1:"+z1) ;
}
}
}
import flash.events.Event;
/**
* ?????????????
*/
class MarkerEvent extends Event
{
/**
* Marker??????
*/
public static const MARKER_ADDED:String = "markerAdded";
/**
* Marker???
*/
public static const MARKER_UPDATED:String = "markerUpdated";
/**
* Marker??????????
*/
public static const MARKER_REMOVED:String = "markerRemoved";
public function MarkerEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}