FLARToolKitとPapervision3Dをもうちょっとだけがんばってみる

前の記事から一ヶ月以上経ってしまいました…。

AS3.0が少しだけわかってきたので、FLARToolKitとPapervision3Dをもうちょっとだけがんばってみる。

今までこのブログに載せていたFLARToolKitは、すべてFLARToolKitに備え付けのサンプル、SimpleCube.asをもとにしていて、認識したマーカーと常に同じ座標に3Dオブジェクトが表示されているというものでした。これをもう少しだけ変更して、3Dオブジェクトを常にマーカーと同期させるのではなく、マーカーの座標を利用しながら3Dオブジェクトの動きを変化させることができるようにしたいと思います。

言葉だけではわかりにくいですが、以下のようなことがしたいわけです。
 

 
今回もFLARToolKitのサンプル、SimpleCube.asをもとに変更していきます。
(SimpleCube.asの動かし方はSaqoosha.net :: FLARToolKit スタートガイドから)
 
SimpleCube.asの44行目

this._baseNode.addChild(this._cube);

を見ると、cubeが_baseNodeにaddChildされていることがわかります。
_baseNodeとは何かとPV3DARApp.asを見ると、57行目で_sceneにaddChildされており、その一行上で_sceneというのはただのScene3Dということがわかるので、この_baseNodeがマーカーを認識して座標を変更しているものなのだな、と推測することができます。
 

そこでSimpleCube.asの44行目を_sceneにaddChildするように変更します。
ここでパブリッシュしても何も表示されません。
ENTER_FRAMEリスナーを作って、_cubeのx、y、z位置を_baseNodeと同じにするように書いてみます。

ACTIONSCRIPT:
  1. //44行目を以下に変更
  2. this._scene.addChild(this._cube);
  3.  
  4. //ENTER_FRAMEリスナーを作る
  5. this.stage.addEventListener(Event.ENTER_FRAME, onEnterframe);
  6.  
  7. private function onEnterframe(e:Event):void {
  8.     this._cube.x = this._baseNode.x;
  9.     this._cube.y = this._baseNode.y;
  10.     this._cube.z = this._baseNode.z;
  11. }

 

 
デモFlashはこちら
 
マーカーと同じ位置に_cubeが表示されています。
角度も同じにしたいので以下のように記述を変更してみます。

ACTIONSCRIPT:
  1. private function onEnterframe(e:Event):void {
  2.     this._cube.x = this._baseNode.x;
  3.     this._cube.y = this._baseNode.y;
  4.     this._cube.z = this._baseNode.z;
  5.     this._cube.rotationX = this._baseNode.rotationX;
  6.     this._cube.rotationY = this._baseNode.rotationY;
  7.     this._cube.rotationZ = this._baseNode.rotationZ;
  8. }

ところがこれでパブリッシュしても角度は変わりません。_baseNodeの各rotation
の値をtraceしてみるとすべて0のままです。なぜなんでしょう。わかりません。
 
もう少し調べてみると、Papervisionはオブジェクトの座標をMatrix3Dというので管理していることがわかります。

オブジェクトのtransformというプロパティがMatrix3Dのようなので、試しに以下のように記述を変更してパブリッシュしてみます。

ACTIONSCRIPT:
  1. private function onEnterframe(e:Event):void {
  2.     this._cube.transform = this._baseNode.transform;
  3. }

 

 
デモFlashはこちら
 
一応思い通りに動くようになりました。
ただこれではFLARToolKitのサンプルとほとんど同じなので、イージングをつけてみることにします。

Matrix3Dはなんかこんなのに↓それぞれ座標の値が入っていて

n11,n12,n13,n14,
n21,n22,n23,n24,
n31,n32,n33,n34,
n41,n42,n43,n44,
 
ちゃんと理解するのは難しいですが、
・n14=x座標、n24=y座標、n34=z座標
・角度に関係してそうなのは、n11~n13、n21~n23、n31~n33。

のようです。
 
とりあえず目標値から現在値を引いて、適当な数値で割ってみるという古典的な方法でイージングをつけてみました。

ACTIONSCRIPT:
  1. private function onEnterframe(e:Event):void {
  2.  var speed:uint = 4;
  3.            
  4.  this._cube.transform.n11 = this._cube.transform.n11+(_baseNode.transform.n11-this._cube.transform.n11)/speed;
  5.  this._cube.transform.n12 = this._cube.transform.n12+(_baseNode.transform.n12-this._cube.transform.n12)/speed;
  6.  this._cube.transform.n13 = this._cube.transform.n13+(_baseNode.transform.n13-this._cube.transform.n13)/speed;
  7.  this._cube.transform.n14 = this._cube.transform.n14+(_baseNode.transform.n14-this._cube.transform.n14)/speed;
  8.            
  9.  this._cube.transform.n21 = this._cube.transform.n21+(_baseNode.transform.n21-this._cube.transform.n21)/speed;
  10.  this._cube.transform.n22 = this._cube.transform.n22+(_baseNode.transform.n22-this._cube.transform.n22)/speed;
  11.  this._cube.transform.n23 = this._cube.transform.n23+(_baseNode.transform.n23-this._cube.transform.n23)/speed;
  12.  this._cube.transform.n24 = this._cube.transform.n24+(_baseNode.transform.n24-this._cube.transform.n24)/speed;
  13.            
  14.  this._cube.transform.n31 = this._cube.transform.n31+(_baseNode.transform.n31-this._cube.transform.n31)/speed;
  15.  this._cube.transform.n32 = this._cube.transform.n32+(_baseNode.transform.n32-this._cube.transform.n32)/speed;
  16.  this._cube.transform.n33 = this._cube.transform.n33+(_baseNode.transform.n33-this._cube.transform.n33)/speed;
  17.  this._cube.transform.n34 = this._cube.transform.n34+(_baseNode.transform.n34-this._cube.transform.n34)/speed;
  18. }

 

 
