[Papervision3D] 座標系 (2)

Papervision3Dを使って、座標系について調べてみるよ。 :boy:

pv3dCoordinates2

Papervision3Dは、左手座標系Y軸上向きだよ! :cake:
HoverController で、ぐるんぐるん動かせるようにしてみたよ。 :sun:

X軸(正値)は赤色、Y軸(正値)は緑色、Z軸(正値)は青色。オブジェクト正面に黄色の矩形を配置。

: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.events.Event;
  import flash.events.MouseEvent;

  import org.papervision3d.Papervision3D;
  import org.papervision3d.scenes.Scene3D;
  import org.papervision3d.cameras.Camera3D;
  import org.papervision3d.view.Viewport3D;
  import org.papervision3d.render.BasicRenderEngine;
  import org.papervision3d.objects.DisplayObject3D;
  import org.papervision3d.core.geom.Lines3D;
  import org.papervision3d.core.geom.renderables.Line3D;
  import org.papervision3d.core.geom.renderables.Vertex3D;
  import org.papervision3d.materials.special.LineMaterial;
  import org.papervision3d.objects.primitives.Plane;
  import org.papervision3d.objects.primitives.Cube;
  import org.papervision3d.materials.ColorMaterial;
  import org.papervision3d.materials.utils.MaterialsList;

  import papervision3d.controllers.HoverController;

  [SWF(backgroundColor="#000000", width="600", height="600", frameRate="30")]

  public class Main extends Sprite {
    // プロパティ
    private var scene:Scene3D;
    private var camera:Camera3D;
    private var viewport:Viewport3D;
    private var renderer:BasicRenderEngine;
    private var controller:HoverController;
    private var axis:Lines3D;
    private var plane:Plane;
    private var cube:Cube;
    private var front:Plane;
    private static var radius:uint = 500;
    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 radian:Number = Math.PI/180;
    private static var center:DisplayObject3D = DisplayObject3D.ZERO;

    // コンストラクタ
    public function Main() {
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      init();
    }

    // メソッド
    private function init():void {
      scene = new Scene3D();
      camera = new Camera3D();
      viewport = new Viewport3D(600, 600, false, false);
      renderer = new BasicRenderEngine();

      controller = new HoverController(camera, angle, degree);
      setup();
      initialize();
      addChild(viewport);
      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 setup():void {
      camera.x = 0;
      camera.y = 0;
      camera.z = - radius;
      camera.focus = radius;
      camera.zoom = 1;
      camera.target = center;
      controller.distance = radius;
    }
    private function initialize():void {
      axis = new Lines3D();
      scene.addChild(axis);

      var wmaterial:LineMaterial = new LineMaterial(0xFFFFFF, 1);
      var rmaterial:LineMaterial = new LineMaterial(0xFF0000, 1);
      var gmaterial:LineMaterial = new LineMaterial(0x00FF00, 1);
      var bmaterial:LineMaterial = new LineMaterial(0x0000FF, 1);
      var xaxis0:Line3D = new Line3D(axis, wmaterial, 1, new Vertex3D(-240, 0, 0), new Vertex3D(0, 0, 0));
      var xaxis1:Line3D = new Line3D(axis, rmaterial, 2, new Vertex3D(0, 0, 0), new Vertex3D(240, 0, 0));
      axis.addLine(xaxis0);
      axis.addLine(xaxis1);
      var yaxis0:Line3D = new Line3D(axis, wmaterial, 1, new Vertex3D(0, -240, 0), new Vertex3D(0, 0, 0));
      var yaxis1:Line3D = new Line3D(axis, gmaterial, 2, new Vertex3D(0, 0, 0), new Vertex3D(0, 240, 0));
      axis.addLine(yaxis0);
      axis.addLine(yaxis1);
      var zaxis0:Line3D = new Line3D(axis, wmaterial, 1, new Vertex3D(0, 0, -240), new Vertex3D(0, 0, 0));
      var zaxis1:Line3D = new Line3D(axis, bmaterial, 2, new Vertex3D(0, 0, 0), new Vertex3D(0, 0, 240));
      axis.addLine(zaxis0);
      axis.addLine(zaxis1);

      var pmaterial:ColorMaterial = new ColorMaterial(0x999999, 0.8);
      pmaterial.doubleSided = false;
      plane = new Plane(pmaterial, 320, 320, 40, 40);
      scene.addChild(plane);

      plane.rotationX = 90;
      var cmaterial:ColorMaterial = new ColorMaterial(0xFFFFFF, 1);
      var materials:MaterialsList = new MaterialsList({"all": cmaterial});

      cube = new Cube(materials, 80, 80, 80, 10, 10, 10);
      scene.addChild(cube);

      var material:ColorMaterial = new ColorMaterial(0xFFFF00, 0.6);
      material.doubleSided = false;
      front = new Plane(material, 40, 32, 1, 1);
      scene.addChild(front);

      front.z = -250;
    }
    private function render(evt:Event):void {
      if (moving) {
        controller.panAngle = angle + (stage.mouseX - point.x)*deceleration;
        controller.tiltAngle = degree + (stage.mouseY - point.y)*deceleration;

      }
      controller.update();
      renderer.renderScene(scene, camera, viewport);
    }
    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);
    }

  }

}

