[Away3D] ステレオビュー (1) ~AnaglyphStereoRenderMethod~

Away3Dを使って、ステレオビューについて調べてみるよ。 :boy:

away3dStereo1a away3dStereo1b

StereoView3D と StereoCamera3D を使うんだよ。 :bouzu:
AnaglyphStereoRenderMethod を調べてみたよ。 :cake:

@rect 先生 :hakase: の「note.x | [Papervision3D]ねぎ振り完了」から、Colladaデータとテクスチャをダウンロードさせていただきました。 :doki:

:caution: 要 Flash Player 11.8 以上

StereoCamera3D のパラメータの値を変えてみてね。 :bouzu:

This movie requires Flash Player 11.8.0

Main.as
package {

  import flash.display.Sprite;
  import flash.system.System;
  import flash.events.Event;
  import flash.geom.Vector3D;

  import away3d.Away3D;
  import away3d.stereo.StereoView3D;
  import away3d.containers.Scene3D;
  import away3d.stereo.StereoCamera3D;
  import away3d.lights.DirectionalLight;
  import away3d.containers.ObjectContainer3D;
  import away3d.entities.Mesh;
  import away3d.primitives.PlaneGeometry;
  import away3d.materials.TextureMaterial;
  import away3d.materials.ColorMaterial;
  import away3d.materials.lightpickers.StaticLightPicker;
  import away3d.materials.methods.SoftShadowMapMethod;
  import away3d.loaders.Loader3D;
  import away3d.loaders.parsers.DAEParser;
  import away3d.events.LoaderEvent;
  import away3d.loaders.misc.AssetLoaderContext;
  import away3d.library.AssetLibrary;
  import away3d.library.assets.AssetType;
  import away3d.events.AssetEvent;
  import away3d.stereo.methods.AnaglyphStereoRenderMethod;

  import org.libspark.betweenas3.BetweenAS3;
  import org.libspark.betweenas3.tweens.ITween;
  import org.libspark.betweenas3.events.TweenEvent;
  import org.libspark.betweenas3.easing.*;


  [SWF(backgroundColor="#333333", width="600", height="600", frameRate="60")]

  public class Main extends Sprite {
    [Embed(source="assets/negimiku/negimiku.dae", mimeType="application/octet-stream")]
    private var ColladaData:Class;
    [Embed(source="assets/negimiku/negimiku.png")]
    private var ImageData:Class;
    // プロパティ
    private var view:StereoView3D;
    private var scene:Scene3D;
    private var camera:StereoCamera3D;
    private var light:DirectionalLight;
    private var negimiku:ObjectContainer3D;
    private var hand:ObjectContainer3D;
    private var arm:Mesh;
    private var negi:Mesh;
    private var plane:Mesh;
    private static var radius:uint = 500;
    private var angle:Number = - 90;
    private var degree:Number = 0;
    private static var depression:uint = 30;
    private static var radian:Number = Math.PI/180;
    private static var center:Vector3D = new Vector3D();

    // コンストラクタ
    public function Main() {
      System.pauseForGCIfCollectionImminent(1);
      init();
    }

    // メソッド
    private function init():void {
      view = new StereoView3D();
      scene = view.scene;

      camera = new StereoCamera3D();
      view.camera = camera;

      addChild(view);
      light = new DirectionalLight();
      scene.addChild(light);

      setup();
      initialize();
    }
    private function setup():void {
      view.backgroundColor = 0x333333;
      view.antiAlias = 4;
      view.stereoEnabled = true;
      view.stereoRenderMethod = new AnaglyphStereoRenderMethod();

      camera.x = 0;
      camera.y = 0;
      camera.z = - radius;
      camera.stereoFocus = 500;
      camera.stereoOffset = 100;

      light.direction = new Vector3D(0, -1, 1);
      light.ambient = 0.3;
      light.diffuse = 1;
      light.specular = 0;

    }
    private function initialize():void {
      var geometry:PlaneGeometry = new PlaneGeometry(300, 300, 1, 1, true, true);
      var material:ColorMaterial = new ColorMaterial(0x666666, 1);

      var lightPicker:StaticLightPicker = new StaticLightPicker([light]);
      material.lightPicker = lightPicker;

      material.ambientColor = 0xFFFFFF;
      var method:SoftShadowMapMethod = new SoftShadowMapMethod(light);
      method.alpha = 0.5;
      material.shadowMethod = method;

      plane = new Mesh(geometry, material);
      plane.y = - 184;
      scene.addChild(plane);

      //Parsers.enableAllBundled();
      var context:AssetLoaderContext = new AssetLoaderContext();
      context.mapUrlToData("negimiku.png", new ImageData());

      AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, loaded, false, 0, true);
      var loader:Loader3D = new Loader3D();
      loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, complete, false, 0, true);
      loader.loadData(new ColladaData(), context, null, new DAEParser());

    }
    private function loaded(evt:AssetEvent):void {
      if (evt.asset.assetType == AssetType.CONTAINER) {
        negimiku = ObjectContainer3D(evt.asset);
        negimiku.rotationX = 90;
        negimiku.scale(12.6);

      }
      if (evt.asset.assetType == AssetType.MATERIAL) {
        var material:TextureMaterial = TextureMaterial(evt.asset);
        var lightPicker:StaticLightPicker = new StaticLightPicker([light]);
        material.lightPicker = lightPicker;

        material.ambientColor = 0xFFFFFF;
        //material.alpha = 0.99;
        material.alpha = 1;
        //material.alphaThreshold = 0.5;
        material.alphaThreshold = 0.9;
      }
      if (evt.asset.assetType == AssetType.MESH) {
        switch (evt.asset.name) {
          case "R_arm" :
            arm = Mesh(evt.asset);
            break;
          case "negi" :
            negi = Mesh(evt.asset);
            break;
        }
      }
    }
    private function complete(evt:LoaderEvent):void {
      AssetLibrary.removeEventListener(AssetEvent.ASSET_COMPLETE, loaded);
      evt.target.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, complete);
      scene.addChild(negimiku);
      hand = new ObjectContainer3D();
      negimiku.addChild(hand);
      hand.addChild(arm);
      hand.addChild(negi);

      addEventListener(Event.ENTER_FRAME, render, false, 0, true);
      jump();
      swingHand();
    }
    private function jump():void {
      var itween:ITween = BetweenAS3.serial(
        BetweenAS3.tween(negimiku, {y: 50}, {y: -50}, 0.5, Cubic.easeOut),
        BetweenAS3.tween(negimiku, {y: -50}, {y: 50}, 0.5, Cubic.easeIn)
      );
      itween.addEventListener(TweenEvent.COMPLETE, jumped, false, 0, true);
      itween.play();

    }
    private function jumped(evt:TweenEvent):void {
      evt.target.removeEventListener(TweenEvent.COMPLETE, jumped);
      jump();
    }
    private function swingHand():void {
      var itween:ITween = BetweenAS3.serial(
        BetweenAS3.tween(hand, {rotationX: -40}, {rotationX: 0}, 0.15, Quad.easeOut),
        BetweenAS3.tween(hand, {rotationX: 0}, {rotationX: -40}, 0.15, Quad.easeIn),
        BetweenAS3.tween(hand, {rotationX: 20}, {rotationX: 0}, 0.1, Quad.easeOut),
        BetweenAS3.tween(hand, {rotationX: 0}, {rotationX: 20}, 0.1, Quad.easeIn)
      );
      itween.addEventListener(TweenEvent.COMPLETE, swingedHand, false, 0, true);
      itween.play();

    }
    private function swingedHand(evt:TweenEvent):void {
      evt.target.removeEventListener(TweenEvent.COMPLETE, swingedHand);
      swingHand();
    }
    private function render(evt:Event):void {
      angle += 0.5;
      degree += 1;
      var dip:Number = depression*Math.sin(degree*radian);
      camera.x = radius*Math.cos(angle*radian)*Math.cos(dip*radian);
      camera.y = radius*Math.sin(dip*radian);
      camera.z = radius*Math.sin(angle*radian)*Math.cos(dip*radian);
      camera.lookAt(center);
      view.render();
    }

  }

}

Flash CC + Flex 4 SDK でパブリッシュ。