• ホーム
  • メモ
  • as3
  • AS3 papervision3dで3D座標を2D座標に変換する魔法の公式

[PR] WEB制作会社PSYCOMMU

as3

AS3 papervision3dで3D座標を2D座標に変換する魔法の公式

papervision3dで3D座標を2D座標に変換できたら夢が膨らむなーと思っていたら・・・
やはり世の中には天才がいるもんですね。

下記サンプルのようにPlaneの中心に必ず赤いボールが付いてきているので座標変換は成功!

【サンプルswf】

とりあえず理解しようとしても無理なものは無理なので・・・
他に覚えないといけないことは山ほどあるので現状下記の公式を丸暗記。

第1引数に2D座標に変換したいDisplayObject3Dを指定。
第2引数にcameraを指定。
第3引数・第4引数にXYそれぞれのオフセット値を設定。(大概ステージの中央で大丈夫かと思われます)

private function getObj2DCords ( o:DisplayObject3D, camera:CameraObject3D,  offsetX:Number = 0, offsetY:Number = 0 ):Point{
    var view:Matrix3D = o.view;
    var persp:Number = (camera.focus * camera.zoom) / (camera.focus + view.n34);
    return new Point ( (view.n14 * persp) + offsetX, (view.n24 * persp) + offsetY );
}

あとこの公式を使用する時は忘れずに下記4行もimportしていないとエラーがでます。

import flash.geom.Point;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.proto.CameraObject3D;

【Sample20091118.as】

package {
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	
	import org.papervision3d.cameras.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.utils.*;
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.render.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.view.*;
	import org.papervision3d.objects.*;
	
	import org.papervision3d.cameras.CameraType;
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.core.proto.CameraObject3D;
	
	public class Sample20091118 extends BasicView {
		
		private var _isMouseDown:Boolean = false;
		private var _oldX:Number=0
		private var _oldY:Number=0
		private var _nowX:Number = 0;
		private var _nowY:Number = 0;
		private var _targetRot:Number = 0;
		private var _targetPitch:Number = 0;
		private var _rot:Number = 0 // 角度
		private var _pitch:Number = 0 // ピッチ=縦の角度
		
		private var _plane:Plane;
		
		private var _ball:Ball;
			
		public function Sample20091118() {
			
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			
			_init();
		
		}
		
		private function _init():void {
			
			camera.zoom = 11;
			camera.focus = 100;
			camera.z = -1100;
			
			var material:WireframeMaterial = new WireframeMaterial(0xFF0000);
			material.doubleSided = true;
			
			_plane = new Plane( material, 100, 100, 1, 1 );
			_plane.extra=new Object();
			_plane.extra.range=100;
			_plane.extra.angle = 0;
			
			scene.addChild( _plane );
			
			
			_ball = new Ball();
			addChild(_ball);

			startRendering();
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN,_onMouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, _onMouseUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, _onMouseMoveHandler);
			
		}
		
		override protected function onRenderTick(event:Event=null):void{   
 
			_rot += (_targetRot - _rot) * 0.05;
			_pitch += (_targetPitch - _pitch) * 0.05;

			_plane.x=Math.sin(_plane.extra.angle) * _plane.extra.range;
			_plane.extra.angle += 0.05;
			
			// 角度に応じてカメラの位置を設定
			camera.x = 1100 * Math.sin(_rot * Math.PI / 180);
			camera.z = 1100 * Math.cos(_rot * Math.PI / 180);
			camera.y = 1100 * Math.sin(_pitch * Math.PI / 180);
			
			var p:Point = getObj2DCords(_plane, camera, stage.stageWidth / 2 , stage.stageHeight / 2 );
			
			_ball.x = p.x;
			_ball.y = p.y;
	
			renderer.renderScene(scene, camera, viewport);   
 
		} 
		
		private function _onMouseDownHandler(e:MouseEvent):void {
			_isMouseDown = true;
			_oldX = mouseX;
			_oldY = mouseY;
		}
		private function _onMouseMoveHandler(e:MouseEvent):void {
			
			if(_isMouseDown){
				var dx:Number = e.stageX - _oldX
				var dy:Number = e.stageY - _oldY
				
				_targetRot += dx * 0.25
				_targetPitch += dy * 0.25
				
				_oldX = e.stageX
				_oldY = e.stageY
			}
			
		}
		private function _onMouseUpHandler(e:MouseEvent):void {
			_isMouseDown = false
		}
		
		private function getObj2DCords ( o:DisplayObject3D, camera:CameraObject3D,  offsetX:Number = 0, offsetY:Number = 0 ):Point{
			var view:Matrix3D = o.view;
			var persp:Number = (camera.focus * camera.zoom) / (camera.focus + view.n34);
			return new Point ( (view.n14 * persp) + offsetX, (view.n24 * persp) + offsetY );
		}
			
	}
}

import flash.display.Sprite;
class Ball extends Sprite {
	public function Ball():void {
		this.graphics.beginFill(0xCC0000 , 1 );
		this.graphics.drawCircle(0,0,6);
		this.graphics.endFill();
	}
}

【参考サイト】

AS3 papervision3dで3D座標を2D座標に変換する魔法の公式に対してコメントをする

Copyright 2009 PANDAMA. All rights reserved.
PANDAMA.com 掲載の記事・写真・図表など無断転載を禁止します。著作権はPANDAMA.comに属します。