HoverController.as (papervision3d.controllers.HoverController.as)
package papervision3d.controllers {

  import org.papervision3d.cameras.Camera3D;

  public class HoverController {
    // プロパティ
    private var _camera:Camera3D;
    private var _angle:Number = 0;
    private var _degree:Number = 0;
    private var _panAngle:Number = 0;
    private var _tiltAngle:Number = 0;
    private var _currentPanAngle:Number = 0;
    private var _currentTiltAngle:Number = 0;
    private var _radius:Number = 0;
    private var _minPanAngle:Number = Number.NEGATIVE_INFINITY;
    private var _maxPanAngle:Number = Number.POSITIVE_INFINITY;
    private var _minTiltAngle:Number = -90;
    private var _maxTiltAngle:Number = 90;
    private static var radian:Number = Math.PI/180;
    private static var deceleration:Number = 0.2;

    // コンストラクタ
    public function HoverController(camera:Camera3D, angle:Number = 0, degree:Number = 0) {
      _camera = camera;
      _currentPanAngle = _panAngle = _angle = angle;
      _currentTiltAngle = _tiltAngle = _degree = degree;
    }

    // メソッド
    public function update():void {
      _currentPanAngle += (_panAngle - _currentPanAngle)*deceleration;
      _currentTiltAngle += (_tiltAngle - _currentTiltAngle)*deceleration;
      if (Math.abs(_panAngle - _currentPanAngle) < 0.01 && Math.abs(_panAngle - _currentPanAngle) < 0.01) {
        _currentPanAngle = _panAngle;
        _currentTiltAngle = _tiltAngle;
      }
      _camera.x = _radius*Math.sin(_currentPanAngle*radian)*Math.cos(_currentTiltAngle*radian);
      _camera.y = _radius*Math.sin(_currentTiltAngle*radian);
      _camera.z = _radius*Math.cos(_currentPanAngle*radian)*Math.cos(_currentTiltAngle*radian);
    }
    public function get panAngle():Number {
      return _panAngle;
    }
    public function set panAngle(value:Number):void {
      value = Math.max(minPanAngle, Math.min(maxPanAngle, value));
      if (_panAngle == value) return;
      _panAngle = value;
    }
    public function get tiltAngle():Number {
      return _tiltAngle;
    }
    public function set tiltAngle(value:Number):void {
      value = Math.max(_minTiltAngle, Math.min(_maxTiltAngle, value));
      if (_tiltAngle == value) return;
      _tiltAngle = value;
    }
    public function get distance():Number {
      return _radius;
    }
    public function set distance(value:Number):void {
      _radius = value;
    }
    public function get minPanAngle():Number {
      return _minPanAngle;
    }
    public function set minPanAngle(value:Number):void {
      _minPanAngle = value;
    }
    public function get maxPanAngle():Number {
      return _maxPanAngle;
    }
    public function set maxPanAngle(value:Number):void {
      _maxPanAngle = value;
    }
    public function get minTiltAngle():Number {
      return _minTiltAngle;
    }
    public function set minTiltAngle(value:Number):void {
      _minTiltAngle = value;
    }
    public function get maxTiltAngle():Number {
      return _maxTiltAngle;
    }
    public function set maxTiltAngle(value:Number):void {
      _maxTiltAngle = value;
    }

  }

}

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