Отправляемся в третье измерение с помощью PaperVision3D

Отправляемся в третье измерение с помощью PaperVision3D
Информация
Автор/переводчик: 
ProcXel.A

В этом уроке мы вновь познакомимся с движком PaperVision3D и в этот раз мы совершим прыжок за пределы монитора с помощью анаглифного эффекта в комбинации с 3D очками.

Для этого урока вам потребуются анаглифные 3D очки. У меня таких очков нет, поэтому, если у вас они есть, то наденьте их и посмотрите на финальный результат этого урока во флешке, опубликованной ниже, и напишите в комментариях о том, всё ли у меня правильно получилось. :)

Подготовка

Создайте новый *.fla файл 400 х 400 пикселей. Импортируйте в библиотеку какую-нибудь картинку и прилинкуйте ее к классу "Image".

Скачайте библиотеку papervision3d.swc. Зайдите в меню "Файл -> Параметры ActionScript 3.0" и подключите к *.fla файлу библиотеку papervision3d.swc. Так же задайте для *.fla документа главный класс "Main".

Пишем код

Для начала напишем вот такой код в классе "Main.as" в качестве заготовки:

package {
 
	import flash.display.Sprite;
 
	public class Main extends Sprite {
 
		public function Main() {
 
		}
	}
}

Теперь зададим немного свойств (переменных) класса, которые нам потребуются в дальнейшем:

		//3D сцена PaperVision, в которую помещаются всё 3D объекты.
		private var scene:Scene3D;
		//Камера левого глаза.
		private var camLeft:Camera3D;
		//Камера правого глаза.
		private var camRight:Camera3D;
		//Вьюпорт левого глаза.
		private var viewLeft:Viewport3D;
		//Вьюпорт правого глаза.
		private var viewRight:Viewport3D;
		//Рендер.
		private var renderer:BasicRenderEngine;
		//Массив кубиков.
		private var cubes:Array = [];

Теперь в конструкторе класса создадим 3D сцену и кубики:

		public function Main() {
			//Создаем 3D сцену.
			scene = new Scene3D();
			//Создаем материал с картинкой.
			var mat:BitmapMaterial = new BitmapMaterial( new Image() );
			//Создаем список материалов для каждой стороны куба.
			var matList:MaterialsList = new MaterialsList();
			matList.addMaterial( mat, "left" );
			matList.addMaterial( mat, "right" );
			matList.addMaterial( mat, "top" );
			matList.addMaterial( mat, "bottom" );
			matList.addMaterial( mat, "front" );
			matList.addMaterial( mat, "back" );
			//Создаем 27 кубиков, расположенных в виде большого куба. Получается что-то вроде трехмерной матрицы.
			for ( var i:int = 0; i < 3; i++ ) {
				for ( var j:int = 0; j < 3; j++ ) {
					for ( var k:int = 0; k < 3; k++ ) {
						//Создаем один куб.
						var cube:Cube = new Cube( matList, 100, 100, 100, 2, 2, 2 );
						//Позиционируем куб.
						cube.x = i * 200 - 200;
						cube.y = j * 200 - 200;
						cube.z = k * 200;
						//Помещаем на сцену.
						scene.addChild( cube );
						//Добавляем в массив.
						cubes.push( cube );
					}
				}
			}
}

Далее создадим всё в том же конструкторе две камеры для левого и правого глаза. И два отдельных вьюпорта для каждой камеры:

