// forked from rokubou's FLARToolKit_Sample_Simple_PV3D /** *------------------------------------------------- * * @itoz (http://www.romatica.com) * * ▼マーカーを最後に認識した位置にイージングで移動させる[ガクガク感の軽減] * * [1] モデルをFLARBaseNodeにaddChildしない * ・モデルはsceneにaddChildして、FLARBaseNodeの位置にイージングで動かす) * [2] Matrix3D.matrix2euler()でマーカー角度変換取得 * [3] マーカー非認識時、3Dモデルを消さない、もしくはすぐに消さない。 * ・非認識になっても、最後に認識した位置までモデルを移動させるため) * ・認識・非認識による点滅の違和感を軽減するため) * * [model data]モデルは前に作ったこれ * http://www.romatica.com/blog/archives/2010/01/blendrpapervision.html * ※こういうモデルじゃなくて、動物(蝶とか鳥とか?)でアニメーションパターンをちゃんと付けてやると雰囲気出て、 * 演出的にいいと思う。 * * [marker pdf] マーカーをプリントしてください * www.romatica.com/dev/resource/flarlogo-marker.pdf * * ┏━━━━━┓ * ┃┏━━━┓┃ * ┃┃ F L ┃┃ * ┃┃ A R ┃┃ これですよー * ┃┗━━━┛┃ * ┗━━━━━┛ * * *------------------------------------------------- */ /** * FLARToolKit Sample - Simple cube PV3D * -------------------------------------------------------------------------------- * Copyright (C)2010 rokubou * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * For further information please contact. * http://www.libspark.org/wiki/saqoosha/FLARToolKit * * Contributors * rokubou */ package { import org.libspark.flartoolkit.core.FLARCode; 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; import org.papervision3d.core.math.Matrix3D; import org.papervision3d.core.math.Number3D; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.parsers.DAE; import org.papervision3d.render.LazyRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.media.Camera; import flash.media.Video; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; [SWF(width=640, height=480, backgroundColor=0x808080, frameRate=30)] //test public class FLARToolKit_Sample_SimpleCube_PV3D extends Sprite { /** * 画面の幅と高さ */ protected var canvasWidth : int; protected var canvasHeight : int; /** * 画面の幅と高さ */ protected var captureWidth : int; protected var captureHeight : int; /** * マーカーの一辺の長さ(px) */ protected var codeWidth : int; /** * カメラパラメータのファイル名 * 内部的に初期化される処理が含まれるので読み込む必要は無い。 * 例外的に 16:9 で使う場合は、それようのパラメータファイルを読み込むこと。 */ protected var cameraParamFile : String; /** * マーカーパターンのファイル名 */ protected var markerPatternFile : String; /** * パラメータファイル、マーカーパターンファイルの読込み用 * @see flash.net.URLLoader */ private var urlLoader : URLLoader; /** * カメラパラメータデータ * アスペクト比や歪みなどの補正のための情報が含まれる * @see org.libspark.flartoolkit.core.param.FLARParam */ protected var cameraParam : FLARParam; /** * マーカーパターン * マーカーを複数パターン使う場合はVectorなどで管理する * @see org.libspark.flartoolkit.core.FLARCode */ protected var markerPatternCode : FLARCode; /** * @see flash.media.Camera */ protected var webCamera : Camera; /** * flash.media.Video */ protected var video : Video; /** * Webカメラからの入力をBitmapに確保する * @see flash.display.Bitmap */ private var capture : Bitmap; /** * ラスタイメージ * @see org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData */ private var raster : FLARRgbRaster_BitmapData; /** * Marker detector * @see org.libspark.flartoolkit.detector.FLARSingleMarkerDetector */ private var detector : FLARSingleMarkerDetector; /** * 3Dモデル表示用 */ protected var scene : Scene3D; /** * 3Dモデル表示用 */ protected var viewport : Viewport3D; /** * 3Dモデル表示字の視点 */ protected var camera3D : FLARCamera3D; /** * Marker base node */ protected var markerNode : FLARBaseNode; /** * 3D Renderer */ protected var renderer : LazyRenderEngine; /** * 表示モデルを一括して押し込めるコンテナ */ protected var container : DisplayObject3D; //-------------------------------------------------------------- /** * DAEモデル */ private var _modelWRAP : DisplayObject3D; private var _dae : DAE; /** * 認識/非認識 表示 */ private var _lastRot : Number3D; //-------------------------------------------------------------- private var _recognizer : TextField= new TextField( ) /** * Constructor * ここから初期化処理を呼び出して処理をスタート */ public function FLARToolKit_Sample_SimpleCube_PV3D() { this.initialize( ); } /** * initialize * 各種サイズの初期化 */ protected function initialize() : void { // 各種サイズの初期化 captureWidth = 320; captureHeight = 240; canvasWidth = 640 canvasHeight = 480; codeWidth = 80; // markerPatternFile = 'http://assets.wonderfl.net/static/flar/flarlogo.pat'; // パラメータファイルの読込み // 今回は省略して初期値を用いる this.cameraParam = new FLARParam( ); this.cameraParam.changeScreenSize( captureWidth, captureHeight ); // マーカーパターンファイルの読込み this.urlLoader = new URLLoader( ); this.urlLoader.dataFormat = URLLoaderDataFormat.TEXT; this.urlLoader.addEventListener( Event.COMPLETE, this.onLoadCode ); this.urlLoader.addEventListener( IOErrorEvent.IO_ERROR, dispatchEvent ); this.urlLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, dispatchEvent ); this.urlLoader.load( new URLRequest( markerPatternFile ) ); } /** * マーカーパターンを読み込む * @param e Event */ protected function onLoadCode(e : Event) : void { // URL Loader関連のイベントを削除 this.urlLoader.removeEventListener( Event.COMPLETE, this.onLoadCode ); // 分割数(縦・横)、黒枠の幅(縦・横) this.markerPatternCode = new FLARCode( 16, 16, 50, 50 ); this.markerPatternCode.loadARPatt( this.urlLoader.data ); // loaderがgc対象になるようにnullを突っ込む this.urlLoader = null; // 初期化 dispatchEvent( new Event( Event.INIT ) ); this.onInit( ); } /** * Webカメラの設定と、ARToolKitの準備 */ protected function onInit() : void { // setup webcam this.webCamera = Camera.getCamera( ); if (!this.webCamera) { throw new Error( 'No webcamera!' ); } this.webCamera.setMode( this.captureWidth, this.captureHeight, 30 ); this.video = new Video( this.captureWidth, this.captureHeight ); this.video.attachCamera( this.webCamera ); // setup ARToolKit this.capture = new Bitmap( new BitmapData( this.captureWidth, this.captureHeight, false, 0 ), PixelSnapping.AUTO, true ); // ウェブカメラの解像度と表示サイズが異なる場合は拡大する this.capture.width = this.canvasWidth; this.capture.height = this.canvasHeight; this.addChild( this.capture ); this.raster = new FLARRgbRaster_BitmapData( this.capture.bitmapData ); // setup Single marker detector this.detector = new FLARSingleMarkerDetector( this.cameraParam, this.markerPatternCode, this.codeWidth ); this.detector.setContinueMode( true ); // 表示関係の設定(使用するライブラリによって変化します) this.viewport = this.addChild( new Viewport3D( this.captureWidth, this.captureHeight ) ) as Viewport3D; this.viewport.scaleX = this.canvasWidth / this.captureWidth; this.viewport.scaleY = this.canvasHeight / this.captureHeight; this.viewport.x = -4; // なぜかずれるので補正 // this.scene = new Scene3D( ); this.markerNode = this.scene.addChild( new FLARBaseNode( FLARBaseNode.AXIS_MODE_PV3D ) ) as FLARBaseNode; // 3Dモデル表示時の視点を設定 this.camera3D = new FLARCamera3D( this.cameraParam ); // setup renderer this.renderer = new LazyRenderEngine( this.scene, this.camera3D, this.viewport ); // モデル格納用のコンテナ作成 this.container = new DisplayObject3D( ); // モデルデータ this.setModelData( ); // モデルデータを登録 this.markerNode.addChild( this.container ); //認識非認識チェッカー _recognizer = new TextField( ); _recognizer.autoSize = TextFieldAutoSize.LEFT; _recognizer.background = true; _recognizer.backgroundColor = 0xcc0000; addChild( _recognizer ); // start this.start( ); //Wonderfl.capture_delay( 10 ); } /** * モデルデータを書く場所 */ protected function setModelData() : void { _modelWRAP = new DisplayObject3D( ); _dae = new DAE( ); _dae.load( "http://www.romatica.com/work/amazon-san/AmazonCollada.dae" ) _dae.scale = 13; _dae.rotationX = -90 _dae.rotationZ = 90 _modelWRAP.addChild( _dae ); scene.addChild( _modelWRAP ); } /** * マーカーの認識と3次元モデルの描写を開始する */ public function start() : void { // マーカー認識・非認識時用のイベントを登録 this.addEventListener( MarkerEvent.MARKER_ADDED, this.onMarkerAdded ); this.addEventListener( MarkerEvent.MARKER_UPDATED, this.onMarkerUpdated ); this.addEventListener( MarkerEvent.MARKER_REMOVED, this.onMarkerRemoved ); // 処理開始 this.addEventListener( Event.ENTER_FRAME, this.run ); } /** * 認識したマーカーの情報を格納 */ protected var resultMat : FLARTransMatResult= new FLARTransMatResult( ); public function onMarkerAdded(e : Event= null) : void { // trace("[add]"); _recognizer.text = "認識中" _recognizer.backgroundColor = 0xffffff; } public function onMarkerUpdated(e : Event= null) : void { } public function onMarkerRemoved(e : Event= null) : void { _recognizer.text = "非認識" _recognizer.backgroundColor = 0xcc0000; } /** * ここで処理振り分けを行っている */ public function run(e : Event) : void { this.capture.bitmapData.draw( this.video ); // Marker detect var detected : Boolean= false; try { detected = this.detector.detectMarkerLite( this.raster, 80 ) && this.detector.getConfidence( ) > 0.5; } catch (e : Error) { } // 認識時の処理 if (detected) { detector.getTransformMatrix( this.resultMat ); markerNode.setTransformMatrix( this.resultMat ); var transform : Matrix3D= markerNode.transform; _lastRot = Matrix3D.matrix2euler( transform ); this.dispatchEvent( new MarkerEvent( MarkerEvent.MARKER_ADDED ) ); // 非認識時 } else { this.dispatchEvent( new MarkerEvent( MarkerEvent.MARKER_REMOVED ) ); } //イージング移動 _modelWRAP.x += (markerNode.x - _modelWRAP.x) * 0.1; _modelWRAP.y += (markerNode.y - _modelWRAP.y) * 0.1; _modelWRAP.z += (markerNode.z - _modelWRAP.z) * 0.1; _modelWRAP.rotationX += (_lastRot.x - _modelWRAP.rotationX) * 0.1; _modelWRAP.rotationY += (_lastRot.y - _modelWRAP.rotationY) * 0.1; _modelWRAP.rotationZ += (_lastRot.z - _modelWRAP.rotationZ) * 0.1; this.renderer.render( ); } } } 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 ); } } FLARToolkitマーカー位置にイージング移動 (easing motion)