Статьи

Руководство для начинающих по дополненной реальности, часть 2

Добро пожаловать во вторую часть моего Руководства по дополненной реальности для начинающих. Надеюсь, вы завершили первую часть этого руководства или, по крайней мере, скачали и прочитали исходные файлы (в противном случае вы можете немного запутаться в происходящем).


В прошлый раз мы рассматривали настройку простой среды AR, создание куба, применение материалов к кубу и эффект «дыры в стене».

Сегодня мы будем опираться на эти знания и создавать финал, как показано в демоверсии. Чтобы создать этот конечный эффект, нам нужно знать, как визуализировать сферы, анимировать объекты, воспроизводить звуковые эффекты и, наконец, визуализировать трехмерные объекты. Рендеринг трехмерных объектов на ладони — главная причина того, что дополненная реальность стала большим хитом в этом году, особенно когда вы создаете некоторые из наиболее интересных фигур или анимируете их. Если вы находитесь в Великобритании, вы, возможно, недавно видели The Gadget Show, где они демонстрировали дополненную реальность и имели анимированную версию Suzi Perry, которую вы могли бы держать в руке. Очень хорошо.

Итак, приступим к делу. Я начну с мира, и звезды будут рендериться в первую очередь, затем перейдем к анимации фигур и, наконец, к созданию коровы. Откройте ваши файлы с прошлого раза, и давайте приступим к созданию.


Источник: НАСА

Источник: НАСА Видимая Земля . Предоставлено: Рето Штекли, Роберт Симмон.

Загрузите версию изображения размером 2048×1024 пикселей со страницы NASA Visible Earth и назовите ее map.jpg. Поместите его в следующую папку: deploy> assets. Это та же папка, в которой вы сохранили изображения для внутренней части куба в последней части урока. Этот прекрасный образ мира прибыл из НАСА. Они делают хорошие фотографии, не так ли?


В своем коде перейдите к тому месту, где мы в последний раз настраивали эффект «дыры в стене» для маркера 0. Сразу после кода «дыра в стене» добавьте следующий код:

1
2
3
var Earth:Sphere = new Sphere(earth, 40);
Earth.z=200;
dispObj.addChild(Earth);

Теперь, когда мы создали сферу, ей нужна текстура. Это делается точно так же, как отображение текстуры в кубе. Обратите внимание, что в настройке для сферы она ищет нечто, называемое «земля», это наша переменная текстуры.

Перейдите в коде туда, где мы настраивали материалы раньше. Добавьте к этому коду следующую строку:

1
var earth : BitmapFileMaterial = new BitmapFileMaterial(«assets/map.jpg»);

Так же, как и другие.


Когда вы проверяете это, вы должны увидеть что-то вроде следующего изображения (но, конечно, без этого красивого дьявола, держащего маркер для вас):

источник: очень белая комната

Как и в прошлый раз, вам нужно скачать изображение маркера и распечатать его с большим количеством пустого пространства по краям.


Какое же космическое изображение без звезд? Давайте добавим немного в мы? Это, возможно, самая утомительная часть для меня, чтобы написать, так как все звезды должны быть расположены в индивидуальном порядке. Но вы, нахальные негодяи, получаете преимущество копирования и вставки.

Добавьте следующий код после кода рендеринга:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
var star1:Sphere = new Sphere(star, 4);
star1.z=65;
star1.x=84;
star1.y=164;
dispObj.addChild(star1);
 
var star2:Sphere = new Sphere(star, 3);
star2.z=246;
star2.x=32;
star2.y=64;
dispObj.addChild(star2);
                                                         
var star3:Sphere = new Sphere(star, 2);
star3.z=163;
star3.x=78;
star3.y=98;
dispObj.addChild(star3);
 
var star4:Sphere = new Sphere(star, 4);
star4.z=120;
star4.x=164;
star4.y=157;
dispObj.addChild(star4);
 
var star5:Sphere = new Sphere(star, 2);
star5.z=148;
star5.x=-164;
star5.y=-157;
dispObj.addChild(star5);
                 
var star6:Sphere = new Sphere(star, 3);
star6.z=46;
star6.x=-36;
star6.y=-156;
dispObj.addChild(star6);
 
var star7:Sphere = new Sphere(star, 5);
star7.z=40;
star7.x=-16;
star7.y=-84;
dispObj.addChild(star7);
                 
var star8:Sphere = new Sphere(star, 5);
star8.z=59;
star8.x=-84;
star8.y=30;
dispObj.addChild(star8);
 
var star9:Sphere = new Sphere(star, 4);
star9.z=87;
star9.x=-134;
star9.y=84;
dispObj.addChild(star9);
 
var star10:Sphere = new Sphere(star, 2);
star10.z=49;
star10.x=10;
star10.y=18;
dispObj.addChild(star10);
 
var star11:Sphere = new Sphere(star, 5);
star11.z=94;
star11.x=-84;
star11.y=41;
dispObj.addChild(star11);
 
var star12:Sphere = new Sphere(star, 3);
star12.z=54;
star12.x=91;
star12.y=-46;
dispObj.addChild(star12);
 
var star13:Sphere = new Sphere(star, 2);
star13.z=180;
star13.x=88;
star13.y=-130;
dispObj.addChild(star13);
 
var star14:Sphere = new Sphere(star, 4);
star14.z=102;
star14.x=134;
star14.y=-13;
dispObj.addChild(star14);
 
var star15:Sphere = new Sphere(star, 1);
star15.z=61;
star15.x=-35;
star15.y=145;
dispObj.addChild(star15);

Фу, это довольно много. Конечно, вы можете добавить больше, если хотите больше звезд. Или просто использовать цикл массив для добавления произвольного числа.


Теперь нам нужно добавить материал для звезд. Добавьте следующее с другим кодом материала:

1
var star : ColorMaterial = new ColorMaterial(0xFFFFFF);

Протестируйте флэш-фильм и, надеюсь, вы увидите что-то вроде этого:

источник: очень белая комната

Разве не было бы здорово, если бы, скажем, у нас была космическая сцена, которую мы только что создали, попали в маленькую коробочку внутри маркера и затем взорвались? Ну, вам повезло, и, вероятно, вы увидели результат, так как именно это мы и собираемся делать.

Это довольно просто оживить вещи в AR. Особенно, если вы просто хотите переместить их из одной точки в другую, как мы хотим. Для этого нам нужно скачать несколько дополнительных классов для Flash. GreenSock создает замечательную серию библиотек анимации, которые помогают нам легко перемещать объекты из одной точки в другую.

Зайдите на greensock.com и загрузите библиотеку AS3 TweenMax .


После того, как вы скачали библиотеку TweenMax, вам нужно извлечь файл .zip и поместить папку greensock в src> com нашего проекта. Здесь также хранится библиотека squidder. Извлеките сюда и все будет просто отлично.

Теперь вернитесь к Flash. Добавьте следующую строку вверху вашего кода с другими строками импорта:

1
import com.greensock.*;

Теперь у вас есть доступ к библиотеке GreenSock.


Найдите код, в котором вы устанавливаете переменную Земли. Замените его следующим кодом:

1
2
3
var Earth:Sphere = new Sphere(earth, 1);
Earth.z=-40;
TweenMax.to(Earth, 4, {scaleX:40, scaleY:40, scaleZ:40, z:»200″, delay:4});

Здесь я изменил начальную точку и размер Земли, чтобы она была очень маленькой и находилась внутри коробки. TweenMax — отличный анимационный класс. Здесь мы устанавливаем, какую переменную нужно анимировать (Земля), сколько времени это займет в секундах (4), на сколько она должна масштабировать переменную, ее точку z и, наконец, сколько времени она должна ждать перед анимацией. Это установлено на 4, чтобы мы могли сначала оживить другие вещи.


Замените весь код установки звездочки следующим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
var star1:Sphere = new Sphere(star, 1);
star1.z=-40;
TweenMax.to(star1, 4,{scaleX:1, scaleY:1, scaleZ:1, x:»84″, y:»164″, z:»65″, delay:4});
dispObj.addChild(star1);
                     
var star2:Sphere = new Sphere(star, 1);
star2.z=-40;
TweenMax.to(star2, 4,{scaleX:3, scaleY:3, scaleZ:3, x:»32″, y:»64″, z:»246″, delay:4});
dispObj.addChild(star2);
                     
var star3:Sphere = new Sphere(star, 1);
star3.z=-40;
TweenMax.to(star3, 4,{scaleX:2, scaleY:2, scaleZ:2, x:»78″, y:»98″, z:»163″, delay:4});
dispObj.addChild(star3);
                     
var star4:Sphere = new Sphere(star, 1);
star4.z=-40;
TweenMax.to(star4, 4,{scaleX:4, scaleY:4, scaleZ:4, x:»164″, y:»157″, z:»120″, delay:4});
dispObj.addChild(star4);
                     
var star5:Sphere = new Sphere(star, 1);
star5.z=-40;
TweenMax.to(star5, 4,{scaleX:2, scaleY:2, scaleZ:2, x:»-164″, y:»-157″, z:»148″, delay:4});
dispObj.addChild(star5);
                     
var star6:Sphere = new Sphere(star, 1);
star6.z=-40;
TweenMax.to(star6, 4,{scaleX:3, scaleY:3, scaleZ:3, x:»-36″, y:»-156″, z:»46″, delay:4});
dispObj.addChild(star6);
                     
var star7:Sphere = new Sphere(star, 1);
star7.z=-40;
TweenMax.to(star7, 4,{scaleX:5, scaleY:5, scaleZ:5, x:»-16″, y:»-84″, z:»40″, delay:4});
dispObj.addChild(star7);
                     
var star8:Sphere = new Sphere(star, 1);
star8.z=-40;
TweenMax.to(star8, 4,{scaleX:5, scaleY:5, scaleZ:5, x:»-84″, y:»30″, z:»59″, delay:4});
dispObj.addChild(star8);
                     
var star9:Sphere = new Sphere(star, 1);
star9.z=-40;
TweenMax.to(star9, 4,{scaleX:4, scaleY:4, scaleZ:4, x:»-134″, y:»84″, z:»87″, delay:4});
dispObj.addChild(star9);
                     
var star10:Sphere = new Sphere(star, 1);
star10.z=-40;
TweenMax.to(star10, 4,{scaleX:2, scaleY:2, scaleZ:2, x:»10″, y:»18″, z:»49″, delay:4});
dispObj.addChild(star10);
                     
var star11:Sphere = new Sphere(star, 1);
star11.z=-40;
TweenMax.to(star11, 4,{scaleX:5, scaleY:5, scaleZ:5, x:»-84″, y:»41″, z:»94″, delay:4});
dispObj.addChild(star11);
                     
var star12:Sphere = new Sphere(star, 1);
star12.z=-40;
TweenMax.to(star12, 4,{scaleX:3, scaleY:3, scaleZ:3, x:»91″, y:»-46″, z:»54″, delay:4});
dispObj.addChild(star12);
                     
var star13:Sphere = new Sphere(star, 1);
star13.z=-40;
TweenMax.to(star13, 4,{scaleX:2, scaleY:2, scaleZ:2, x:»88″, y:»-130″, z:»180″, delay:4});
dispObj.addChild(star13);
                     
var star14:Sphere = new Sphere(star, 1);
star14.z=-40;
TweenMax.to(star14, 4,{scaleX:4, scaleY:4, scaleZ:4, x:»134″, y:»-13″, z:»102″, delay:4});
dispObj.addChild(star14);
                     
var star15:Sphere = new Sphere(star, 1);
star15.z=-40;
TweenMax.to(star15, 4,{scaleX:1, scaleY:1, scaleZ:1, x:»-35″, y:»145″, z:»61″, delay:4});
dispObj.addChild(star15);

Это оживит ваши звезды от скрытой начальной точки до их конечных положений. Опять же, я изменил z-положения звезд, чтобы они начинались внутри коробки.


Давайте снова протестируем Flash-ролик. У вас должен быть хороший анимированный переход из ничего на землю и звезды, взрывающиеся из коробки, в которую мы их заперли.

источник: подозрительно белая комната
источник: подозрительно белая комната
источник: подозрительно белая комната

Для крышки коробки, которая откроется и взорвутся Земля и звезды, мы будем использовать четыре изображения. Я использую деревянную панель для своей коробки, но не стесняйтесь создавать свою. Вот изображения, которые я сделал, скачайте их и сохраните в установках deploy>.

Источник: я сделал это.

Сохранить как top.png

Источник: я сделал это.

Сохранить как bottom.png

Источник: я сделал это.

Сохранить как left.png

Источник: я сделал это.

Сохранить как right.png


Ниже, где мы устанавливаем звезды, добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var top:Cube = new Cube( new MaterialsList( {all: Top} ) , 80 , 0 , 80 );
top.z=0;
top.y=40;
TweenMax.to(top, 2,{rotationX:-180, delay:2});
dispObj.addChild(top);
                      
var bottom:Cube = new Cube( new MaterialsList( {all: Bottom} ) , 80 , 0 , 80 );
bottom.z=0;
bottom.y=-40;
TweenMax.to(bottom, 2,{rotationX:180, delay:2});
dispObj.addChild(bottom);
                      
var left:Cube = new Cube( new MaterialsList( {all: Left} ) , 80 , 0 , 80 );
left.z=0;
left.rotationZ=90;
left.x=-40;
TweenMax.to(left, 2,{rotationX:180, delay:2});
dispObj.addChild(left);
                      
var right:Cube = new Cube( new MaterialsList( {all: Right} ) , 80 , 0 , 80 );
right.z=0;
right.x=40;
right.rotationZ=90;
TweenMax.to(right, 2,{rotationX:-180, delay:2});
dispObj.addChild(right);

Это устанавливает все детали, которые составляют крышку коробки, правильно их позиционирует и анимирует. Отличный материал.

Каждый «куб» имеет нулевую глубину (третий аргумент в конструкторе), поэтому они кажутся плоскими плоскостями.


В разделе материала добавьте следующий код:

1
2
3
4
var Top : BitmapFileMaterial = new BitmapFileMaterial(«assets/top.png»);
var Bottom : BitmapFileMaterial = new BitmapFileMaterial(«assets/bottom.png»);
var Left : BitmapFileMaterial = new BitmapFileMaterial(«assets/left.png»);
var Right : BitmapFileMaterial = new BitmapFileMaterial(«assets/right.png»);

Теперь крышка будет смотреться со стороны. Я уверен, что вы заметили, что левые и правые изображения поворачиваются, а затем я снова поворачиваю их в коде на шаге 14. Возможно, вы удивляетесь, почему я сделал это, а не просто оставил изображения такими, какими они были. Ну, есть причина для этого. Они не будут работать правильно, если вы не поверните их. Это странная ошибка, но при рендеринге изображения переворачиваются в обратном направлении, и когда вы применяете к ним анимацию, они идут не в ту сторону. Вращение их сначала, а затем обратно в коде заставляет их работать как надо. Это довольно странно, но вы идете.


Теперь все детали готовы к следующему испытанию, и все становится на свои места. Я уверен, что ты сейчас издаешь всевозможные шумы. Изумительный.

источник: самый белый из белых комнат
источник: самый белый из белых комнат
источник: самый белый из белых комнат

Если вы похожи на меня, вы смотрите на это мышление, вау, это здорово, но для этого действительно нужно больше драмы. Ну, мы собираемся сделать именно это. Давайте добавим немного драматической музыки, когда коробка откроется.

Перейдите в библиотеку звуковых эффектов Hollywood Edge и загрузите BrightPad.wav. (Он не включен в загрузку исходного кода.) Я преобразовал это в MP3 с именем «dramatic.mp3», но вы можете следовать этим инструкциям, сохраняя его в формате WAV.

Сохраните его в папке deploy> assets.


Откройте файл .fla и выберите «Файл»> «Импорт»> «Импорт в библиотеку». Импорт dramatic.mp3.

Откройте свою библиотеку, и вы должны увидеть свой недавно импортированный файл, сидящий прямо там.

Щелкните правой кнопкой мыши и выберите «Свойства». Установите флажок «Экспорт для ActionScript». Поле класса теперь должно стать активным; введите его «драматический» без кавычек.

Источник: Flash CS4. Меню свойств

Вернитесь в файл .as. В верхней части файла найдите код импорта. Добавьте следующий код импорта:

1
2
import flash.media.SoundMixer;
import flash.media.SoundChannel;

Чуть дальше внизу есть несколько частных варов. Вы можете помнить это с прошлого раза, когда мы настраивали зеленый куб. Добавьте следующий код в приватные переменные:

1
2
private var drama:dramatic = new dramatic();
private var dramaChnl:SoundChannel = new SoundChannel();

Теперь мы установили звуковой файл «драматический» и звуковой канал. Звуковой канал позволяет запускать и останавливать звук через код.


