[AIR3.0] ロケーション・センサー

AIR for iOS で、ロケーション・センサーを試してみるよ。 :bouzu:

sensor_geolocation

Geolocationクラス を用いて、位置情報を取得するよ。 :boy:

緯度・経度・デバイスの向きが取得できるよ。

: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.events.MouseEvent;
  import flash.geom.Vector3D;
  import flash.geom.Matrix3D;

  import flash.sensors.Geolocation;
  import flash.events.GeolocationEvent;

  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.primitives.SphereGeometry;
  import away3d.materials.TextureMaterial;
  import away3d.textures.BitmapTexture;
  import away3d.primitives.ConeGeometry;
  import away3d.materials.ColorMaterial;
  import away3d.materials.lightpickers.StaticLightPicker;
  import away3d.entities.SegmentSet;
  import away3d.primitives.LineSegment;
  import away3d.utils.Cast;

  import away3d.controllers.FullHoverController;

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

  public class Main extends Sprite {
    // プロパティ
    private var bw:uint = 480;
    private var bh:uint = 640;
    private var view:View3D;
    private var scene:Scene3D;
    private var camera:Camera3D;
    private var light:DirectionalLight;
    private var controller:FullHoverController;
    private var container:ObjectContainer3D;
    private var earth:Mesh;
    private var pointer:Mesh;
    private static var radius:uint = 500;
    private static var inclination:Number = 23.4;
    private var moving:Boolean = false;
    private var angle:Number = 180;
    private var degree:Number = 0;
    private static var deceleration:Number = 0.3;
    private var point:Object = {x: 0, y: 0};
    private static var center:Vector3D = new Vector3D();
    private static var radian:Number = Math.PI/180;
    private var geolocation:Geolocation;
    private var latitude:Number = 35.7;
    private var longitude:Number = 139.6;
    private var heading:Number = 0;

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

    // メソッド
    private function init():void {
      if (Geolocation.isSupported) {
        geolocation = new Geolocation();
        geolocation.setRequestedUpdateInterval(50);
        geolocation.addEventListener(GeolocationEvent.UPDATE, locate, false, 0, true);
      }

      view = new View3D();
      scene = view.scene;
      camera = view.camera;

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

      controller = new FullHoverController(camera, null, angle, degree);
      setup();
      initialize();
      addEventListener(Event.ENTER_FRAME, render, false, 0, true);
      stage.addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
      stage.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);

    }
    private function locate(evt:GeolocationEvent):void {
      if (!isNaN(evt.latitude)) latitude = evt.latitude;
      if (!isNaN(evt.longitude)) longitude = evt.longitude;
      if (!isNaN(evt.heading)) heading = int(evt.heading);
    }
    private function setup():void {
      view.backgroundColor = 0x333333;
      view.antiAlias = 4;
      camera.x = 0;
      camera.y = 0;
      camera.z = – radius;
      var matrix:Matrix3D = new Matrix3D();
      matrix.appendRotation(45, Vector3D.Y_AXIS);
      matrix.appendRotation(- inclination, Vector3D.Z_AXIS);
      var sun:Vector3D = matrix.transformVector(new Vector3D(0, 0, 1));
      light.direction = sun;
      light.ambient = 0.4;
      light.diffuse = 0.8;
      light.specular = 0.1;

      //controller.panAngle = angle;
      //controller.tiltAngle = degree;

      controller.distance = radius;
      controller.yFactor = 1;

      controller.minTiltAngle = Number.NEGATIVE_INFINITY;
      controller.maxTiltAngle = Number.POSITIVE_INFINITY;
      controller.noFlip = true;
      controller.initialize();

    }
    private function initialize():void {
      container = new ObjectContainer3D();
      scene.addChild(container);

      container.rotationZ = – inclination;
      var lightPicker:StaticLightPicker = new StaticLightPicker([light]);
      var geometry:SphereGeometry = new SphereGeometry(160, 40, 20, true);
      var material:TextureMaterial = new TextureMaterial(new BitmapTexture(new World(1024, 512)), true, false, true);

      material.lightPicker = lightPicker;
      earth = new Mesh(geometry, material);
      container.addChild(earth);

      var _geometry:ConeGeometry = new ConeGeometry(4, 16, 8, 1, true, true);
      var _material:ColorMaterial = new ColorMaterial(0xCC0000, 1);

      _material.lightPicker = lightPicker;
      pointer = new Mesh(_geometry, _material);
      container.addChild(pointer);

      direction();
      var segment:LineSegment = new LineSegment(new Vector3D(0, 180, 0), new Vector3D(0, -180, 0), 0xFFFFFF, 0xFFFFFF, 0.8);
      var axis:SegmentSet = new SegmentSet();
      axis.addSegment(segment);
      container.addChild(axis);
    }
    private function render(evt:Event):void {
      container.rotationY -= 0.5;
      if (moving) {
        controller.panAngle = angle + (stage.mouseX – point.x)*deceleration;
        controller.tiltAngle = degree + (stage.mouseY – point.y)*deceleration;

      }
      camera.lookAt(center);
      view.render();
    }
    private function direction():void {
      var theta:Number = (longitude + 180)*radian;
      var phi:Number = latitude*radian;
      pointer.x = 168*Math.cos(theta)*Math.cos(phi);
      pointer.y = 168*Math.sin(phi);
      pointer.z = 168*Math.sin(theta)*Math.cos(phi);

      pointer.lookAt(center);
      pointer.pitch(90);
    }
    private function press(evt:MouseEvent):void {
      moving = true;
      angle = controller.panAngle;
      degree = controller.tiltAngle;
      point.x = stage.mouseX;
      point.y = stage.mouseY;

      stage.addEventListener(Event.MOUSE_LEAVE, leave, false, 0, true);
    }
    private function release(evt:MouseEvent):void {
      moving = false;
      stage.removeEventListener(Event.MOUSE_LEAVE, leave);
    }
    private function leave(evt:Event):void {
      moving = false;
      stage.removeEventListener(Event.MOUSE_LEAVE, leave);
    }

  }

}

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

画像(1024*512)を埋め込む。(画像サイズは2の累乗じゃないとダメって怒られたのでサイズ変更)
:check: 「Planet Earth Texture Maps」の画像を使わせていただきました。


[修正] (14/01/12 Sun 16:36)
参考資料「Away3D Forum HoverController with infinite tilt
HoverControllerJB.as を参考に FullHoverController.as を作成。(away3d.controllers.FullHoverController.as)
デモ版で、ドラッグして全方位に回転できるように変更。デバイス版でも、全方位に回転できるように変更。