[FLARToolkit]革命的で魔法のようなデバイス。しかも拡張現実で。
/**
* -------------------------------------------------
* ▼ 革命的で魔法のようなデバイス。しかも拡張現実で。
* 5月28日発売 http://www.apple.com/jp/ipad/
*
* @auther itoz ( http://www.romatica.com/ )
*
* -------------------------------------
* マーカーの1辺が80mmでほぼ実寸。(だとおもう。)
* shadeで作ったColladaは面のZソートがなんかガビガビです。。。
*
* [marker pdf] マーカーをプリントしてください
* http://www.romatica.com/dev/resource/flarlogo-marker.pdf
* -------------------------------------------------
*/
/**
* Copyright romatica ( http://wonderfl.net/user/romatica )
* GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
* Downloaded from: http://wonderfl.net/c/8PVg
*/
// forked from romatica's FLARToolkitマーカー位置にイージング移動 (easing motion)
// forked from rokubou's FLARToolKit_Sample_Simple_PV3D
/**
* Copyright romatica ( http://wonderfl.net/user/romatica )
* GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
* Downloaded from: http://wonderfl.net/c/8PVg
*
* -------------------------------------------------
* ▼ 革命的で魔法のようなデバイス。しかも拡張現実で。
* 5月28日発売 http://www.apple.com/jp/ipad/
*
* @auther itoz ( http://www.romatica.com/ )
*
* -------------------------------------
* マーカーの1辺が80mmでほぼ実寸。(だとおもう。)
* shadeで作ったColladaは面のZソートがなんかガビガビです。。。
*
* [marker pdf] マーカーをプリントしてください
* http://www.romatica.com/dev/resource/flarlogo-marker.pdf
* -------------------------------------------------
*/
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;
[SWF(width=465, height=465, backgroundColor=0x808080, frameRate=30)]
public class FLARToolkit_iPad extends Sprite
{
protected var _cameraParamFile : String;
private var _canvasWidth : int;
private var _canvasHeight : int;
private var _captureWidth : int;
private var _captureHeight : int;
private var _codeWidth : int;
private var _markerPatternFile : String;
private var _urlLoader : URLLoader;
private var _cameraParam : FLARParam;
private var _markerPatternCode : FLARCode;
private var _webCamera : Camera;
private var _video : Video;
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;
private var _scene : Scene3D;
private var _viewport : Viewport3D;
private var _camera3D : FLARCamera3D;
private var _markerNode : FLARBaseNode;
private var _renderer : LazyRenderEngine;
private var _container : DisplayObject3D;
private var _modelWRAP : DisplayObject3D;
private var _dae : DAE;
private var _recognizer : TextField;//認識/非認識 表示
private var _lastRot : Number3D;
public function FLARToolkit_iPad()
{
this.initialize( );
}
protected function initialize() : void
{
//Wonderfl.capture_delay( 10 );
_captureWidth = 320;
_captureHeight = 240;
_canvasWidth = 640;
_canvasHeight = 480;
_codeWidth = 80;
_markerPatternFile = 'http://assets.wonderfl.net/static/flar/flarlogo.pat';
// パラメータファイルの読込み 今回は省略して初期値を用いる
_cameraParam = new FLARParam( );
_cameraParam.changeScreenSize( _captureWidth, _captureHeight );
// マーカーパターンファイルの読込み
_urlLoader = new URLLoader( );
_urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
_urlLoader.addEventListener( Event.COMPLETE, this.onLoadCode );
_urlLoader.addEventListener( IOErrorEvent.IO_ERROR, dispatchEvent );
_urlLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, dispatchEvent );
_urlLoader.load( new URLRequest( _markerPatternFile ) );
}
// ======================================================================
/**
* マーカーパターンを読み込む
*/
protected function onLoadCode(e : Event) : void
{
_urlLoader.removeEventListener( Event.COMPLETE, this.onLoadCode );
// 分割数(縦・横)、黒枠の幅(縦・横)
_markerPatternCode = new FLARCode( 16, 16, 50, 50 );
_markerPatternCode.loadARPatt( this._urlLoader.data );
_urlLoader = null;
// 初期化
dispatchEvent( new Event( Event.INIT ) );
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 );
// ウェブカメラの解像度と表示サイズが異なる場合は拡大する
_capture.width = this._canvasWidth;
_capture.height = this._canvasHeight;
addChild( this._capture );
_raster = new FLARRgbRaster_BitmapData( this._capture.bitmapData );
// setup Single marker detector
_detector = new FLARSingleMarkerDetector( this._cameraParam, this._markerPatternCode, this._codeWidth );
_detector.setContinueMode( true );
// 表示関係の設定(使用するライブラリによって変化します)
_viewport = this.addChild( new Viewport3D( this._captureWidth, this._captureHeight ) ) as Viewport3D;
_viewport.scaleX = this._canvasWidth / this._captureWidth;
_viewport.scaleY = this._canvasHeight / this._captureHeight;
_viewport.x = -4; // なぜかずれるので補正
_scene = new Scene3D( );
_markerNode = this._scene.addChild( new FLARBaseNode( FLARBaseNode.AXIS_MODE_PV3D ) ) as FLARBaseNode;
// 3Dモデル表示時の視点を設定
_camera3D = new FLARCamera3D( this._cameraParam );
// setup renderer
_renderer = new LazyRenderEngine( this._scene, this._camera3D, this._viewport );
// モデル格納用のコンテナ作成
_container = new DisplayObject3D( );
// モデルデータ
setModelData( );
// モデルデータを登録
_markerNode.addChild( this._container );
//認識非認識チェッカー
createRecognizer();
// start
start( );
}
// ======================================================================
/**
* 認識チェッカー作成
*/
private function createRecognizer():void
{
_recognizer =addChild( new TextField()) as TextField;
_recognizer.autoSize = TextFieldAutoSize.LEFT;
_recognizer.background = true;
_recognizer.backgroundColor = 0xcc0000;
_recognizer.x = _recognizer.y = 5;
}
// ======================================================================
/**
* モデルデータ
*/
protected function setModelData() : void
{
_modelWRAP = new DisplayObject3D( );
_dae = new DAE( );
_dae.load( "http://www.romatica.com/dev/wonderfl/iPad/ipad.dae" );
_dae.scale = 3;
_dae.rotationX = 0;
_dae.rotationY = 180;
_dae.rotationZ = 0;
_modelWRAP.addChild( _dae );
_markerNode.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
{
_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 );
dispatchEvent( new MarkerEvent( MarkerEvent.MARKER_ADDED ) );
// 非認識時
} else {
this.dispatchEvent( new MarkerEvent( MarkerEvent.MARKER_REMOVED ) );
}
_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 );
}
}