3D Flash (практика), Создаем контрольную панель гравицапы

Источник: arttower

Тема этого урока - конвертация из 3D Max (или любого другого 3D-редактора, допускающего экспорт в формат 3ds) в Flash методом векторного пререндеринга и возможные варианты использования полученного материала. Оговорю специально, что это не урок о том, как делать сайты или презентации, и вопросы художественные в данном случае не рассматриваются. Цель урока - дать представление о технических возможностях подобного подхода.
Урок очень длинный, но если вы его одолеете - у Вас будет весьма интересное средство для реализации дизайнерских фантазий.

Я не буду оговаривать каждый раз, когда нужно сохранить файл. Скажу один раз, что это нужно делать каждые 5-10 минут просто на всякий случай, и к тому же - в новый файл (3D Max это делает автоматически при нажатии на "+" в диалоге Save As, в остальных программах сохранение предыдущих версий придется делать вручную).

Итак: мы делаем оригинальный интерфейс пользователя, корнями уходящий в увлечение автора урока игрой "ИЛ-2 Штурмовик". Предположим, что мы уже создали в 3D MAX нужную нам модель "кокпита" нашей гравицаппы. Примерно такая:

 Уменьшено: 98% от [ 800 на 608 ] - нажмите для просмотра полного изображения

На моделировании такого объекта останавливаться не будем, а перейдем непосредственно к теме урока - конвертации

1. Подготовка модели и анимации в 3D MAX.

а) Первым делом разгруппируем все сгруппированные объекты. Удобнее всего это делать не ungroup, а explode - с помощью этой функции объекты разгруппировываются по всем уровням вложенности групп. Делать это нужно потому, что группы не отобразятся правильно в Swift3D - будут перепутаны pivot point-ы (точки привязки), и сгруппированные объекты переместятся в сцене на совершенно неожиданные места - а выставлять их на места в Swift 3D - задача не из приятных.


б) Все элементы нашей модели оптимизируем - в разумных пределах, но помня, что 100 000 полигонов - это для Swift3D ноша тяжелая, к тому же увеличивающая размер конечной swf-ки (за счет не особенно нужного нам точного просчета теней векторным рендером), а, с другой стороны - слишком сильная оптимизация даст "вылезшие полигоны" на конечном рендере.


в) После этого все элементы модели, кроме стандартных примитивов (бокс, сфера, цилиндр), превращаем в Editable Mesh. Оставшиеся в стеке модификаторы - риск получить "кривую" 3ds-ку, которую Swift попросту не поймет и в лучшем случае не так отобразит, в худшем - зависнет.


г) Поскольку анимация камеры у нас очень простая, не предполагающая сложного движения по контроллерам, мы можем выставить и анимировать камеру прямо в 3D MAX. Для наших целей нужно поставить Target камеру точно по центру на некотором расстоянии от нашей "панели управления" - примерно как на первом скриншоте. После этого выставляем количество фреймов (50), FPS (25/с) - хотя это скорее для предварительного просмотра в 3D MAX, FPS мы будем выставлять позднее.
При выбранной камере нажимаем Set Keys, то же самое делаем при выбранном Target-е камеры. Переходим на последний фрейм анимации и при нажатом auto key двигаем камеру и target до положения, когда видна "приборная доска" нашего "кокпита".


Просматриваем, поправляем камеру, еще раз проверяем, все ли объекты разгруппированы и "с-мешены", и - экспортируем в формат 3ds. Т.е. выбираем File -> Export, формат "3ds", задаем имя файла, сохранить. Все, на этом работа в 3D MAX завершена.

2. Импорт модели и редактирование сцены в Swift3D.

а) Запускаем Swift3D , помолясь богам 3D-моделлеров, выбираем пункт "File->New from 3DS".
В общем-то, импортом назвать это в полной мере и нельзя: это действительно создание новой сцены t3d (формат хранения данных Swift-а) с использованием имеющейся сцены формата 3ds.
Мы видим примерно такую картину:

 Уменьшено: 98% от [ 800 на 625 ] - нажмите для просмотра полного изображения