//Создаем камеру левого глаза.
camLeft = new Camera3D();
//Позиционируем.
camLeft.z = -520;
camLeft.x = 10;
//Создаем камеру правого глаза.
camRight = new Camera3D();
//Позиционируем.
camRight.z = -520;
camRight.x = -10;
//Создаем вьюпорт левого глаза, в котором будет рисоваться то, что видит камера левого глаза.
viewLeft = new Viewport3D();
//Создаем вьюпорт правого глаза, в котором будет рисоваться то, что видит камера правого глаза.
viewRight = new Viewport3D();
//Выравниваем вьюпорты по размеру главной сцены.
viewLeft.autoScaleToStage = true;
viewRight.autoScaleToStage = true;
//Рисуем во вьюпортах серый задний фон.
viewLeft.graphics.beginFill( 0x333333 );
viewLeft.graphics.drawRect( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
viewRight.graphics.beginFill( 0x333333 );
viewRight.graphics.drawRect( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
//Добавляем вьюпорты в список отображения.
this.addChild( viewLeft );
this.addChild( viewRight );

Теперь добавим анаглифный эффект к нашим вьюпортам:

			//Вырезаем из левого вьюпорта красный канал.
			var viewLeftColorransform:ColorTransform = new ColorTransform( 0, 1, 1 );
			//Вырезаем из правого вьюпорта зеленый и синий канал канал.
			var viewRightColorransform:ColorTransform = new ColorTransform( 1, 0, 0 );
			//Применяем цветокорекцию к вьюпортам.
			viewLeft.transform.colorTransform = viewLeftColorransform;
			viewRight.transform.colorTransform = viewRightColorransform;
			//Применяем режим наложения для правого вьюпорта. Тем самым цвета двух вьюпортов накладываются друг на друга, образуя анаглифный эффект.
			viewRight.blendMode = BlendMode.ADD;

Теперь осталось создать покадровый рендер сцены. В конструкторе дописываем:

			//Создаем PaperVision рендер.
			renderer = new BasicRenderEngine();
			//Добавляем слушатель каждого кадра.
			this.stage.addEventListener( Event.ENTER_FRAME, Update );

И в классе создаем функцию обновления:

		private function Update( e:Event ):void {
			//Вращаем кубики.
			for each ( var cube:Cube in cubes ) {
				cube.rotationX += 1;
				cube.rotationY += 2;
			}
			//Отрисовываем вьюпорты.
			renderer.renderScene( scene, camLeft, viewLeft );
			renderer.renderScene( scene, camRight, viewRight );
		}

Теперь сохраним наш класс Main.as и протестируем ролик. И если ничего не напутали, то увидим, как кубики вращаются и... Странно выглядят. Но не беда! Надеваем очки и оп! Теперь всё сразу становится красиво и понятно. :)

Полный код класса Main.as выглядит вот так:

package {
 
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.shadematerials.PhongMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
 
	public class Main extends Sprite {
		//3D сцена PaperVision, в которую помещаются всё 3D объекты.
		private var scene:Scene3D;
		//Камера левого глаза.
		private var camLeft:Camera3D;
		//Камера правого глаза.
		private var camRight:Camera3D;
		//Вьюпорт левого глаза.
		private var viewLeft:Viewport3D;
		//Вьюпорт правого глаза.
		private var viewRight:Viewport3D;
		//Рендер.
		private var renderer:BasicRenderEngine;
		//Массив кубиков.
		private var cubes:Array = [];
 
		//Конструктор.
		public function Main() {
			//Создаем 3D сцену.
			scene = new Scene3D();
			//Создаем материал с картинкой.
			var mat:BitmapMaterial = new BitmapMaterial( new Image() );
			//Создаем список материалов для каждой стороны куба.
			var matList:MaterialsList = new MaterialsList();
			matList.addMaterial( mat, "left" );
			matList.addMaterial( mat, "right" );
			matList.addMaterial( mat, "top" );
			matList.addMaterial( mat, "bottom" );
			matList.addMaterial( mat, "front" );
			matList.addMaterial( mat, "back" );
			//Создаем 27 кубиков, расположенных в виде большого куба. Получается что-то вроде трехмерной матрицы.
			for ( var i:int = 0; i < 3; i++ ) {
				for ( var j:int = 0; j < 3; j++ ) {
					for ( var k:int = 0; k < 3; k++ ) {
						//Создаем один куб.
						var cube:Cube = new Cube( matList, 100, 100, 100, 2, 2, 2 );
						//Позиционируем куб.
						cube.x = i * 200 - 200;
						cube.y = j * 200 - 200;
						cube.z = k * 200;
						//Помещаем на сцену.
						scene.addChild( cube );
						//Добавляем в массив.
						cubes.push( cube );
					}
				}
			}
			//Создаем камеру левого глаза.
			camLeft = new Camera3D();
			//Позиционируем.
			camLeft.z = -520;
			camLeft.x = 10;
			//Создаем камеру правого глаза.
			camRight = new Camera3D();
			//Позиционируем.
			camRight.z = -520;
			camRight.x = -10;
			//Создаем вьюпорт левого глаза, в котором будет рисоваться то, что видит камера левого глаза.
			viewLeft = new Viewport3D();
			//Создаем вьюпорт правого глаза, в котором будет рисоваться то, что видит камера правого глаза.
			viewRight = new Viewport3D();
			//Выравниваем вьюпорты по размеру главной сцены.
			viewLeft.autoScaleToStage = true;
			viewRight.autoScaleToStage = true;
			//Рисуем во вьюпортах серый задний фон.
			viewLeft.graphics.beginFill( 0x333333 );
			viewLeft.graphics.drawRect( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
			viewRight.graphics.beginFill( 0x333333 );
			viewRight.graphics.drawRect( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
			//Добавляем вьюпорты в список отображения.
			this.addChild( viewLeft );
			this.addChild( viewRight );
			//Вырезаем из левого вьюпорта красный канал.
			var viewLeftColorransform:ColorTransform = new ColorTransform( 0, 1, 1 );
			//Вырезаем из правого вьюпорта зеленый и синий канал канал.
			var viewRightColorransform:ColorTransform = new ColorTransform( 1, 0, 0 );
			//Применяем цветокорекцию к вьюпортам.
			viewLeft.transform.colorTransform = viewLeftColorransform;
			viewRight.transform.colorTransform = viewRightColorransform;
			//Применяем режим наложения для правого вьюпорта. Тем самым цвета двух вьюпортов накладываются друг на друга, образуя анаглифный эффект.
			viewRight.blendMode = BlendMode.ADD;
			//Создаем PaperVision рендер.
			renderer = new BasicRenderEngine();
			//Добавляем слушатель каждого кадра.
			this.stage.addEventListener( Event.ENTER_FRAME, Update );
		}
 
		//Функция обновления кадров.
		private function Update( e:Event ):void {
			//Вращаем кубики.
			for each ( var cube:Cube in cubes ) {
				cube.rotationX += 1;
				cube.rotationY += 2;
			}
			//Отрисовываем вьюпорты.
			renderer.renderScene( scene, camLeft, viewLeft );
			renderer.renderScene( scene, camRight, viewRight );
		}
	}
}

Конец. А кто читал - молодец.

Исходник: 

Впервые!

Если у вас было хоть раз желание сделать что-то новое и необычное, то этот видеокурс для вас! Знания ActionScript 3.0 вдохнут в ваши проекты новую жизнь, позволив тем самым поднять их на новый уровень

С помощью этого видеокурса вы пройдёте путь от новичка до Объектно-Ориентированного Программирования, сможете работать со многими популярными библиотеками и научитесь создавать сайты во flash! + Видеокурс по PaperVision3D в подарок!

Видеокурс содержит 119 видеоуроков в 12 главах. На сегодняшний день это единственный видеокурс, таких масштабов

Узнайте о других возможностях ActionScript 3.0


Внимание!

Первый в интернете видеокурс по популярной as библиотеке PaperVision3D! C этим курсом вы поймете, что 3D во flash – это просто и интересно!

55 видео уроков

Шаг за шагом расскажут и покажут, как делать свои интерактивные 3D проекты во flash. Курс сопровождается множеством примеров, поэтому он особенно легко усваивается.

Подробное описание курса

Похожие записи