Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ponimayka1

.pdf
Скачиваний:
131
Добавлен:
07.06.2015
Размер:
37.11 Mб
Скачать

Существует еще масса примеров использования expressions, не попадающих ни в один из двух перечисленных типов (например, Particle Expressions), однако я сосредоточусь именно на традиционном применении expressions, как одном из способов анимации атрибутов объекта.

Порядок создания expressions

Есть много способов создать expression для выбранного атрибута, однако на первых порах я советую придерживаться идеи о том, что expressions «висят» на атрибутах, подобно остальным типам анимации.

Поэтому, чтобы создать новый expression, надо сначала продумать, каким атрибутом (или атрибутами) объекта он будет управлять, затем выделить этот атрибут в Channel Box (или разыскать в Attribute Editor) и, нажав правую кнопку мыши, выбрать в контекстном меню пункт Expressions.

После этого появится специальное окно для работы с expressions, называемое, как ни странно, по-простому: Expression Editor. В центральное тестовое поле Expressions следует ввести текст магической формулы и нажать кнопку Create. Если формула на языке MEL введена без ошибок (с точки зрения MAYA, а не с вашей точки зрения), то expression будет успешно создан и кнопка Create превратится в кнопку Edit (это основной индикатор успеха). В противном случае MAYA бесстрастно ругнется, сообщая об ошибке (не прячьте Command Line с экрана!), а вы должны будете отыскать эту ошибку в написании своей формулы, исправить ее и снова нажать Create. И так далее.

Атрибуты, управляемые с помощью expressions, отображаются в Channel Box или Attribute Editor фиолетовым цветом. Чтобы «добраться» до этих expressions следует опять выделить нужные атрибуты в Channel Box и в контекстном меню выбрать пункт Expressions, открывающий Expression Editor с уже загруженными формулами.

Примечание. Один из моих самых любимых и быстрых способов созданий несложных expressions заключается в следующем. Отыскав нужный атрибут в Attribute Editor, следует ввести знак «равно» (=) в поле атрибута, а затем ввести текст формулы expression, после чего нажать Enter. Конечно в случае ошибки, придется набирать все заново, однако удовольствие наблюдать, как после ввода «=» внезапно разъезжается числовое поле атрибута, стоит того.

611

Синтаксис expressions

Основные правила синтаксиса для написания скриптов и expressions изложены в главе, посвященной MEL-программированию. Здесь я лишь сформулирую простейшие принципы составления expressions, позволяющие писать довольно эффективные формулы.

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

pTorus1.rotateX

Регистр букв исключительно важен. pTorus1 и PTorus1 - это разные объекты, а атрибута rotatex Maya по умолчанию не знает (вы можете сделать его сами).

Для ленивых пользователей были дополнительно придуманы короткие имена атрибутов, чтобы сэкономить силы при наборе формул на MEL. pTorus1.rotateX и pTorus1.rx - это один и тот же атрибут. Коротких имен для объектов, как ни прискорбно, не может быть в принципе.

Совет. П о с м о т р е т ь короткие имена атрибутов можно в Channel Box. Дли этого в контекстном меню достаточно выбрать Channel Names= >Short.

612

Также я советую раз и навсегда включить отображение длинных (Long) имен атрибутов в Channel Box. По непонятной мне причине, по умолчанию включен режим отображения «красивых» (Nice) имен, и это явно дезинформирует пользователя относительно правильного написания названий атрибутов. В этом режиме в именах атрибутов появляются пробелы и все имена начинаются с большой буквы, что не соответствует истине.

Зная имена атрибутов, вы можете складывать, вычитать, перемножать и делить значения этих атрибутов с помощью общепринятых знаков. Использование скобок и наиболее употребительных функций типа rand, noise, sin и cos не должно вызвать у вас затруднений. Нижеследующие примеры должны развеять страх перед написанием несложных формул.

Единственное, о чем стоит помнить всегда, это то, что в конце каждой строки, (а точнее в конце каждой MEL-команды) необходимо ставить точку с запятой.

pCube1.tx=(pTorus1.tx+ pTorus2.tx)/2; pCube1.tz=(pTorus1.tz+ pTorus2.tz)/2;

