Papervision3D で手軽に星空を作るための Stars オブジェクトを試してみた。

マウス押下でズームイン可能。

赤い大量の点が Stars オブジェクト。
それにしても、非常に処理が重い。

Stars のソースコード(Stars.as)を見ると、public override function render( scene :SceneObject3D ):void とレンダリング処理をオーバーライドしている。他のプリミティブオブジェクトではこんな処理は無いっぽいので、ちょっと扱いが違う感じ。

ソースコード(StarsSample.as)


package {
 
  import flash.display.*;
  import flash.events.*;
 
  import org.papervision3d.core.proto.*;
  import org.papervision3d.scenes.*;
  import org.papervision3d.objects.*;
  import org.papervision3d.cameras.*;
  import org.papervision3d.materials.*;
 
  [SWF(width="400", height="400", backgroundColor="#000000", frameRate="30")]
 
  public class StarsSample extends Sprite {
 
    private var container : Sprite;
    private var scene     : MovieScene3D;
    private var camera    : Camera3D;
    private var rootNode  : DisplayObject3D;
 
    private var obj:Array = new Array();
 
    // マウスの状態
    private var mousedown:Boolean = false;
 
    // 3Dオブジェクト踊らせ用パラメータ
    private var valx    : Number = 0;
    private var valy    : Number = 0;
 
    public function StarsSample():void {
 
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
      stage.addEventListener(Event.RESIZE, onStageResize);
      stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
      stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
 
      // 表示用の Sprite オブジェクトを生成
      container = new Sprite();
      container.x = 400 / 2; // at center : swf width  = 400
      container.y = 400 / 2; // at center : swf height = 400
      addChild(container);
 
      // シーンオブジェクトを作る
      scene = new MovieScene3D(container);
 
      // カメラオブジェクトを作る
      camera = new Camera3D();
      camera.z = -300;
      camera.focus = 500;
      camera.zoom = 1;
 
      // ルートノードを作る
      rootNode = new DisplayObject3D();
      scene.addChild(rootNode);
 
      // いろんな3Dオブジェクトを作ってみて、配列に入れておく
      obj.push(createStars(container));
      obj.push(createCube());
 
      // 3Dオブジェクトをルートノードに追加
      for(var i:int; i<obj.length; i++){
        //rootNode.addChild(obj[i]);
        scene.addChild(obj[i]); // 直接 MovieScene3D に add する必要あり
      }
    }
 
    private static function createStars(target:Sprite):DisplayObject3D {
 
      var material:ColorMaterial = new ColorMaterial(0xFF0000);
      var quantity:Number = 500;
      var width:Number    = 400;
      var height:Number   = 200;
      var depth:Number    = 200;
 
      var obj:Stars = new Stars(material, target, quantity, width, height, depth);
      obj.x = 0;
      obj.y = 0;
      obj.z = 0;
      return obj;
    }
 
    private static function createCube():DisplayObject3D {
 
      var material:WireframeMaterial = new WireframeMaterial(0x00FF00);
      material.lineAlpha = 1;
      material.oneSide = true;
 
      var width:Number  = 200;
      var depth:Number  = 200;
      var height:Number = 400;
      var segmentsS:Number = 10;
      var segmentsT:Number = 10;
      var segmentsH:Number = 10;
 
      var obj:Cube = new Cube(material, width, depth, height, segmentsS, segmentsT, segmentsH);
      obj.x = 0;
      obj.y = 0;
      obj.z = 0;
      return obj;
    }
 
    private function onMouseDown(event:MouseEvent):void {
      mousedown = true;
    }
 
    private function onMouseUp(event:MouseEvent):void {
      mousedown = false;
    }
 
    private function onEnterFrame(event:Event):void {
 
      if(mousedown){
        // マウス押下中はズームイン
        camera.zoom += 0.01;
      }else{
        // ズームアウト
        if(camera.zoom > 1){
          camera.zoom -= 0.05;
        }
      }
 
      valx += container.mouseX / 100;
      valy += container.mouseY / 100;
 
      for(var i:int; i<obj.length; i++){
        obj[i].rotationY = valx;
        obj[i].rotationX = valy;
      }
 
      scene.renderCamera(camera);
    }
 
    private function onStageResize(event:Event):void {
      container.x = stage.stageWidth  / 2;
      container.y = stage.stageHeight / 2;
    }
 
  }
}

トラブルその1

Papervision3D 1.5 の Stars.as がコンパイルできない。


C:\flex\libs\org\papervision3d\objects\Stars.as(223): col: 10 エラー:
 未定義のプロパティ v へのアクセスです。
 
                                        if( v.visible )
                                            ^

もしかして、Flex SDK のバージョンに問題が? (いま使っているバージョンは 2.0.1)
よくわからなかったので、今回は Papervision3D を古いリビジョンのものに戻してコンパイルした。

トラブルその2

Stars オブジェクトは表示されるのに、一緒に表示させようとした Cube オブジェクトがなぜか表示されない。これは Scene3D を MovieScene3D へ変更したら解決した。

追記: 2007-09-11

Papervision3D 1.5 でコンパイルできなかったのは、もしかしたら型チェックの問題かもとか思った。
Flex には型チェックなしでコンパイルするオプションがあるらしいので、それで解決できるかも。

あるいは、trick7.com blog: Papervision3D 1.5 をダウンロードしたら 1.1 だった件 とかで何らかの不整合でもあったのかもしれない。

# って、思っただけ。

tags: zlashdot Flash Flash Flex Papervision3D

Posted by NI-Lab. (@nilab)