Вращение камеры Alternativa 3D

Способ №1:
Создать Object3D, добавить его на сцену, затем в Object3D добавить камеру и отодвинуть ее по оси z с отрицательными координатыми, в нашем случае это -300. При создание любого объекта на сцене он смотрит “лицом вверх” параллельно оси z (подробнее тут).

В итоге, получим камеру в объекте, которая удалена от центра на -300 единиц. Теперь надо повесить действие на ENTER_FRAME, в котором происходит вращение Object3D, отсюда и камера будет летать по кругу:
post3

Ниже код:

package
{
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Scene3D;
	import alternativa.engine3d.display.View;
	import alternativa.engine3d.materials.FillMaterial;
	import alternativa.engine3d.primitives.Box;
	import alternativa.utils.FPS;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.navigateToURL;
	import flash.net.URLRequest;
 
	/**
	 * ...
	 * @author Romano (www.romano.su)
	 */
	public class ObjectRotation extends Sprite
	{
		private var scene:Scene3D;
		private var view:View;
		private var camera:Camera3D;
		private var box:Box;
		private var object:Object3D;
 
		[Embed(source = "../assets/alternativa3d_medium.png")]
		private var Logo:Class;
 
		public function ObjectRotation():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
 
			// Создание сцены
			scene = new Scene3D();
			scene.root = new Object3D();
 
			// Добавление камеры и области вывода
			camera = new Camera3D();
 
			view = new View();
			addChild(view);
			view.camera = camera;
			view.interactive = true;
 
			// создание куба
			box = new Box();
			box.cloneMaterialToAllSurfaces(new FillMaterial(0xFF0000, 1, "normal", 1, 0xFFFFFF));
			scene.root.addChild(box);
 
			// создаем объект для камеры
			object = new Object3D();
			// кидаем объект на сцену
			scene.root.addChild(object);
			// в сам объект кидаем камеру
			object.addChild(camera);
			// отодвигаем камеру на 300px
			camera.z = -300;
 
			// Запуск счётчика кадров
			FPS.init(stage);
 
			stage.addEventListener(Event.RESIZE, onResize);
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
 
			insertLogo();
 
			onResize(null);
		}
 
		private function onResize(e:Event):void {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}
 
		private function insertLogo():void
		{
			var logoSprite:Sprite = new Sprite();
			logoSprite.addChild(new Logo());
			addChild(logoSprite);
			logoSprite.x = stage.stageWidth - logoSprite.width - 5;
			logoSprite.y = stage.stageHeight - logoSprite.height - 5;
			logoSprite.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
					var request:URLRequest = new URLRequest("http://www.alternativaplatform.com");
					navigateToURL(request, "_blank");
				});
		}
 
		private function onEnterFrame(event:Event):void
		{
			// вращение объекта
			object.rotationY += Math.PI/180
 
			// Расчёт сцены
			scene.calculate();
		}
 
	}
 
}

Способ №2:
Использовать  сферические координаты.

Из сферической системы координат нам понадобятся только эти формула:

  • r ≥ 0 — расстояние от начала координат до заданной точки P.
  • 0 ≤ θ ≤ 180° — угол между осью Z и отрезком, соединяющим начало координат и точку P.
  • 0 ≤ φ ≤ 360° — угол между осью X и проекцией отрезка, соединяющего начало координат с точкой P, на плоскость XY

В данном примере, камера будет ездить по плоскости XY, значит угол тета будет равен 90°, т.к. в движке rotation задается в радианах, то будет Math.PI/2.

На ентер фрейме будем изменять только угол фи, чтобы камера летала по кругу вокруг куба.

Вот что имеем:
post3
Ниже код:

package
{
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Scene3D;
	import alternativa.engine3d.display.View;
	import alternativa.engine3d.materials.FillMaterial;
	import alternativa.engine3d.primitives.Box;
	import alternativa.utils.FPS;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.navigateToURL;
	import flash.net.URLRequest;
 
	/**
	 * ...
	 * @author Romano (www.romano.su)
	 */
	public class CameraRotation extends Sprite
	{
		private var scene:Scene3D;
		private var view:View;
		private var camera:Camera3D;
		private var box:Box;
		private var angle1:Number;
		private var angle2:Number;
 
		private var distance:Number = 300;
 
		[Embed(source = "../assets/alternativa3d_medium.png")]
		private var Logo:Class;
 
		public function CameraRotation():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
 
			// Создание сцены
			scene = new Scene3D();
			scene.root = new Object3D();
 
			// Добавление камеры и области вывода
			camera = new Camera3D();
			scene.root.addChild(camera);
 
			angle1 = Math.PI / 2;
			angle2 = 0;
 
			// выставляем камеру
			changeCameraCoords();
 
			view = new View();
			addChild(view);
			view.camera = camera;
			view.interactive = true;
 
			// создание куба
			box = new Box();
			box.cloneMaterialToAllSurfaces(new FillMaterial(0xFF0000, 1, "normal", 1, 0xFFFFFF));
			scene.root.addChild(box);
 
			// Запуск счётчика кадров
			FPS.init(stage);
 
			stage.addEventListener(Event.RESIZE, onResize);
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
 
			insertLogo();
 
			onResize(null);
		}
 
		private function changeCameraCoords():void
		{
			camera.x = distance * Math.sin(angle1) * Math.cos(angle2);
			camera.y = distance * Math.sin(angle1) * Math.sin(angle2);
			camera.z = distance * Math.cos(angle1);
 
			camera.rotationZ = angle2 + Math.PI/2;
			camera.rotationX = angle1 - Math.PI;
		}
 
		private function onResize(e:Event):void {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}
 
		private function insertLogo():void
		{
			var logoSprite:Sprite = new Sprite();
			logoSprite.addChild(new Logo());
			addChild(logoSprite);
			logoSprite.x = stage.stageWidth - logoSprite.width - 5;
			logoSprite.y = stage.stageHeight - logoSprite.height - 5;
			logoSprite.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
					var request:URLRequest = new URLRequest("http://www.alternativaplatform.com");
					navigateToURL(request, "_blank");
				});
		}
 
		private function onEnterFrame(event:Event):void
		{
			angle2 += Math.PI / 180;
			changeCameraCoords();
 
			// Расчёт сцены
			scene.calculate();
		}
 
	}
 
}

Тэги: , ,

Оставить комментарий