Если в одной строчке не помещается вся команда, можно без проблем перенести ее на другую строчку.

pCube1.ty=(pTorus1.ty+pTorus2.ty+pTorus3.ty

+pTorus4.ty+pTorus5.ty)/5.0;

Следует лишь помнить: точка с запятой отделяет одну команду от другой.

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

$rot = pCube1.ry/180*3.14; pCube2.ry = sin($rot);

Кроме того, специально для использования в expressions имеются две специальные переменные для работы со временем. Они называются time и frame и обозначают текущее время

всекундах и в кадрах, соответственно.

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

Прежде чем перейти к практическим примерам использования expressions, я немного остановлюсь на разнице между expressions и скриптами, о которых все, без сомнения, наслышаны. И те и другие пишутся на языке MEL, но служат несколько разным целям.

Разница между скриптами и expressions. Порядок выполнения expressions

Майский скрипт - это набор команд на языке MEL, который выполняется по вашему требованию, то есть когда вы сами его запустите. Хранится он, как правило, на диске в виде текстового файла и не является частью сцены.

Expression - это тоже набор команд. Но во-первых, эти команды хранятся в виде объекта и являются частью сцены, то есть хранятся внутри нее. А во-вторых, эти команды выполняются не по вашему желанию, а, вообще говоря, при смене номера кадра при анимации. Каждый раз, когда происходит переход к следующему кадру (или когда вы в очередной раз неловко ткнули мышкой в TimeLine), выполняются все незаблокированные expressions, присутствующие в сцене. Также выполнение expressions происходит с том случае, когда один из объектов, чьи атрибуты используются в expression, изменяет значение этих атрибутов.

Таким образом, если вы проиграли двести кадров анимации, все expressions, созданные

613

в сцене, выполнятся по двести раз. Поэтому expressions используются, как правило, не для интенсивных расчетов и вычислений, а для задания логических связей между объектами (точнее говоря, между атрибутами объектов).

Примеры использования expressions. Часы

Разберем пример использования expressions для «явной» анимации, то есть для установления прямой зависимости между атрибутом объекта и временем.

Изготовьте в новой сцене стрелку часов.

Расположите ее так, чтобы центр вращения находился в начале координат и вращение стрелки происходило вокруг оси Z.

Назовите стрелку sec, ибо она будет отсчитывать секунды. Если это слишком сложно или скучно, откройте файл clock.ma.

Выделите в Channel Box атрибут rotateZ и в контекстном меню выполните пункт Expres­ sions. В появившемся окне Expression Editor введите простую формулу

rz = time*6;

Нажмите кнопку Create.

Если в строке из десяти символов вы допустили ошибку, то кнопка Create не превратится в кнопку Edit, и вам придется хорошенько сосредоточиться, чтобы найти ошибку. В противном случае проиграйте анимацию и подумайте о сути формулы.

614

Переменная time содержит время в секундах для текущего кадра. Соответственно, через одну секунду после начала анимации (то есть в двадцать пятом кадре), значение time будет равно единице. За одну секунду секундная стрелка должна повернуться на шесть градусов (360 градусов разделить на 60 секунд равно 6). Поэтому, чтобы задать значение атрибута rotateZ в градусах, мы умножили время в секундах на 6.

Примечание. В данном случае имя объекта можно было не писать перед именем атрибута. Об этом я скажу чуть позже.

Очевидно, для того, чтобы стрелка поворачивалась в другую сторону, следует добавить знак минус. Кроме того, зададим «дискретное» вращение стрелки, чтобы она скачком поворачивалась в новое положение только в тех кадрах, где значение времени равно «целым» секундам. Очевидно для этого нужно взять целую часть числа, содержащего время в секундах, то есть целую часть переменной time.

Если вы закрыли Expression Editor, доберитесь до него снова, выделив rotateZ в Channel Box и вызвав пункт Expressions.

Примечание. Возможно, вы удивитесь, увидев, что ваша формула неузнаваемо изменилась. Если нет, нажмите кнопку Reload, и вы увидите, что MAYA автоматически преобразует короткие имена атрибутов в длинные и добавляет к ним имена соответствующих объектов. Для того, чтобы изменить такое поведение, необходимо исправить некоторое количество стандартных майских скриптов. Однако обсуждение этого процесса выходит за рамки данной главы.

