Анимация падающего домино в Maya
Анимация падающего домино в Maya
Меня зовут Тодоров Дмитрий, я учусь на втором курсе МатМеха СПбГУ.
Каждый, наверное, хотя бы раз в жизни видел какой-нибудь рекламный ролик, в котором бы одна за другой падали бы сотни поставленных стоймя доминошек. Сделать это не совсем просто, но ничего суперсложного в этом также нет. От читателя потребуется знание основ майи(включая основы динамики твёрдых тел). Я использовал Maya 8.5 unlimited для подготовки урока.
Шаг 1. Подготовка.
Создайте кубик и плоскость с минимальным количеством сегмента. Плоскость будет полом, поэтому сделайте её достаточно большой, чтобы на ней потом всё поместилось. Кубик отмасштабируйте так, чтобы он стал похож на доминошку.
Допуская вольность по отношениям к правилам перевода и правилам русского языка, я буду называть его прокси. Он будет в дальнейшем использоваться для просчёта вместо реальной модели, которую можно сделать весьма тяжеловесной, главное, чтобы её форма была похожа на форму прокси. Заняться её созданием лучше уже самом конце, в Шаге 6.
Шаг 2. Создание путей.
Создайте текст со шрифтом Comic Sans MS (Create->Text) и поверните его так, чтобы он был строго параллелен полу.
Можно использовать любой шрифт, но у этого меньше острых краёв. После создания текста, отредактируйте его кривые так, чтобы острых углов не было совсем.
Если этого не сделать или сгладить углы слишком слабо, то потом может получиться так, что на изломе падение доминошек прервётся.
Шаг 3. Размещение проксей по путям.
Это можно сделать руками, с помощью стандартных средств(Motion Path + Create Animation Snapshot) или скриптом. Первый способ занимает слишком много времени, второй – творит прямо-таки аномальные вещи с атрибутами объекта, связанными с движением(translate, rotate, глобальные и локальные пивоты и т.д.). Третий способ проще -шil, требует меньше работы руками, надёжнее и позволяет работать с иерархией(хотя в нашем случае это не актуально). Любым способом запустите скрипт(самый простой – скопировать его текст в Script Editor, запустить его, а потом вызвать функцию FEDominoHelper ()).
global proc FEDominoHelper()
{
window -h 100 -title FEDominoHelper;
gridLayout -numberOfColumns 2 -cellWidth 220;
button -aop true -label "Distribute Object Copies Along Path" -c FEDistributeAlongPath;
textField -tx 0.138386 Dist;
button -aop true -label "Replace Proxies With Geometry Instances" -c ProxyReplace;
showWindow;
}
proc ProxyReplace()
{
// Сохраняем выделение
$sel = `ls -sl`;
// Первый выделенный объект - то, на что будем заменять
$objectName = $sel[0];
// Скопируем его, чтобы не трогать оригинал
$tmpsel = `duplicate $objectName`;
$objectName = $tmpsel[0];
// Выбираем shape
select $objectName;
pickWalk -d down;
$tmpsel = `ls -sl`;
$objectShape = $tmpsel[0];
for($i = 1; $i < size($sel); $i++)
{
// Выбираем shape и удаляем её
select $sel[$i];
pickWalk -d down;
delete;
// Приделываем shape приделывем её к анимированному transform nod'у
parent -add -shape $objectShape $sel[$i];
}
delete $objectName;
}
//////////////////////////////// FEDistributeAlongPath
global proc FEDistributeAlongPath()
{
// Узнаюм расстояние
$dist = (float)`textField -q -tx Dist`;
$sel = `ls -sl`;
$count = size($sel);
// Цикл по кривым
for($ii = 1; $ii < $count; $ii++)
{
// Копируем объект
duplicate $sel[0];
$tmp = `ls -sl`;
$objToDistribute = $tmp[0];
// Вычисляем длину кривой и количество объектов на пути
$len = `arclen $sel[$ii]`;
$end= (int) ($len / $dist);
// Создаём Motion Path с стартом в 1 кадре и концом в кадре с номером, равным количеству копий
select $objToDistribute $sel[$ii];
pathAnimation -fractionMode true -follow true -followAxis z -upAxis y -worldUpType "vector" -worldUpVector 0 1 0 -inverseUp false -inverseFront false -bank false -startTimeU 1 -endTimeU $end;
// На каждом кадре копируем объект
for($i=2; $i <= $end; $i++)
{
select $objToDistribute;
currentTime -update true $i;
duplicate;
};
delete $objToDistribute;
}
currentTime -update true 1;
}
Выделите сначала прокси, а потом одну кривую. Введите в единственное поле ввода расстояние по кривой между соседними проксями(его нужно просто подобрать) и жмите Distribute Object Copies Along Path. Теперь выделите прокси и все остальные кривые и опять нажмите на ту же кнопку(не нужно выбирать сразу все кривые т.к. Undo будет работать лишь для первой, что неудобно при подборе расстояния). Вторая кнопка нам понадобиться позднее.
Если кривые были опущены слишком низко, то прокси могут пройти сквозь пол – в этом случае поднимите их. Поднимите и поверните по одному прокси от каждой кривой так чтобы они в дальнейшем вызвали падение следующих(можно конечно, вводить значения моментов вращения и импульсов вручную, но я так предпочитаю, чтобы всё было наглядно).
Удостоверьтесь, что прокси между собой и с полом не пересекаются.
Шаг 4. Симуляция.
В Maya.
Выберите все прокси и сделайте их активными твёрдыми телами. Пол сделайте пассивным твёрдым телом. При выбранных проксях создайте поле гравитации. Попробуйте просимулировать. Если Вы симулируете несколько букв одновременно и видно, что прокси одной из них явно не будут пересекать проксей другой, то сделайте им разные значения Collision Layer – это ускорит вычисления. Если падать начинает не то, что надо, уменьшите Collision Tolerance и, возможно, Step Size в параметрах Rigid Solver’а. Потом подберите подходящие значения для силы гравитации и для атрибутов mass(масса), Dumping(скорость затухания импульса) и Bounciness(способность отскакивать) твёрдых тел. Потом включите кэш в параметрах Rigid Solver’а и просимулируйте до конца. После запеките ключи в анимацию. Для этого выберите пункт меню Edit->Keys->Bake Simulation, поставьте всё так, как на скриншоте и выберите атрибуты движения, вращения и масштаба в Channel Box’е. Теперь жмите Bake.
Симуляция готова и запечена, можно удалить гравитацию и твёрдые тела (выберите пол и прокси, потом Edit->Delete By Type->Rigid Bodies).
В Real Flow.
Выберите все прокси и пол и триангулируйте их (Mesh->Triangulate), иначе RealFlow не сможет их импортировать.
Сделайте так, чтобы панель time range отображала лишь два кадра (чем их больше, тем больше лишней информации экспортируется)
Не снимая выделения, экспортируйте(File->Export Selection) в формате sd. Если его нету в списке, то или у Вас не установлены коннекторы, или не загружен соответствующий плагин (тогда выберите пункт меню Window->Settings\Preferences->Plug-in Manager и поставьте галочку loaded для sdTranslator.mll).
Откройте Real Flow (я использовал версию 4.2.3.0102) и импортируйте созданный sd файл. Удалите камеру, чтобы не мешалась под ногами, прокси и пол сделайте твёрдыми телами (Node Params->Node->Dynamics = Rigid Body). Пол сделайте пассивным(Node Params->Rigid Body->Dyn Motion = No), а прокси – движимыми (Node Params->Rigid Body->Dyn Motion = Yes).
Выберите пункт меню File->Preferences, зайдите на вкладку Simulation, включите Stacking и поставьте Stacking Quality = 10 – это упростит задачу импорта симуляции в майю.
Добавьте гравитацию(Add new daemon to scene->Gravity).
Сделайте для пола примитив просчёта(Node Params->Rigid Body->Primitive) - Plane, А для проксей – Box. Это значительно быстрее по сравнению с остальными вариантами, но подходит лишь в случае простых объектов. На самом деле можно было экспортировать в Real Flow сразу модели доминошек и тоже поставить им примитив просчёта кубик, но иногда это работает не совсем верно, так что лучше называть кубиками лишь настоящие кубики. Сделайте плоскость невидимой (Node Params->Display->Visible = No), чтобы потом случайно не выделить её.
Просимулируйте до кадра, на котором прокси уже упали на пол и устоялись на нём, но ещё не начали валиться. Сделайте те прокси, до которых падение доберётся не скоро и выключите их из симуляции (Node Params->Node->Simulation = Inactive) – это тоже ускорит просчёт.
Также, если Вы хотите, чтобы падало всё лишь в одном направлении, сделайте прокси, ближайший «сзади» к повёрнутому прокси, недвижимым (Node Params->Rigid Body->Dyn Motion = No).
Не забывайте потом, когда падение подберётся достаточно близко, делать соответствующие прокси симулируемыми и движимыми. Симулируйте дальше, когда увидите, что часть проксей более-менее улеглась и шевелиться очень слабо и не затронута падениями следующих проксей, выключите их из симуляции их всех, кроме нескольких, ближайших к ещё не улёгшимся проксям – их сделайте лишь недвижимыми(иначе могут произойти пересечение уже неактивных и ещё не улёгшихся). Мелкие движения сильно замедляют просчёт.
Если в процессе симуляции Вы видите, что есть небольшие пересечения, то можно увеличить количество Min Substeps в опциях симуляции, но это имеет смысл лишь если Вы будете рендерить доминошки вблизи. Никогда не двигайте объекты, на которых есть хотя бы одни кадр симуляции – это может привести к очень странным результатам.
Когда просимулируете до нужного состояния, экспортируйте всё (Export->Export All) и импортируйте в майю файл animation.sd, лежащий в папке objects в папке с созданного в Real Flow проекта.
Шаг 5. Доводка ключей.
Сначала выделите пол и все прокси, потом квадрангулируйте их и очистите историю.
Узнайте, на каком кадре прокси встают на пол, но ещё не начинают валиться. Выберите все прокси и откройте dope sheet (Window->Animation Editors->Dope Sheet). Выберите все ключи до этого кадра (для этого не обязательно прокручивать вниз большой список проксей, достаточно выделить чёрную полоску на линии Dope Sheet Summary) и удалите их.
Потом выберите все оставшиеся ключи и введите в левое поле Stats строку -=<номер кадра>, опуская угловые кавычки. Нажмите enter и все ключи сдвинутся на нужное число кадров назад (такой фокус можно проделывать с половиной полей ввода в майе, кроме оператора -= есть ещё +=, *=, /=).
Можете при желании удалить ключи после стабилизации лежачего положения проксей, чтобы убрать малые шевеления. Можно передвинуть и растянуть ключи так, чтобы анимация по всем кривым начиналась и оканчивалась в одно и тоже время и т.д.
Шаг 6. Замена проксей на модели доминошек.
ыделите любой прокси, скопируйте (не Duplicate Special, а простой Duplicate). Сделайте из него модель доминошки, не трогая угловых вершин. Это на самом деле не обязательно, но помогает понять, где они будут после замены проксей на геометрию доминошек. Если Вы хотите наложить на неё текстуры – делайте это сейчас.
Теперь сначала выберите модель доминошки, а потом все прокси, запустите скрипт и нажмите вторую кнопку. Скрипт заменяет shape прокси на shape доминошки - В результате окажется, что на месте каждого прокси появился анимированный instance геометрии доминошки (в частности, это означает, что нельзя использовать скрипт во второй раз, чтобы заменить уже заменённые однажды доминошки, нужно вернуться к тому месту, где были прокси и заменять их).
Вот и всё, теперь осталось лишь назначить материалы и рендерить!