Поскольку мы хотим, чтобы звук воспроизводился только один раз (когда открывается окно, а не каждый раз, когда мы показываем маркер), вам необходимо добавить следующий код со всем кодом настройки формы. Я положил свой сразу после того, как я установил крышку коробки.

1
dramaChnl = drama.play(0,1);

Это воспроизводит звук один раз, когда крышка открывается.


Теперь звук должен звучать, и, надеюсь, он будет действительно очень драматичным.

Вы должны чувствовать себя очень довольными собой прямо сейчас, вы создали то, что может произвести впечатление на ваших друзей.


Теперь мы переходим к той части, где мы отрисовываем 3D-корову, которую вы можете держать в руке. Прежде всего, вам необходимо скачать следующие два файла, сохранить их в обычном месте:

источник: не настоящая шкура коровы

Текстура , которую вы должны сохранить как Cow.png, и файл модели коровы, который вы должны сохранить как cow.dae.


Вверху вашего файла вам нужно добавить импорт. Добавьте следующую строку:

1
import org.papervision3d.objects.parsers.Collada;

Найдите приватные переменные чуть ниже и добавьте следующее:

1
2
3
private var cowSkin: BitmapFileMaterial;
private var cowMat: MaterialsList;
private var cow: Collada;

Мы собираемся загрузить корову на второй маркер. Это должно показать вам, что этот метод загрузки различных объектов на разные маркеры достаточно надежен и может обрабатывать не только фигуры, но и сложные 3D-объекты.

Помните, в предыдущей части урока мы имели четыре маркера на одном листе бумаги и создавали разные цветные кубики для каждого маркера? Мы собираемся повторно использовать этот код, чтобы позволить нам использовать отдельный маркер для коровы и Земли.

Перемещайтесь по своему файлу, пока не найдете else if (id ==1){ — проверка второго маркера.

Замените все в двух фигурных скобках следующим кодом:

1
2
3
4
5
6
7
8
9
cowMat = new MaterialsList();
cowSkin = new BitmapFileMaterial(«assets/Cow.png»);
cowMat.addMaterial(cowSkin,»all»);
            
//Create the new Collada Object with cowMat
cow = new Collada(«assets/cow.dae»,cowMat);
cow.rotationX = 90;
cow.scale = 0.5;
dispObj.addChild(cow);

Да, больше тестов уже не было так быстро. Скачайте и распечатайте второй маркер . Если все идет хорошо, вы должны стать счастливым обладателем новой маленькой 3-й коровы. Поздравляем!

источник: эта комната такая белая

Здорово, что у нас такая красивая корова, но разве не лучше, если бы корова заговорила?

Перейдите в этот каталог файлов с компакт-диска под названием The Best Of Tucows , том 2 — и загрузите MOO.WAV. (Он не включен в исходную загрузку.)

Сохраните его в обычном месте как moo.wav.

Перейдите к файлу .fla и импортируйте файл в свою библиотеку. Как и в случае с последним импортированным звуковым файлом, откройте его свойства, установите флажок «Экспорт для ActionScript» и измените его класс на mooSnd.


Перейдите к частным файлам и добавьте следующие строки кода:

1
2
private var moo:mooSnd = new mooSnd();
private var mooChnl:SoundChannel = new SoundChannel();

Теперь для этого маркера я хочу, чтобы звук воспроизводился каждый раз, когда появляется корова, но только один раз. Для этого вам нужно добавить код для воспроизведения звука в немного другом месте, чем мы делали в прошлый раз.

Найдите эту строку в своем коде:

1
private function _addCube( id:int , index:int ) : void {

Мы хотим добавить наш код сразу после этого. Принимая следующее из кода настройки формы, он будет воспроизводиться каждый раз, когда будет найден идентификатор, а не когда форма настроена, что происходит только один раз.

Добавьте этот код:

1
2
3
if(id==1){
    mooChnl = moo.play(0, 1);
}

Протестируйте файл в последний раз, и корова должна мычать. Вы даже можете использовать оба маркера одновременно и быть супер свистом.

источник: одной рукой, ооо да

Я надеюсь, что вам понравился этот учебник из двух частей по дополненной реальности, и надеюсь, что вы можете уйти сейчас и создать несколько очень крутых вещей.