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

ponimayka1

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

так, что в некоторый момент он станет равным нулю, шляпа в этот момент «оцепится» от руки и останется на месте. Иногда удобно точно задавать положение объекта, в которое он вернется, когда веса всех влияющих на него объектов станут равными нулю. Такое положение называется «исходной позицией» (Rest Position). Координаты такого положения задаются атрибутами Rest Po­ sition, которые можно разыскать в Attribute Editor. Кроме того, если атрибут Enable Rest Position включен, объект будет возвращаться в исходную позицию при обнулении весов всех влияющих на него объектов; в противном же случае он просто будет замирать на месте в тот момент, когда веса приняли нулевое значение.

Примечание. Все

сказанное

справедливо и

для

констрейнов, ограничивающих

вращение объекта.

В этом

случае под

Rest

Position понимается «исходная

ориентация-.

 

 

 

 

Обнуление весов всех управляющих объектов не «выключает» выполнения работы констрейна, а лишь изменяет его способ воздействия на объект. Если вы хотите совсем выключить констрейн и избавить MAYA от необходимости все время вычислять позицию управляемого объекта, то заблокируйте его, установив в Attribute Editor значение атрибута Node State=Blocking.

Примечание. Вы также можете одним махом заблокировать (или разблокировать) работу всех констрейнов в сцене, выполнив: Modify=>Evaluate Nodes=>Constraints.

Констрейны как потенциальный источник циклов в дереве зависимостей

Некоторые из пытливых умов (особенно любители динамики) наверняка сталкивались с истеричными сообщениями MAYA о загадочных циклах.

//Warning: Cycle on 'pCube2.rotate' may not evaluate as expected.

//(Use 'cycleCheck -e o f f to disable this warning.) //

Именно о них сейчас и пойдет речь. Проведите следующий простой эксперимент.

Создайте сферу и цилиндр.

Выберите сферу, затем цилиндр и создайте Point Constraint, привязывающий цилиндр к

сфере.

А теперь выполните операцию Edit=>Parent.

Коль скоро цилиндр был выбран вторым, он становится «родителем» сферы.

Теперь попробуйте перемещать сферу. Впечатляет?

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

При этом MAYA проявляет завидное терпение и старается не «упасть» от таких циклических издевательств; она даже сообщает о наличии циклов в сцене с помощью замечания в Script Edi­ tor:

// Warning: Cycle on 'pCylinder1_pointConstraint1 .target[0].targetParentMatrix' may not evaluate as expected. (Use 'cycleCheck -e o f f to disable this warning.) //

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

601

такого сообщения в Script Editor при работе с констрейнами сразу проверьте взаимодействия между объектами и логику влияния объектов друг на друга. Объект, указанный в сообщении, помогает понять, в каком месте возник цикл.

И только в одном случае не стоит паниковать при появлении такого сообщения. При использовании динамики твердых тел, после возвращения в первый кадр, MAYA весело сообщает о наличии циклов. Не пугайтесь: так устроена динамика, а точнее - начальное положение твердого тела. В этом случае можете просто игнорировать сообщение о циклах.

Пример использования констрейнов. Конструирование карданной передачи

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

Данный пример описывает «инженерный» подход к работе с констрейнами (его любезно предоставил Володя Забелин). Использование констрейнов в данном случае весьма нетривиально, но является практически единственным способом решить поставленную задачу. Не верите? Тогда попробуйте решить ее по-другому.

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

Откройте с диска сцену kardan01.ma. (Если вы «сняли» эту книжку в Интернете и у вас нет диска, сделайте подобную конструкцию с помощью некоторого количества цилиндров).

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

Прежде всего, стоит соединить оба вала в центре с помощью Point Constraint. Нетрудно заметить, что пивоты обоих валов находятся в начале координат. Это сделано для того, чтобы обеспечивать их корректную ориентацию друг относительно друга.

602

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

Не забывайте про Undo.

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

Создайте два локатора (Create=>Locator).

Растащите их в стороны по оси X, чтобы они располагались позади валов. Назовите один их них LocRed, а второй LocBlue.

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

ив первой закладке (можно и во второй) найти раздел Display=>Drawing Overrides.

Внем следует включить галку Enable Overrides и с помощью слайдера Color выбрать нужный