б) У нас имеется два окна для 3d-видов, панель инструментов сверху, два больших внизу - одно для вращения объектов, другое для вращения источников света, - правее - библиотека материалов, слева вверху - основное "меню сцены", оно же окно свойств, откуда можно управлять параметрами сцены вроде environment и ambient light, и параметрами объектов в зависимости от того, какой объект выбран - от координат и углов поворота до параметров сглаживания (и то, и другое нам пригодится). Здесь же (пункт Layout) выставляются основные параметры - конечный размер (у нас 800x600), способы отображения 3d-видов (на удивление не влияющие на скорость прорисовки), отображение "сеток" и др.
Первое знакомство с перемещением по этой сцене оставляет недоумение - навигация в 3d-окнах неудобна. По "drag"-у левой (на свободном месте! - щелкнув на объекте, "утащим" объект) - панорамирование, по "drag"-у правой клавишей мыши - zoom. Все вращение - как объектов, так и камер - осуществляется "трекболлом" - окном с серым шаром в левом нижнем углу. При этом клавиши Shift, Ctrl и Ctrl+Shift используются для залочивания плоскости вращения.
Поэкспериментируйте немного (только не с основной камерой - а то нам придется пересоздавать сцену; сделайте активным соседнее окно и там потренируйтесь в навигации а-ля Swift 3D).
Плохая новость: нормального диметрического вида здесь нет: все виды Front, Left и т.д. - это такие же виды из камер, как и Perspective. Хорошая новость: нас это не остановит smile.gif и даже не особенно помешает.

в) Но пора и к делу.
Для начала несколько изменим движение камеры и сократим число фреймов. По нашей идее, интерфейс будет имитировать опускание взгляда на панель управления, а для этого многовато 50 фреймов - вполне достаточно 30.
Нажимаем "Animate" при выбранной камере (а она будет выбрана по умолчанию при создании сцены из 3ds) и двигаем правую границу фреймов до фрейма 30. Да, вот так просто: промежуточный кейфрейм на таргете камеры, который был создан при импорте из 3ds, будет передвинут автоматически
на пересчитанную позицию). Я еще изменил положение этого кейфрейма с тем, чтобы несколько изменить движение камеры, избавить его от монотонности.
Кейфреймы в Swift своеобразные - "сдвоенные". Можно оттащить левую или правую "половинку" кейфрейма, и между "половинками" появится красная полоса - промежуток времени анимации, на котором объект "замрет на месте".

 Уменьшено: 76% от [ 1024 на 344 ] - нажмите для просмотра полного изображения

г) Отжимаем кнопку "Animate" и раскрашиваем "панель". В процессе раскраски познакомимся с библиотекой материалов, которая, конечно, существует скорее для ознакомления с возможностями и старта для редактирования/создания новых материалов, чем для использования.
Здесь интерфейс Swift3D тоже "радует" нестандартностью.
Во-первых, назначение материала из библиотеки объекту возможно двумя способами:
- или "перетащить" материал на объект, что даже при небольшом числе объектов чревато промахами
- или перетащить материал в окошечко сэмпла материала в свойствах объекта в левой панели.


Но для этого нужно сначала, разумеется, выбрать объект. Если он недоступен "мышью в окне" - можно открыть флоатер "Hierarchi" ("Иерархия"), в котором будут представлены объекты геометрии сцены, и где можно их выбрать.

Я выбрал темно-серый материал из вкладки "Metals", доредактировав - затемнив, - для основной "конструкции", темный серый металл из "Reflections" для угловых шариков и довольно долго подбирал золотистый и темно-серый материалы для кнопок и панели. Для кнопок "вправо-влево" я сначала выбрал "хромистый" reflection, но в процессе настройки оказалось, что лучше смотрится темный неблестящий металл.
Мелкие "заклепки" я перекрашивать не стал, ибо их цвет показался мне удовлетворительным, а работа по перекрашиванию для учебного материала - чрезмерной smile.gif

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

А вот прозрачные материалы пригодятся - тем более что они и в итоговой флэшке будут прозрачными, т.е. сквозь них будут "видны" не только части, отрендеренные в Swift, но и фон той флэшки, в которую мы все это импортируем. Так что выбираем голубоватое "стекло" из категории материалов "Transparent", донастраиваем его и присваиваем "экранчикам".


