Alternativa3Dをやる その7-コントローラーを使う

Filed under 3D, Alternativa3D, AS3



Flashの3D表現ライブラリの1つである、Alternativa3Dに手を出してみました。

使ってるバージョンは7.5です。

今回は、コントローラーを使ってみました。

これを使うと、Object3Dの位置や向きを簡単に制御できます。

で、作ったのはこれ

カメラが円運動をしつつ、常に原点をむくようにコントロールしています。

lookAtがあるので、カメラの視線を簡単に変更できるのが嬉しいです。

以下ソースです。

package
{
	import alternativa.engine3d.containers.DistanceSortContainer;
	import alternativa.engine3d.controllers.SimpleObjectController;
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Clipping;
	import alternativa.engine3d.core.View;
	import alternativa.engine3d.materials.TextureMaterial;
	import alternativa.engine3d.primitives.Sphere;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;

	[SWF(backgroundColor=0x000000)]
	public class Main extends Sprite
	{
		[Embed(source='image.jpg')]
		private var img:Class;

		private static const RADIAN:Number = Math.PI/180;
		private var rootContainer:DistanceSortContainer;
		private var camera:Camera3D;
		private var view:View;
		private var theta:Number;
		private var radius:Number;
		private var controller:SimpleObjectController;
		private var back:Graphics;
		private var flug:int;

		public function Main()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.LOW;
			stage.frameRate = 30;

			// ベースとなるコンテナ。
			rootContainer = new DistanceSortContainer();
			rootContainer.sortByZ = true;

			// カメラの初期化 (PV3Dでいうフリーカメラみたいなの)。
			camera = rootContainer.addChild(new Camera3D) as Camera3D;

			// コントローラーの作成
			controller = new SimpleObjectController(stage, camera,1);

			// ビューポート (View is DisplayObject)
			view = new View(800,500);
			view.logoAlign = StageAlign.TOP_LEFT;
			camera.view = addChild(view) as View;

			// Sphereを配置
			theta = flug = 0;
			radius = 600;
			var texture:BitmapData = (new img as Bitmap).bitmapData;
			var mat:TextureMaterial = new TextureMaterial(texture, false, true);
			var sphere:Sphere = rootContainer.addChild(new Sphere(150,14,14,false,mat)) as Sphere;

			back = (addChild(new Shape) as Shape).graphics;
			onResize();
			addEventListener(Event.ENTER_FRAME, onFrame);
			stage.addEventListener(Event.RESIZE, onResize);
		}

		private function onResize(e:Event=null):void
		{
			// viewの位置を調整
			view.x = (stage.stageWidth - 800)/2;
			view.y = (stage.stageHeight - 500)/2;

			// 枠を描写
			back.clear();
			back.lineStyle(0, 0x777777);
			back.drawRect(view.x, view.y, 800, 500);
		}

		private function onFrame(e:Event):void
		{
			// カメラの位置を計算
			var _x:Number = Math.sin(theta * RADIAN) * radius;
			var _y:Number = -Math.cos(theta * RADIAN) * radius;
			theta ++;
			controller.setObjectPosXYZ(_x, _y, 0);
			controller.lookAtXYZ(0,0,0);

			// 半径計算 (大きくなったり小さくなったり)
			switch(flug)
			{
				case 1:
					radius+=2;
					if (radius > 600) flug=0;
					break;
				case 0:
					radius-=2;
					if (radius < 300) flug=1;
					break;
			}

			// レンダリング
			camera.render();
		}
	}
}

Post a Comment

Your email is never published nor shared.