цвет.

Далее я буду ссылаться на красный локатор (LocRed) и синий локатор (LocBlue). Сориентируем оба вала, так чтобы они смотрели своей продольной осью на локаторы.

603

Выберите красный локатор, затем красный вал. Выполните Constraint Aim.

Сдвиньте локатор вверх и убедитесь, что вал «смотрит» на него своей продольной осью. (Неплохо также помнить, что продольная ось - это локальная ось X для вала).

Теперь выберите синий локатор, затем синий вал. Выполните Constrain=>Aim.

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

Это связано с тем, что локальная ось X (используемая по умолчанию для задания направления внутри объекта, «которым» надо смотреть на цель) для синего вала направлена в стороны «скобы», а не в сторону шестеренки. Вместо того, чтобы разворачивать локальную ось, отредактируем атрибуты созданного констрейна.

Выберите синий вал, откройте Attribute Editor.

Перейдите в закладку VAL2_aimConstraint1 и в разделе Aim Constrain Attributes задайте Aim Vector =(-1, 0, 0).

Это означает, что синий вал должен смотреть на цель (aim) направлением, противоположным локальной оси X.

После этого синий вал развернется к своему локатору шестеренкой.

Сдвиньте синий локатор вверх и убедитесь, что вал «смотрит» на него своей продольной

осью.

Сохраните сцену (kardanfJ2.ma).

604

После того, как мы развернули оба вала с помощью констрейнов, может возникнуть резонный вопрос, а как будет крутиться красный вал, если на атрибутах вращений у него «висит» Aim-констрейн? И как он будет передавать свое вращение синему валу, если вращения последнего тоже зависят от Aim-констрейна?

Будем решать проблемы по порядку. Красный вал «следит» за своим локатором с помощью поворотов вокруг локальных осей Y и Z, а вращение вокруг продольной оси X определяет лишь его поворот вокруг направления слежения. Никто не мешает нам разорвать связь между констрейном и атрибутом rotateX для красного вала. Это можно сделать вручную (такой способ нравится мне гораздо больше, как олицетворение демократических свобод при работе с MAYA) или «официально», через меню.

Через меню это можно сделать следующим образом:

Выберите красный вал и выполните Constrain=>Modify Constrained Axis...

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

Снимите галку с оси X и нажмите Apply.

Убедитесь, что на атрибуте rotateX красного вала никто не «висит»: его цвет в Channel Box или Attribute Editor должен быть белым.

Примечание. Такой способ опасен тем, что если на выбранном объекте «висят» несколько констрейнов, такая операция разорвет связь не только для атрибутов rotate, но для остальных (translate или scale). Для того, чтобы «отцепить» конкретный констрейн от какого-либо атрибута таким способом, надо предварительно выбирать сам констрейн, а не объект. Это не всегда удобно.

Вручную «отцепить» констрейн от любого атрибута можно гораздо быстрее. Выберите красный вал. Нажмите Undo, если вы только что разорвали связь между констрейном и атрибутом rotateX. Затем в Attribute Editor, в первой закладке, нажмите правую кнопку мыши над атрибутом rotateX и в появившемся меню выберите Break Connection (разорвать связь).

605

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

В Attribute Editor впишите в клетку для rotateX следующую формулу: =frame*3

и нажмите Enter.

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

Займемся теперь передачей вращения от красного к синему валу. Воспользуемся тем, что для Aim Constraint можно задавать не только вектор «прицеливания», но и направление «вверх», вдоль которого должна смотреть одна из «поперечных» осей синего вала.

Идея проста: если продольная ось X синего вала смотрит в центр красного вала, то поперечная ось (например, Y) должна смотреть на отверстие в скобе красного вала.

Выберите синий вал, разыщите Attribute Editor закладку VAL2_aimConstraint1.

Вместо ориентации «наверх» выберите разворот в сторону дополнительного объект, установив World Up Type=Object Up.

Далее возникает вопрос, а в сторону какого объекта разворачивать поперечную ось Y синего вала? Быстро создаем локатор и помещаем его в центр отверстия на скобе красного вала.

606

Назовите этот локатор UpLoc.

Затем выберите снова синий вал и в закладке VAL2_aimConstraint1 впишите в поле World Up Object строку UpLoc.