д) Изменяем Environment - окружение и занимаемся расстановкой и настройкой источников света.
Это самый долгий этап работы, поскольку настройка нужна довольно тонкая, а чтобы посмотреть результат - нам придется отрендерить один или два фрейма сцены.
- в меню свойств сцены/объектов выбираем Environment. По двойному щелчку на соответствующих полях будут вызваны диалоги выбора цвета для фона (мы выставим черный), для окружающего света - Ambient Light (мы выставим очень темный серо-синеватый) и собственно environment (это цвет, который будут "отражать" материалы "Reflection").
- делетируем две "лампочки", приехавшие к нам из 3D MAX - "разыскивать" их местопложение в сцене дольше, чем "нашлепать" новых. Удалить же просто: на правом "сером шаре" внизу выбираем желтые "шарики" - это и есть искомые "лампочки". Delete.
- Добавляем в сцену Targeted Omni Light - верхняя панель инструментов. Я, честно говоря, так и не обнаружил, чем он по световым качествам отличается от просто Omni, но найти в сцене "таргетед" проще.

 Уменьшено: 98% от [ 800 на 305 ] - нажмите для просмотра полного изображения

Плохие новости: в иерархии объектов сцены лайты не отображаются. Хорошие новости: зато они есть на "Light Ball"-е - том самом сером шаре внизу.
Световая модель не отличается особенной замысловатостью: затуханий нет (вернее, они все - по умолчанию, вшиты "раз навсегда"), градиентов, битовых карт и т.п. модификаторов - нет, и... ну, в общем-то - считай, ничего нет. Есть два вида источника - direct и omni, цвет (он же - интенсивность, черно/белой градацией цвета), галки "Active". "Shadows", "Specular". Все.

Периодически в процессе настройки света приходится делать пробный рендеринг, а заодно и посмотреть, что из всей нашей работы выходит.
Для этого переходим на вкладку "Preview and Export Editor" и выбираем тип рендеринга Vector. Дальше нужно установить параметры рендеринга:
- General: здесь выбираем "SWFT Importer" - файл будет рендерится в самый удобный для дальнейшей обработки формат swft, фильтр для импорта которого (из комплекта "Свифта") мы уже заботливо положили в подкаталог Importers каталога Flash MX; Separate Stationary And Moving Objects: Свифт умеет "раскладывать" по отдельным слоям движущиеся и неподвижные объекты. Нам это не нужно - у нас вся сцена двигается; остальное здесь устроит по умолчанию
- Fill Objects: "Fill" - галка, Fill type - "Area Gradient Shading", ибо на меньшее мы не согласны, а самый "навороченный" метод - Mesh Gradient - нам пока не нужен; включаем Specular, 5 и Shadows, и выключаем Reflections - пока по крайней мере.
- Edge Objects: по умолчанию рендеринг контуров отключен, и это хорошо - он нам и не нужен.
выбираем нужный фрейм Export Selected Frames

 Уменьшено: 61% от [ 1280 на 998 ] - нажмите для просмотра полного изображения

Я выбрал серовато-зеленый свет для подсветки "экранчика" вверху и основного "света" и синий для подсветки нижнего "экранчика".

В процессе настройки оказалось, что нужен еще серый для "заполнения" - вместо "выключенного" амбиента.

 Уменьшено: 98% от [ 800 на 297 ] - нажмите для просмотра полного изображения

 Уменьшено: 98% от [ 800 на 301 ] - нажмите для просмотра полного изображения

е) Еще один тестовый рендер выявляет маленькую, но неприятную проблему:

 Уменьшено: 68% от [ 1158 на 830 ] - нажмите для просмотра полного изображения

маленькие черные артефакты на трех видимых "шариках" не очень заметны сами по себе, но при анимировании они явно будут еще и "мерцать".
Причина их - неправильный рендер сферы, в которой изначально было мало полигонов, и неправильный параметр "сглаживание". Повернув "шарики" так, чтобы их "макушки" были "спрятаны" в основания цилиндров, и изменив значение "сглаживания" (в свойствах объекта - сняв галку "Autosmooth") на 5, удалось от этих мелких неприятностей избавиться.
Заодно я отрегулируем параметр smooth и для других объектов - главным образом это касается тех, которые получены MeshSmooth-ом в 3DMAX-е.