デモFlashはこちら
 
 
最終ソースコード

ACTIONSCRIPT:
  1. package net.saqoosha.flartoolkit.example {
  2.    
  3.     import flash.events.Event;
  4.     import flash.events.MouseEvent;
  5.    
  6.     import org.papervision3d.lights.PointLight3D;
  7.     import org.papervision3d.materials.WireframeMaterial;
  8.     import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  9.     import org.papervision3d.materials.utils.MaterialsList;
  10.     import org.papervision3d.objects.primitives.Cube;
  11.     import org.papervision3d.objects.primitives.Plane;
  12.    
  13.  
  14.     [SWF(width=640,height=480,frameRate=10,backgroundColor=0x0)]
  15.  
  16.     public class SimpleCube2 extends PV3DARApp {
  17.        
  18.         private static const PATTERN_FILE:String = "Data/patt.hiro";
  19.         private static const CAMERA_FILE:String = "Data/camera_para.dat";
  20.        
  21.         private var _plane:Plane;
  22.         private var _cube:Cube;
  23.        
  24.         public function SimpleCube2() {
  25.             this.addEventListener(Event.INIT, this._onInit);
  26.             this.init(CAMERA_FILE, PATTERN_FILE);
  27.         }
  28.        
  29.         private function _onInit(e:Event):void {
  30.             this.removeEventListener(Event.INIT, this._onInit);
  31.            
  32.             var wmat:WireframeMaterial = new WireframeMaterial(0xff0000, 1, 2);
  33.             wmat.doubleSided = true;
  34.             this._plane = new Plane(wmat, 80, 80);
  35.             this._baseNode.addChild(this._plane);
  36.            
  37.             var light:PointLight3D = new PointLight3D();
  38.             light.x = 1000;
  39.             light.y = 1000;
  40.             light.z = -1000;
  41.             var fmat:FlatShadeMaterial = new FlatShadeMaterial(light, 0xff22aa, 0x0);
  42.             this._cube = new Cube(new MaterialsList({all: fmat}), 40, 40, 40);
  43.             //this._cube.z = 320;
  44.             this._scene.addChild(this._cube);
  45.            
  46.             this.stage.addEventListener(MouseEvent.CLICK, this._onClick);
  47.             this.stage.addEventListener(Event.ENTER_FRAME, onEnterframe);
  48.         }
  49.        
  50.         private function onEnterframe(e:Event):void {
  51.             var speed:uint = 4;
  52.            
  53.             this._cube.transform.n11 = this._cube.transform.n11+(_baseNode.transform.n11-this._cube.transform.n11)/speed;
  54.             this._cube.transform.n12 = this._cube.transform.n12+(_baseNode.transform.n12-this._cube.transform.n12)/speed;
  55.             this._cube.transform.n13 = this._cube.transform.n13+(_baseNode.transform.n13-this._cube.transform.n13)/speed;
  56.             this._cube.transform.n14 = this._cube.transform.n14+(_baseNode.transform.n14-this._cube.transform.n14)/speed;
  57.            
  58.             this._cube.transform.n21 = this._cube.transform.n21+(_baseNode.transform.n21-this._cube.transform.n21)/speed;
  59.             this._cube.transform.n22 = this._cube.transform.n22+(_baseNode.transform.n22-this._cube.transform.n22)/speed;
  60.             this._cube.transform.n23 = this._cube.transform.n23+(_baseNode.transform.n23-this._cube.transform.n23)/speed;
  61.             this._cube.transform.n24 = this._cube.transform.n24+(_baseNode.transform.n24-this._cube.transform.n24)/speed;
  62.            
  63.             this._cube.transform.n31 = this._cube.transform.n31+(_baseNode.transform.n31-this._cube.transform.n31)/speed;
  64.             this._cube.transform.n32 = this._cube.transform.n32+(_baseNode.transform.n32-this._cube.transform.n32)/speed;
  65.             this._cube.transform.n33 = this._cube.transform.n33+(_baseNode.transform.n33-this._cube.transform.n33)/speed;
  66.             this._cube.transform.n34 = this._cube.transform.n34+(_baseNode.transform.n34-this._cube.transform.n34)/speed;
  67.         }
  68.        
  69.         private function _onClick(e:MouseEvent):void {
  70.             this.mirror = !this.mirror;
  71.         }
  72.        
  73.     }
  74. }

COMMENTS [4]

  1. サッカン :

    えー僕もちょっとAR触ってみます★

    5 月 20th, 2009 at 8:39:04
  2. chabudai :

    楽しみです!!
    そして私にMatrix3Dを教えてください。

    5 月 21st, 2009 at 22:22:09
  3. » » 大阪てら子 22 「webカメラで遊ぼう!」 trace :

    [...] (ご本人様による解説) その物体とは、BigDog! [...]

    5 月 27th, 2009 at 0:48:04
  4. 番茄网络创业者 :

    这是在介绍3D制作吗?

    10 月 7th, 2010 at 23:06:44

トラックバック URL :