Теперь синий вал развернется своей «поперечной» осью Y в направлении локатора Up­ Loc. Чтобы убедиться в этом окончательно, а заодно заставить локатор UpLoc вращаться вместе с красным валом, перетащите этот локатор в Outliner средней кнопкой мыши и «бросьте» его на красный вал VAL1.

Это сделает красный вал «родителем» для локатора UpLoc.

607

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

Сохраните сцену (kardan03.ma).

Первое, что нужно сделать, это прибить крестовину к центру соединения, а точнее к красному валу с помощью Point Constrain.

Выберите красный вал, затем крестовину и выполните Constrain=>Point.

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

Локатор в отверстии скобы красного вала уже имеется, поэтому выберите его (UpLoc), затем крестовину и выполните Constrain=>Aim.

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

Выберите крестовину.

В Attribute Editor, в закладке krestovina_aimConstraint1, задайте Aim Vector = (0, 0, 1), чтобы крестовина развернулась с сторону локатора UpLoc своей локальной осью Z.

Для разворота второй оси крестовины, воспользуемся тем же трюком, что и для ориентации синего вала. Создайте еще один локатор. Назовите его DownLoc. Переместите его в центр отверстия скобы синего локатора.

608

Не забудьте также -припарентить- его к синему валу, перетащив его средней кнопкой мыши в нужное место в Outliner.

Выберите крестовину, в Attribute Editor перейдите в закладку VAL2_aimConstraint1 и сначала измените тип ориентации Word Up Type=Object Up.

Впишите имя DownLoc в поле World Up Object.

После этого крестовина развернется своей второй осью - локальной осью Y, указанной в атрибуте Up Vector как (0,1,0) - в сторону локатора DownLoc.

Проиграйте анимацию. Измените взаимное расположение локаторов. Сохраните сцену как kardanFinal.ma.

Подумайте: как бы вы смогли выкрутиться в данной ситуации без помощи констрейнов?..

609

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

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

для expression

термин «выражение».

Тем более, что в

русскоязычной майской среде никто

и никогда так

не говорит, а если вы

вдруг заявите, что

заставили своего персонажа работать

с помощью «выражений», то окружающие подумают в первую очередь о крепких выражениях.

... Устная майская традиция предполагает употребление термина «экспрешен», обеспечивая стопроцентную однозначность трактовки. Я же ограничусь непереведенным написанием «expres­ s i o n » (так же, как loft или trim), предполагая, что произносить вы его будете, как положено, так что все вас поймут при общении.

Формулы для expression пишутся на языке MEL. Вы можете прочитать обсуждение синтаксиса и правил написания кода на MEL в соответствующей главе. В этом же разделе я сосредоточусь на практическом аспекте использования различных expressions и возможных вариантах их применения. А также на том, каким образом они взаимодействуют с объектом. Дополнительную информацию о «внутренностях» expressions и об их реализации в дереве зависимостей майской сцены вы можете почерпнуть из главы про изнанку MAYA.

Напомню: главная концепция анимации в MAYA основана на том, что анимируются не сами объекты, а их атрибуты. Поэтому среди прочих связей на атрибутах объекта могут «висеть» ex­ pressions, определяющие процедурную анимацию объекта.

Среди всевозможных вариантов использования expressions можно выделить два основных типа. К первому относятся expressions, связывающие атрибуты объекта со временем. Например: pTorus1.rotateX=noise(time)

Такие expressions - явные «посредники» между временем и атрибутами объекта, задавая вместо анимационной кривой формулу, по которой будет меняться тот или иной атрибут. Такие формулы задают «бесконечное» движение и применяются в тех случаях, когда не обязательно устанавливать точное состояние объекта в определенном кадре, а надо лишь задать характер или тип движения. Например «хаотическая тряска» или «движение по спирали». Задавать беспорядочное движение в диапазоне из пятисот кадров с помощью сотни-другой ключей - занятие довольно утомительное, а вот посредством expressions такая задача решается моментально.

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

Второй тип expressions задает связь атрибутов объекта не со временем, а с атрибутами других объектов. Например:

pTorus1.rotateX = pTorus1.translateZ * 180/3.1415926/(polyTorus1.radius + polyTorus1.sectionRadius);

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

610

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