После экспериментов я поставил еще один Omni Light - темно-фиолетовый, "контровым" светом, и на "кнопочках" на панели засветились красноватые отблески.

 Уменьшено: 98% от [ 800 на 310 ] - нажмите для просмотра полного изображения

ж) На этом самый больошй этап - редактирование в Swift - закончен. Еще раз проверяем настройки рендеринга, делаем несколько пробных рендерингов, - первого кадра, последнего, откуда-нибудь из середины - а вдруг там рендерер выкинет неожиданный фокус и свет "прыгнет" слишком резко или тень появится "из ниоткуда"?...

 Уменьшено: 61% от [ 1280 на 1000 ] - нажмите для просмотра полного изображения

...нет, вроде не появился.

Export All Frames.
...и можно пойти перекурить, попить кофе... ибо 100 000 полигонов на 30 кадров для векторного рендера - не такая уж и слабая задача, а Swift - барышня капризная, не очень любит, когда его беспокоят переключениями активного окна, проверкой почты, шатаниям по форумам во время Рендеринга, может и подвиснуть, особенно если оперативки мало.

...и Ваш покорный слуга тоже отправляется на перекур, после чего мы непременно продолжим.

====================

3. Импорт в Flash и работа с swft-объектом в Flash.

а) Предварительные хлопоты.
- Открываем Flash, создаем новый Flash-документ, выставляем размеры 800x600, FPS 15 (sic!), ставим черный фон.
(я опущу создание хотя бы примитвного прелоадера и т.п. "обрамление")
- File -> Import to Library - > Формат SWFT Importer -> наш swft-файл.
- бросаем его в первый фрейм пока единственного слоя (можем его переименовать, напр., в "cab") основной сцены, выставляем координаты x=0, y=0
- заводим новый слой, называем его "as". Новый слой нужен во избежание случайного сдвига чего-либо при написании Action Script-ов
- в первом (собственно, все еще единственном) фрейме этого слоя - нажимаем F9, в открывшемся окне Actions пишем stop();
- еще раз нажимаем F9, чтобы закрыть Actions.
- любуемся нашим гравицаппьим пультом smile.gif Не удержавшись, нажимаем F12 - и смотрим, как "кивает головой" наша пока полуторамегабайтная "кабинка".
- даем экземпляру муви-клипа имя, напр., "cab".
- Заводим новый слой (над имеющимся), второй слой - который с "панелькой" - блокируем, чтобы не мешал работать, в новом слое рисуем прямоугольник в контуром толщиной 2 и цветом по вкусу (я взял темно-зеленый "пипеткой" с "панельки"), размер 800х600, ставим ему x=0, y=0. Называем слой "border", блокируем.

 Уменьшено: 76% от [ 1024 на 798 ] - нажмите для просмотра полного изображения

б) Забираемся в swft
- блокируем все слои, "отпираем" слой "cab", двойным щелчком забираемся "внутрь" мувика-swft...
Мувик этот устроен очень умно: в отдельных слоях лежат "colors" - непрозрачные объекты, тени, блики и прозрачные объекты. Если бы в сцене были неподвижные объекты - они бы тоже лежали отдельно. Можно попробовать "повыключать" отдельные слои, чтобы посмотреть, как смотрится анимация без теней или без бликов. В некоторых случаях (не в нашем) можно обойтись без одного из слоев или допарвить/нарисовать его "вручную" - для экономии "веса" конечной флэшки или достижения какого-либо особенного эффекта. Можно поменять прозрачность теней, непр., или, наоборот, сдублировать слой бликов, а то и поиграть с их цветом. Можно даже, набравшись терпения, превратить каждый кадр какого-либо слоя в муви-клип и применить фильтры.
Рендеринг, естественно, покадровый - он в данном случае и не может быть другим.
Кадров для нас и тут многовато. При 15-ти кадрах в секунду движение все еще замедленно, а "вес" при этом изряден - и, к чести Swifta, эффективной оптимизации практически не поддается - максимум 20% можно "выжать". Для сравнения: после импорта обысного векторного файла - ai, wmf - Shape Optimising-ом иногда выжимается до 80% "воды" - лишней информации.
Я решил кадры "проредить" - т.е. уничтожил через один.