Исправьте формулу следующим образом: sec.rotateZ = -int(time)*6;

Нажмите кнопку Edit.

Теперь стрелка вращается ежесекундными рывками.

Установите диапазон анимации в 90 ООО кадров - ведь если 3600 секунд (то бишь 1 час) умножить на 25 кадров, это аккурат 90 000 кадров.

В настройках анимации задайте Playback Speed=Real-time(25 fps), чтобы наблюдать реальное время на экране.

Запустите анимацию, посидите, отдохните, подумайте о вечном, глядя на кончик секундной стрелки...

Вернитесь в нулевой кадр и скопируйте объект sec, изготовив таким образом минутную стрелку. Назовите ее mtn и немного подредактируйте ее позицию и форму.

615

Минутная стрелка должна вращаться в 60 раз медленнее секундной. Поэтому expression для вращения будет вызывающе прост.

Выделите в Channel Box атрибут rotateZ и вызовите Expression Editor. Введите формулу:

min.rz=sec.rz/60; Нажмите Create.

«Повозите» мышкой по временной линейке, убедитесь, что стрелки вращаются согласованно. Сделайте еще одну стрелку, часовую.

Назовите ее hour.

Она должна вращаться в двенадцать раз медленнее минутной, поэтому expression для нее будет выглядеть следующим образом:

hour.rz=min.rz/12;

Теперь вы имеете процедурно анимированные часы. Скорость вращения соответствует сейчас реальному течению мирового времени. Однако для создания нереалистичных эффектов хотелось бы иметь атрибут, управляющий скоростью вращения стрелок. Коль скоро основной у нас является секундная стрелка, добавим атрибут к ней.

Выберите объект sec и выполните Modify=>Add Attribute.

Назовите новый атрибут speed, задайте Minimum=-10, Maximum=10, Default=1. Нажмите ОК.

Теперь снова выделите атрибут rotateZ в Channel Box и откройте Expression Editor. Исправьте формулу для секундной стрелки:

616

sec.rotateZ = -int(time)*6*sec.speed;

Запустите анимацию и попробуйте менять атрибут speed.

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

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

Для того, чтобы получить вконец обезумевшие часы и остаться в рамках процедурного подхода, выделите атрибут speed в Channel Box, вызовите Expression Editor и введите формулу:

sec.speed = noise(time)*10;

Это заставит меняться скорость вращения беспорядочным образом в диапазоне от 10 до минус 10. Если вы захотите замедлить (или ускорить) стремительность таких изменений, введите в формулу дополнительный коэффициент:

sec.speed = noise(time*0.5)*10;

Приручение Expression Editor

Некоторые из вас, наверное, уже столкнулись с некоторыми «бестактностями» в поведении Expression Editor. Если вы, печатая свою магическую формулу, вдруг решили на секундочку выбрать другой объект, чтобы, например, проверить значения его атрибутов, все ваши «печатные труды» тут же исчезнут! Чтобы сохранить свои нервы, напечатанный текст, а заодно призвать к порядку Expression Editor, следует знать о двух режимах работы с ним.

По умолчанию включен первый режим, когда в Expression Editor отображаются expres­ sions только для выбранного объекта. Поэтому при случайном щелчке мыши в окне камеры весь введенный текст пропадает.

Второй, более гуманный (на мой взгляд) режим, отображает в окне Expression Editor все имеющиеся в текущей сцене expressions.

Эти режимы переключаются в меню Expression Editor с помощью пунктов Select Filter=>By Object Name и Select Filter=>By Expression Name, соответственно.

Два этих режима отражают два идеологических подхода к expressions. Первый рассматривает expressions как, например, анимационные кривые, которые жестко закреплены за определенными атрибутами и рассматриваются только вместе с объектом. В этом режиме, чтобы увидеть код нужного expression, недостаточно выбрать объект: надо дополнительно в окне Expression Edi­ tor выбрать атрибут объекта, на который этот expression влияет. В этом режиме весьма полезно ограничить отображение в Expression Editor только тех атрибутов, для которых уже созданы expres­ sions. Это можно сделать в меню Expression Editor, выбрав Attribute Filter=>Connected to Expressions. Заметьте также, что в меню Object Filter также существуют разные варианты, «фильтрующие» отображение в списке Objects объектов тех или иных типов.

