[AIR3.0] IN2ARを体験するのだ! (3)

そうだ! IN2ARを体験してみよう! :bouzu:

IN2AR

IN2AR SDK を使ってみるよ。 :boy:  複数マーカーを試してみたよ。 :girl:

:caution: 要 Flash Player 11.8 以上

This movie requires Flash Player 11.8.0

Main.as
package {

  import flash.display.Sprite;
  import flash.display.StageScaleMode;
  import flash.display.StageAlign;
  import flash.system.System;
  import flash.events.Event;
  import flash.geom.Vector3D;
  import flash.media.Camera;
  import flash.media.Video;
  import flash.display.BitmapData;
  import flash.geom.Matrix;
  import flash.utils.ByteArray;

  import com.in2ar.ane.IN2ARNative;
  import com.in2ar.IIN2AR;
  import com.in2ar.calibration.IntrinsicParameters;
  import com.in2ar.event.IN2ARDetectionEvent;
  import com.in2ar.detect.IN2ARReference;

  import in2ar.controls.CaptureController;
  import in2ar.away3d.textures.CaptureTexture;
  import in2ar.away3d.containers.IN2ARContainer3D;
  import in2ar.away3d.cameras.lenses.IN2ARCameraLens;

  import away3d.Away3D;
  import away3d.containers.View3D;
  import away3d.containers.Scene3D;
  import away3d.cameras.Camera3D;
  import away3d.lights.DirectionalLight;
  import away3d.containers.ObjectContainer3D;
  import away3d.entities.Mesh;
  import away3d.materials.TextureMaterial;
  import away3d.materials.lightpickers.StaticLightPicker;
  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 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="640", height="480", frameRate="30")]

  public class Main extends Sprite {
    [Embed(source="assets/def_data1.ass", mimeType="application/octet-stream")]
    private var DefinitionData1:Class;
    [Embed(source="assets/negimiku/negimiku.dae", mimeType="application/octet-stream")]
    private var ColladaData1:Class;
    [Embed(source="assets/negimiku/negimiku.png")]
    private var ImageData1:Class;
    [Embed(source="assets/def_data2.ass", mimeType="application/octet-stream")]
    private var DefinitionData2:Class;
    [Embed(source="assets/slime/slime.dae", mimeType="application/octet-stream")]
    private var ColladaData2:Class;
    [Embed(source="assets/slime/slime.png")]
    private var ImageData2:Class;
    // プロパティ
    private var view:View3D;
    private var scene:Scene3D;
    private var camera:Camera3D;
    private var light:DirectionalLight;
    private var negimiku:ObjectContainer3D;
    private var hand:ObjectContainer3D;
    private var arm:Mesh;
    private var negi:Mesh;
    private var slime:ObjectContainer3D;
    private static var radius:uint = 400;
    private static var center:Vector3D = new Vector3D();
    private var bw:uint = 640;
    private var bh:uint = 480;
    private var lib:IN2ARNative;
    private var intrinsic:IntrinsicParameters;
    private var lens:IN2ARCameraLens;
    private var container1:IN2ARContainer3D;
    private var container2:IN2ARContainer3D;
    private var video:Video;
    private var controller:CaptureController;
    private var buffer:BitmapData;
    private var matrix:Matrix;
    private var capture:CaptureTexture;
    private static const MIRROR:Boolean = false;

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

    // メソッド
    private function init():void {
      var sw:uint = stage.fullScreenWidth;
      var sh:uint = stage.fullScreenHeight;
      var scale:Number = sh/sw;
      bw = 640;
      bh = bw*scale;
      lib = new IN2ARNative();
      lib.init(bw, bh, 300, 2, 100, stage);
      lib.setupIndexing(12, 10, false);
      lib.setUseLSHDictionary(true);
      lib.addReferenceObject(ByteArray(new DefinitionData1()));
      lib.addReferenceObject(ByteArray(new DefinitionData2()));
      lib.setMaxReferencesPerFrame(2);

      intrinsic = lib.getIntrinsicParams();
      var cam:Camera = Camera.getCamera();
      cam.setMode(bw, bh, 24, false);

      video = new Video(bw, bh);
      video.attachCamera(cam);

      controller = new CaptureController(cam, CaptureController.UPDATE_BITMAPDATA);
      buffer = new BitmapData(bw, bh, false, 0x00000000);
      matrix = new Matrix();
      view = new View3D();
      scene = view.scene;
      camera = view.camera;

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

      setup();
      initialize1();
      resize();
      stage.addEventListener(Event.RESIZE, resize, false, 0, true);
      stage.mouseChildren = false;
    }
    private function setup():void {
      view.backgroundColor = 0x333333;
      view.antiAlias = 4;
      capture = new CaptureTexture(controller.bitmapData);
      capture.mirror = MIRROR;

      view.background = capture;
      lens = new IN2ARCameraLens();
      lens.updateProjection(intrinsic.fx, intrinsic.fy, bw, bh, bw, bh);

      camera.lens = lens;
      camera.position = center;

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

    }
    private function initialize1():void {
      //Parsers.enableAllBundled();
      var context:AssetLoaderContext = new AssetLoaderContext();
      context.mapUrlToData("negimiku.png", new ImageData1());

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

    }
    private function loaded1(evt:AssetEvent):void {
      if (evt.asset.assetType == AssetType.CONTAINER) {
        negimiku = ObjectContainer3D(evt.asset);
        negimiku.rotationX = 180;
        if (MIRROR) negimiku.rotationZ = 180;
        negimiku.scale(8.4);

      }
      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 complete1(evt:LoaderEvent):void {
      AssetLibrary.removeEventListener(AssetEvent.ASSET_COMPLETE, loaded1);
      evt.target.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, complete1);
      container1 = new IN2ARContainer3D();
      scene.addChild(container1);

      container1.addChild(negimiku);
      hand = new ObjectContainer3D();
      negimiku.addChild(hand);
      hand.addChild(arm);
      hand.addChild(negi);

      initialize2();
    }
    private function initialize2():void {
      //Parsers.enableAllBundled();
      var context:AssetLoaderContext = new AssetLoaderContext();
      context.mapUrlToData("slime.png", new ImageData2());

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

    }
    private function loaded2(evt:AssetEvent):void {
      if (evt.asset.assetType == AssetType.MESH) {
        slime = ObjectContainer3D(evt.asset);
        slime.rotationY = 180;
        slime.rotationZ = 90;
        if (MIRROR) slime.rotationZ = – 90;
        slime.scale(31.5);

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

        material.ambientColor = 0xFFFFFF;
      }
    }
    private function complete2(evt:LoaderEvent):void {
      AssetLibrary.removeEventListener(AssetEvent.ASSET_COMPLETE, loaded2);
      evt.target.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, complete2);
      container2 = new IN2ARContainer3D();
      scene.addChild(container2);

      container2.addChild(slime);
      complete();
    }
    private function complete():void {
      controller.addEventListener(Event.VIDEO_FRAME, update);
      lib.addListener(IN2ARDetectionEvent.DETECTED, detected);
      //lib.addListener(IN2ARDetectionEvent.FAILED, failed);
      addEventListener(Event.ENTER_FRAME, render, false, 0, true);
      jump1();
      swingHand();
      jump2();
    }
    private function jump1():void {
      var itween:ITween = BetweenAS3.serial(
        BetweenAS3.tween(negimiku, {z: 200}, {z: 100}, 0.5, Cubic.easeOut),
        BetweenAS3.tween(negimiku, {z: 100}, {z: 200}, 0.5, Cubic.easeIn)
      );
      itween.addEventListener(TweenEvent.COMPLETE, jumped1, false, 0, true);
      itween.play();

    }
    private function jumped1(evt:TweenEvent):void {
      evt.target.removeEventListener(TweenEvent.COMPLETE, jumped1);
      jump1();
    }
    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 jump2():void {
      var itween:ITween = BetweenAS3.serial(
        BetweenAS3.tween(slime, {z: 100}, {z: 20}, 0.8, Cubic.easeOut),
        BetweenAS3.tween(slime, {z: 20}, {z: 100}, 0.8, Cubic.easeIn)
      );
      itween.addEventListener(TweenEvent.COMPLETE, jumped2, false, 0, true);
      itween.play();

    }
    private function jumped2(evt:TweenEvent):void {
      evt.target.removeEventListener(TweenEvent.COMPLETE, jumped2);
      jump2();
    }
    private function render(evt:Event):void {
      if (container1) container1.lost();
      if (container2) container2.lost();
      //camera.lookAt(center);
      view.render();
    }
    private function update(evt:Event):void {
      var bitmapData:BitmapData = controller.bitmapData;
      lib.addBitmapFrame(bitmapData);
      capture.invalidate();
      if (buffer) {
        buffer.lock();
        buffer.draw(video);
        buffer.unlock();
        lib.detect(buffer);
      }
    }
    private function detected(evt:IN2ARDetectionEvent):void {
      var references:Vector.<IN2ARReference> = evt.detectedReferences;
      var max:uint = evt.detectedReferencesCount;

      for (var n:uint = 0; n < max; n++) {
        var reference:IN2ARReference = references[n];
        if (reference.id == 0) {
          if (container1) {
            container1.in2arTransform(reference.rotationMatrix, reference.translationVector, 0.8, MIRROR);
          }
        }
        if (reference.id == 1) {
          if (container2) {
            container2.in2arTransform(reference.rotationMatrix, reference.translationVector, 0.8, MIRROR);
          }
        }
      }
    }
    private function failed(evt:IN2ARDetectionEvent):void {
    }
    private function resize(evt:Event = null):void {
      //var sw:uint = stage.stageWidth;
      //var sh:uint = stage.stageHeight;

      var sw:uint = stage.fullScreenWidth;
      var sh:uint = stage.fullScreenHeight;
      view.width = sw;
      view.height = sh;
    }

  }

}

CaptureController.as (in2ar.controls.CaptureController.as)
(サンプルコードの CaptureController.as を参考に作成)
CaptureTexture.as (in2ar.away3d.textures.CaptureTexture.as)
(サンプルコードの com.in2ar.away3d.Away3DCaptureTexture.as を参考に作成)
IN2ARContainer3D.as (in2ar.away3d.containers.IN2ARContainer3D.as)
(サンプルコードの com.in2ar.away3d.Away3DContainer.as を参考に作成)
IN2ARCameraLens.as (in2ar.away3d.cameras.lenses.IN2ARCameraLens.as)
(サンプルコードの com.in2ar.away3d.Away3DCameraLens.as を参考に作成)

libsフォルダに、in2ar.ane を用意。ライブラリパスを通す。

CCなら、Android端末、iOS端末にデプロイするだけ。(AIR 3.9/ASC 2.0)


[iPad mini]

in2ar_ios_multi1

in2ar_ios_multi2

in2ar_ios_multi3