в) Останавливаем "cab": в первом фрейме swft-шки (т.е. - не возвращаясь в основную сцену) пишем stop(); Больше он сам по себе кивать не будет - что мы незамедлительно проверим по F12.
Возвращаемся в основную сцену.
г) Делаем таймер-контроллер, по которому сможем все что хотим запускать:
Ctrl+F8, в открывшемся диалоге выбираем MovieClip, набираем имя - напр., ctrl, жмем ОК.
е) Создаем новый слой, называем его "Controller", в него (первый и по-прежнему единственный фрейм) кидаем из Library только что созданный нами ctrl. Даем ему имя экземпляра - "ctrl".
г) Переходим на слой "as", F9 -> и пишем окне Actions перед уже написанным stop(); :

function onMouseMove() {
if (_ymouse > 300) {
_root.ctrl.onEnterFrame = function () {
var f = _root.cab._currentframe;
if (f < 15) {
_root.cab.gotoAndStop(f+1);
} else {
_root.ctrl.onEnterFrame = function () {}
}

}
}
if (_ymouse 1) {
_root.cab.gotoAndStop(f-1);
} else {
_root.ctrl.onEnterFrame = function() {}
}
}
}
}
Mouse.addListener(this);

Я не буду сейчас останавливаться на ActionScript программировании, только скажу, что этот кусочек кода делает следующее: определяет, когда пользователь двинул мышь выше 300px по вертикали, а когда - ниже. В первом случае включается функция, которая c каждым кадром мувика ctrl заставляет переходить мувик cab на один фрейм назад, пока не будет достигнут первый фрейм мувика cab, во втором случае - в обратном направлении.

Дальше мы добавим кнопки.
Чтобы опять-таки не вдаваться в тему рисования и обскриптовывания красивых кнопочек в Flash, поскольку это не входит в тему урока, скажу только, в чем фокус именно в этом случае: во-первых, кнопочки рисуются на новом слое в самом мувике cab, а не в основной сцене, а во-вторы - они рисуются только в последнем фрейме. Поскольку пока на них не навели мышь - они абсолютно прозрачные, то этого никто и не заметит. И обработчики onRelease, onRollOver, onRollOut для них лучше писать в мувике, а не в основной сцене.

 Уменьшено: 93% от [ 843 на 716 ] - нажмите для просмотра полного изображения

А в первом фрейме нашей панельки можно "посадить" что-нибудь другое. В данном случае я в мувике cab завел новый слой и в первом его фрейме нарисовал "логотип мегакорпорации "Гравицаппа", потом скопировал этот "логотип" во второй фрейм, посмотрел, на каком фрейме верхний "экранчик" исчезает и до этого фрейма сделал банальный MotionTween - на 5 кадрах вряд ли кто-то заметит неуловимое несходство перспективных искажений логотипа и "верхнего экранчика". В первом же фрейме превратил этот логотип в муви-клип (по клавише F8) и сделал Motion Tween на несколько кадров - чтобы он и появлялся не скучно.

Немного фоновых звезд (новый слой, импорт картинки, картинку - на сцену в новый слой, превратить в MovieClip - F8 - и задать имя экземпляра - "stars1", в свойствах слоя я немного поиграл с режимами blending-а - благо Flash 8 на дворе... ) и маленький кусочек Flash-кода (в первом и навсегда единственном фрейме основной сцены, слой "as" -> F9), перед stop(); - останавливаем мы мувик в последнююю очередь:

_root.stars1.onEnterFrame = function() {
this._rotation++;
if (this._rotation==360) {
this._rotation=0;
}
}

...что означает "на каждом фрейме поворачивать на 1 градус,если градусов набралось 360 - обнулить (от греха переполнения).

Автором урока является Des.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=8699