617

Здесь, наверное, стоит уточнить, что значит «expression влияет на атрибут». Неформально выражаясь, в этом случае expression «висит» на атрибуте. Формально говоря, в дереве зависимостей атрибут имеет входящую связь, приходящую к нему от expression. А с точки зрения написании формул это означает, что в коде expression встречается выражение типа "object.attr=..." в котором имя атрибута стоит в левой части оператора присваивания. Как вы понимаете, в одном expression может встречаться несколько таких выражений для разных атрибутов. Все они создают связь одного expression с этими атрибутами.

Второй режим идеологически предполагает, что вы рассматриваете expressions как самостоятельные объекты сцены, выполняющие определенные действия. В этом режиме вы можете видеть в верхней части окна Expression Editor список всех expressions, уже имеющихся в текущей сцене (включая предназначенные для частиц). Вы можете не бояться, что код expres­ sion пропадет при случайном выборе объекта и спокойно редактировать любой expression, просто выбирая его из списка. Не забывайте при этом нажимать кнопку Edit: она сохраняет результаты вашего редактирования, и ее действие аналогично традиционной операции Save. Кнопка Reload возвращает вас к последнему сохраненному варианту кода. Помните о том, что после того, как вы изменили код expression, ваша сцена изменилась, и ее нужно будет сохранить для сохранения нового варианта expression.

Лично мне ближе второй режим работы: как бывший программист, я оперирую с expres­ sions как с самостоятельными, а не с вспомогательными объектами. Однако с точки зрения общей идеологии MAYA, возможно, более последовательным будет использование первого режима.

Совет.

Если вы хотите избежать пропадания всего

набранного текста

expres­

sion при

случайной

смене

выбранного объекта,

тогда либо включите режим

Select

Filter->By

Expression Name, либо в меню Object Filter

выберите

любой

вариант,

кроме Selected Objects - например, Transforms. Сделайте

э т о

при

первом

же

открытии Expression Editor после запуска MAYA.

Если

вы

хотите

сделать

эти

режимы

задаваемыми по

умолчанию, сделайте

так,

чтобы

соответствующие

этим действиям

команды EEselectFilterCB

expression;

или

EEobjFilterCB

trans­

forms; выполнялись автоматически при открытии MAYA.

О том,

как это

сделать,

читайте

в главе,

посвященной MEL.

 

 

 

 

 

 

 

 

 

Заметьте также, что MAYA достаточно «интеллектуальна», чтобы отслеживать изменившиеся имена объектов. Если вы переименуете любой из объектов, «участвующих» в expression, то MAYA автоматически изменит текст этого expression, заменяя старое имя объекта на новое.

Совет. Если число expressions в вашей сцене превышает три, хорошо завести привычку переименовывать их сразу после успешного их создания. Это можно быстро сделать в Expression Editor. В имени expression можно отразить, что именно он делает и для чего предназначен. Позднее гораздо проще будет выбирать нужные expressions из списка, чем просматривать их все, пытаясь найти нужные команды.

Вы можете также обнаружить в Expression Editor загадочное поле Default Object, в котором, как правило, содержится имя выбранного объекта (особенно, если вы открываете Expression Editor через Channel Box). Это поле предназначено для суперленивых создателей expression и для тех, кто совершенно не умеет набирать тексты на клавиатуре. Для того объекта, чье имя содержится в этом поле, можно писать в тексте набираемого expression не полное имя атрибута, включающее имя объекта, а лишь имя самого атрибута. Например, если в поле Default Object содержится имя объекта pTorus1, вы можете написать просто:

ty = noise(time);

При этом после нажатия кнопки Edit MAYA сама добавит имя объекта к короткому имени атрибута и превратит этот текст в следующую формулу:

pTorus1.translateY = noise(time);

Также для ленивых (и любопытных) пользователей предназначено меню Insert Functions в окне Expression Editor. Оно позволяет вставлять имена различных полезных функций в то место

618

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

Кнопка Delete удаляет expression как объект сцены. Помните о том, что если вы выполняете операцию Break Connection в контекстном меню Channel Box, вы лишь разрываете связь между атрибутом объекта и expression, не удаляя последнего.

Примечание. Предположим, вы собираетесь

проанимировать два объекта с

помощью expressions.

 

Для этого вы можете создать один expression, в котором будет описана анимация обоих

объектов, например:

 

pTorus1.translateY = noise(time);

 

pCube1.translateY = sin(time);

 

Однако, если следовать по иному пути, а именно выделять атрибуты в Channel Box и

создавать индивидуальные expressions для каждого объекта,

вы можете получить два отдельных

expression, каждый из которых описывает анимацию только одного объекта. Какой способ лучше? С точки зрения производительности, наверное, первый, хотя вряд ли вам когда-нибудь удастся заметить разницу. Идеологически, возможно, корректнее второй способ, когда каждый объект, связан только со своей процедурной анимацией. Однако редактировать формулы будет быстрее и удобнее в общем expression, то есть первым способом. Таким образом, нельзя сказать, какой способ лучше это дело вкуса. Результат будет совершенно одинаковым в обоих случаях.

Примеры использования expressions. Телескопическая антенна

Разберем пример применения expressions для анимации различных «выдвигающихся» конструкций, типа телескопа. Использование expressions в этом случае едва ли не единственный способ решить поставленную задачу. Никакими констрейнами или операцией Set Driven Key не удастся добиться выполнения массы логических условий, типа «если одно звено выдвинулось на определенное расстояние, то вслед за ним начинает двигаться следующее звено». С помощью логических операторов языка MEL эти «вполне человеческие» требования легко программируются в виде expressions.

Итак, создайте в новой сцене два цилиндра и один локатор.

Поднимите локатор повыше, а один из цилиндров также приподнимите немного и сделайте его радиус немного поменьше другого (не меняя высоты цилиндра).

Самые ленивые пользователи могут открыть сцену telescope_start.ma.

Назовите локатор end, верхний цилиндр р1, нижний - р2. Помните, что MAYA чувствительна к маленьким и большим буквам.

619

Идея состоит в следующем: если верхний цилиндр (р1) в результате вертикального перемещения «высовывается» из нижнего (р2) полностью, нижний цилиндр должен последовать за верхним. Если же верхний цилиндр «входит» обратно в нижний, последний должен перестать двигаться. Представьте себе телескопическую антенну, и вы поймете, о чем идет речь.

Напишем expression для нижнего (подчиненного) цилиндра. Выберите р2 и откройте Expression Editor.

Введите следующий текст:

Нажмите Create и сразу установите в меню Expression Editor режим Select Filter=>By Ex­ pression Name.

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

В скобках стоит логическое выражение, а все, что идет после скобок, относится к тому случаю, когда это выражение логически выполняется.

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

Поэтому для улучшения читаемости нажмите Reload и исправьте текст следующим обоазом.

Некоторые из вас, наверное, заметили, что MAYA самостоятельно «перегрузила» наш ex­ pression в «длинную» форму. Меня такое поведение регулярно бесит, однако что поделаешь - пока что приходится мириться с этакой бестактностью.

Перемещайте верхний цилиндр по вертикали.

Теперь нижний следует за ним, если расстояние между цилиндрами превышает 2. Однако это работает лишь при движении цилиндра р1 вверх. Добавим в наш expression еще одну строку:

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

Не забывайте нажимать кнопку Edit после каждого исправления текста!

Примечание. Взрослые мальчики, конечно, могут тут

же

начать

оптимизировать

код с

помощью функций

abs() (абсолютная

величина)

или

sign()

( з н а к выражения),

однако

«читабельность»

команд от этого

испортится,

а оптимизация коснется

только количества знаков в тексте.

Теперь нижний цилиндр послушно следует за верхним и вниз и вверх.

В принципе, задача решена и пытливые умы быстро сообразят, как написать дополнительные expressions для добавочных цилиндров. Я лишь добавлю «марафет» и прокомментирую некоторые моменты.

Высота обоих цилиндров равна двум. Отсюда и взялось число 2 в наших формулах. Если цилиндры отмасштабировать, приведенные формулы перестанут правильно работать. Отредактируем их так, чтобы они отражали масштаб цилиндров по вертикали:

620

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]