2010年07月27日

modoからFLASHへ書き出してみた その16 modo 401 SP4 ActionScript 3.0

前回作ったモーファーだけどPapervision3Dの中をあちこち見ていたら、org.papervision3d.core.controller.MorphControllerというのを見つけた。ウーム、これ使った方がいいのかな?

さて、PaperVision3Dの提供するDisplayObjectContainer3Dクラスを継承しているクラスはペアレント設定が出来る。modoから書き出したクラスはTriangleMesh3Dを継承していて、その親の親のそのまた親のクラスがDisplayObjectContainer3Dだから当然これもペアレントできる。

この機能を使うのはとても簡単で、ペアレントしたい親のオブジェクトのaddChild( )メソッドに子のオブジェクトを渡してやればいいだけだ。

でもその前に、PaperVision3Dのデフォルトの座標系とmodoの座標系は左手系・右手系の違いがあって、座標値をそのまま持ってくると裏返っちゃうので、前回まで使っていたExportPapervision3D.pyはX軸方向を反転して書き出していた。

fig06


でもちょっとやっぱり不自然なので今回からはZ軸を反転する事にしたよ。Plane.asなどのソースコードを読むと、org.Papervision3D.useRIGHTHANDEDってプロパティがあって、これをtrueにすると右手系になったりするみたいだけど、なるべくならデフォルトの状態で使いたいよね。でもそのせいでZ軸座標値とX・Y軸回転角度を符号反転して使わなくちゃならない。そこはまあいろんなCGソフトを使えばよくある事ではあるけどね。

例えば次の3つのアイテムを作って(黄色い点が中心点)、

Base

fig03

Body

fig04

Arm

fig05

fig02
これらのペアレント関係を左のようにして、
各アイテムをこんな感じに配置するとクレーン風のオブジェが出来る。

fig01

これをFlash上で再現するために、各アイテムをExportPapervision3D.pyでBase.as、Body.as、Arm.asで書き出し、Main.asと同じフォルダに入れておく。

次に各アイテムを収めるための変数をTriangleMesh3D型で用意して

  var base:TriangleMesh3D;
  var body:TriangleMesh3D;
  var arm:TriangleMesh3D;

それぞれの変数にアイテムパーツのインスタンスを生成して割り当て、

  base=new Base();
  body=new Body();
  arm=new Arm();

armはbodyにペアレントし、bodyはbaseにペアレントし、baseはsceneにペアレントして、

  body.addChild(arm);
  base.addChild(body);
  scene.addChild(base);

各アイテムの位置はmodoの各アイテムのトランスフォームプロパティをもとにarmの基点はbodyの基点に対してbodyのローカル座標で(0.095,0.564,0.0)の位置に、bodyはbaseのローカル座標で(0,0.182,0)の位置に設定する(Z座標値は全部ゼロだから符号反転を気にする必要が無いなw)。

  arm.x=0.095;
  arm.y=0.564;
  body.y=0.182;

このようにして組み立ててみたのが下のFLASHムービーだ。フレームイベントでbodyとarmの角度を変えてみている。

Adobe Flash Player を取得

これがMain.asのソース。今回はポイントライトを1灯つけてフラットシェードマテリアルを付けてみた。動きにあわせて陰影が変化しているのがその効果だ。

package  {
 import org.papervision3d.view.BasicView;
 import org.papervision3d.objects.primitives.Sphere;
 import flash.events.Event;
 import org.papervision3d.objects.primitives.Plane;
 import org.papervision3d.core.geom.renderables.Vertex3D;
 import flash.display.DisplayObject;
 import org.papervision3d.objects.DisplayObject3D;
 import org.papervision3d.core.geom.TriangleMesh3D;
 import org.papervision3d.materials.ColorMaterial;
 import org.papervision3d.lights.PointLight3D;
 import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
 import org.papervision3d.materials.shadematerials.PhongMaterial;
 
 public class Main extends BasicView{
  var base:TriangleMesh3D;
  var body:TriangleMesh3D;
  var arm:TriangleMesh3D;
  private var offset:Number=0.0;
  public function Main() {
   var light:PointLight3D=new PointLight3D(true,false);
   var material:FlatShadeMaterial=new FlatShadeMaterial(light,0xffffff,0x111111,50);
   base=new Base(material);
   body=new Body(material);
   arm=new Arm(material);
   body.addChild(arm);
   base.addChild(body);
   scene.addChild(base);
   arm.x=0.095;
   arm.y=0.564;
   body.y=0.182;
   light.x=2;
   light.z=-2;
   light.y=2;
   scene.addChild(light);
   var ct:DisplayObject3D=new DisplayObject3D();
   camera.x=1.2;
   camera.y=1.5;
   camera.z=-7;
   ct.y=1.6;
   camera.target=ct;
   startRendering();
   addEventListener(Event.ENTER_FRAME,loop);
  }
  
  private function loop(e:Event){
   var v:Number=Math.sin(offset);
   var v2:Number=Math.sin(offset/5);
   body.rotationY=v2*180;
   arm.rotationZ=v*30+30;
   offset+=0.1;
  }
 }
}

もし他のオブジェクトのペアレントを解除して、オブジェクトを除去したければ、removeChild( )を使えばいいみたいだ。

public function removeChild(child:DisplayObject3D):DisplayObject3D

例えば

body.removeChild(arm);

としてやれば、アームが消える。詳しくはDisplayObjectContainer3Dのリファレンスを見てね。

また、ペアレントされているオブジェクトを他のオブジェクトにペアレントしてみたら、最後にペアレントした方にオブジェクトのペアレントが移った。

それではまた次回。

modoカテゴリー別ページ



take_z_ultima at 12:00│Comments(0)TrackBack(0)modo | FLASH

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives