3d max анимация персонажа кости

Создание и настройка скелета для анимации персонажа

В этом уроке я подробно расскажу, как правильно построить и настроить скелет. Мы рассмотрим детали этого, казалось бы, простого процесса и научимся пользоваться основными инструментами. Полученный скелет можно будет использовать для дальнейшего процесса рига или для иных целей. Так же, всё, что тут описано, являются необходимыми условиями для моего скрипта авторига (скрипт авторига гуманоидоподобных существ. Подробнее в документации скрипта). Но они при этом весьма стандартны и подойдут для других ваших целей. Все этапы снабжены сценами *.mb из maya 8.5. Так что, если вы потеряетесь, то всегда сможете свериться с ними.

Что в этом уроке:

Для кого этот урок:

Начало. (Файл start.mb)

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

3d max анимация персонажа кости

Итак, наш персонаж. Модель расположена в начале координат, направлена по оси Z. Руки и ноги немного согнуты – это необходимо для корректного задания направления для ikHandle. Либо, если конечности совершенно прямые, вам будет необходимо задавать направления вручную.

3d max анимация персонажа кости

Начнём строить скелет. Что нужно помнить:

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

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

3d max анимация персонажа кости

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

3d max анимация персонажа кости

Построили суставы в середине, теперь переходим к рукам.

3d max анимация персонажа кости

Строим сустав ключицы. Ключица выполняет важную роль – попробуйте ссутулить плечи или распрямить их, поднять руки вверх. Ключица будет работать почти во всех движениях руки. Так что не забывайте об этой важной кости. (Конечно, вам не нужна ключица для анимации персонажей комикса xkcd. )

Так же не забываем, что в окне перспективы можно войти в режиме wireframe или X-ray для того, чтобы рассмотреть со всех сторон сустав и массы персонажа. Это поможет вам поместить сустав на его место. Сустав плеча старайтесь расположить в центре массы плеча персонажа. Сустав локтя располагаем точно посередине лупов для сгиба.

3d max анимация персонажа кости

3d max анимация персонажа кости

Идём дальше. Строим суставы для пальцев. В середине ладони расположим сустав, от которого будут идти суставы пальцев. Первыми стройте суставы того пальца, который находится на одной линии с рукой. В данном случае это средний палец. Видите, у нас получилась почти прямая линия из суставов. Теперь можно взять основание среднего пальца и скопировать нужное число раз (ctrl+D). Суставы кончиков пальцев можно расположить, используя привязку к вершинам.

3d max анимация персонажа кости

Суставы большого пальца можно отпарентить от общего основания и припарентить к суставу кисти (выбираем основание большого пальца – Unparent, добавляем к выделению сустав кисти – Parent).

3d max анимация персонажа кости

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

Итак, мы построили половину скелета. (Файл half_skelet.mb).

Если включить отображение локальных осей, то можно увидеть, что мы имеем хаотично ориентированные суставы. Исправить это можно при помощи замечательного скрипта от Comet-a. Найти можно тут: http://comet-cartoons.com/maya.html

3d max анимация персонажа кости

Но сначала самое главное – нам нужно тщательно переименовать все суставы. ВСЕ суставы, ВСЕ объекты рига, да и вообще все объекты сцены должны иметь уникальные вменяемые имена. Если это левый сустав бедра, то так и пишем “L_hip_jnt”. Никаких joint125 или sphere67.

— вы легко ориентируетесь в объектах

— вы можете писать скрипты, работающие с объектами определённым образом. У вас не будет ситуации, когда в одной иерархии будет несколько объектов с одинаковыми именами.

— соответственно, сторонние скрипты работают корректно

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

Схема того, что должно у вас получиться:

3d max анимация персонажа кости

Мой скрипт поддерживает персонажей с такой иерархией суставов (ну ещё можно добавить хвост). Поэтому, если вы будете им пользоваться, то проверьте скелет персонажа.

Переименованный скелет можно посмотреть тут: (Файл half_renamed.mb).

Теперь можно заняться ориентацией суставов.

3d max анимация персонажа кости

3d max анимация персонажа кости

Для начала отпарентим бедро и ключицу от центрального скелета. Выберем первый сустав спины и выделим всю иерархию (select hierarcy). Запустим скрипт.

World Up Dir задаёт вектор на который будут ориентироваться локальные оси объектов.

Aim Axis – та локальная ось, которая будет смотреть на потомка.

Up Axis – та локальная ось, которая смотрит в направлении World Up Dir.

3d max анимация персонажа кости

Aim Axis у нас всегда X. World Up Dir выставляем так, чтобы все суставы смогли ориентироваться этому направлению уменьшая хаотичность результата. Например, сейчас мы хотим, чтобы локальная ось Z стремилась в направлении World Up Dir. Если мы выберем ось Z в качестве World Up Dir, то в данном примере всё будет хорошо, но если у вашей модели позвоночник сильно перекручен в плоскости YZ? По этой же причине мы не выбираем ось Y. Выберем ту ось, по которой меньше всего деформаций – ось X. И все суставы своими осями Z могут единообразно стремится в этом направлении.

3d max анимация персонажа кости

3d max анимация персонажа кости

Скрипт позволяет вручную редактировать локальные оси. Для этого в окне Tweak наберите небольшое значение (например, 5 градусов) для нужной оси (направляющая у нас всегда X поэтому пишем в первом прямоугольничке «5»). Выделяем нужный сустав и жмём на «Manual+» или «Manual-«.

Сейчас мы редактируем то, как будут гнуться суставы. Согните у себя на руке палец и представьте, что будет, если бы какой-то нерадивый вдруг сделал так, что палец теперь гнётся куда-то в бок, а не внутрь ладони. Вам бы не хотелось, правда? Поэтому повертите суставы по осям – посмотрите, туда ли они гнутся. Если нет, подправьте. Главное, не забудьте обнулить вращение, перед тем, как редактировать локальные оси.

3d max анимация персонажа кости

Аналогично я повернул немного оси на суставах пальцев.

Teперь настраиваем суставы ног.

3d max анимация персонажа кости

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

3d max анимация персонажа кости

3d max анимация персонажа кости

Этот шаг не совсем обязательный но … Мы могли в самом начале выбирать не первый сустав спины, а базовый сустав. Тогда бы все центральные суставы были соорентированы. Но вы можете захотеть оставить базовый сустав с локальными осями, совпадающими с мировыми координатами. Тогда нам нужно будет разорвать связи между базовым суставом и спиной, а так же отпарентить сустав таза. Теперь припарентим базовый сустав к тазу и ориентируем только его. Базовый сустав остаётся в нетронутом виде. Теперь восстановим связи.

Ориентированный скелет можно посмотреть тут: (Файл orientedJoints.mb)

Для того чтобы ровно вставить сегменты, можно создать следующую конструкцию. Берём 2 круга и столько локаторов, сколько у нас будет сегментов. Присоеденим локаторы к кругам через pointConstraint, выставляя нужные веса. Теперь локаторы всегда ровно делят расстояние между кругами. Используя привязки, ставим круги на нужные суставы, а новые сегменты строим через insertJoint, также используя привязки.

3d max анимация персонажа кости

Теперь восстановим связи конечностей и центрального скелета. Отзеркалим конечности (выделяем, например, сустав ключицы и зеркалим через Mirror joint со значениями по умолчанию. Не забудьте выставить автоматическое переименование с L_ на R_).

3d max анимация персонажа кости

На этом построение скелета закончено. (Файл finalSkeleton.mb)

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

Прискиненого персонажа можно посмотреть тут: (Файл ReadyToRig.mb)

3d max анимация персонажа кости

Все! Теперь вы можете начать процесс рига. Или, если вам лень, или вы не знаете как, то можете воспользоваться, например, моим скриптом авторига. Если вы сделали всё правильно, то он у вас запустится.

3d max анимация персонажа кости

Полностью готовый к анимации персонаж: (Файл FIN.mb). Скрипт авторига можно взять тут: (Файл MBcatAutoRig.rar).

Спасибо halinka за помощь в оформлении. Спасибо, что дочитали до конца. Надеюсь, урок оказался полезным.

Источник

Реализация скелетной анимации для трёхмерных моделей

Здравствуйте! В данный момент на Хабре существует большое количество статей, посвящённых компьютерной графике и реализации различных эффектов, однако текстов на тему реализации скелетной анимации (особенно «с нуля») достаточно немного. Постараюсь восполнить этот пробел с помощью данного текста с описанием технологии и примером несложной реализации на C++ и OpenGL 4.5 (SDL2).

3d max анимация персонажа кости

Введение

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

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

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

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

Иерархия частей в таком случае могла выглядеть, например, так:

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

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

Подготовка модели на этапе дизайна

Рассмотрим обзорно процесс подготовки модели к анимации на этапе дизайна.

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

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

На изображении ниже продемонстрирована структура и визуализация скелета трёхмерной модели человека (взята отсюда) при редактировании в Autodesk 3ds Max. Хотя на данной визуализации кости имеют объём, на самом деле они являются точками с привязанными системами координат, что будет более подробно описано ниже.

3d max анимация персонажа кости

Как можно заметить, каждая кость скелета имеет родительскую кость. Корневая кость является исключением. Родительским объектом для неё является локальная система координат модели. Стоит заметить, что в общем случае 3D-редакторы позволяют размещать несколько моделей на сцене, но здесь системы координат сцены и модели совпадают.

На следующем этапе выполняется привязка вершин модели к созданному скелету (этот процесс называется скиннингом). Каждая вершина может быть привязана к любому количеству костей одновременно (но часто используют не более четырёх костей). В случае привязки к одной вершине нескольких костей, для каждой из них задаётся вес (обычно число от 0.0 до 1.0), определяющий степень влияния кости на данную вершину. Чем больше вес, тем активнее вершина перемещается при движении кости. Сумма весов всех костей для каждой вершины должна равняться единице.

На следующем изображении визуализировано влияние кости на связанные с ней вершины (более тёплые цвета обозначают высокую степень влияния — число более близкое к единице).

3d max анимация персонажа кости

Здесь стоит обратить внимание на позу, в которой скелет привязывается к модели (персонаж находится в стоящей позе, руки вытянуты в стороны). Данная поза называется T-позой (так как напоминает букву T) или bind-позой и обычно используется дизайнерами при скиннинге в силу удобства при назначении весов и дальнейшем анимировании.

Анимация модели на этапе дизайна

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

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

3d max анимация персонажа кости

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

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

Позиционирование модели

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

С точки зрения математики кость представляет собой систему координат, заданную относительно системы координат родительской кости или модели для корневой кости. Для задания кости можно использовать матрицу или SRT-структуру (scale, rotation, translation — масштаб, поворот, перенос/позиция). Масштабирование на практике применяется к костям не очень часто, поэтому в дальнейшем будем считать, что для костей задаются только поворот и позиция относительно родителя, и будем хранить RT-структуру (без R-компонента). Для представления поворота будем использовать кватернионы.

Исходя из этого, на самом деле не очень правильно использовать в данном контексте слово «кость», так как здесь она представляет собой всего лишь материальную точку. Более правильным было бы использовать слово Joint (сустав, соединение), однако со временем данные понятия стали практически взаимозаменяемыми.

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

Обозначим матрицу перехода из системы координат кости в систему координат её родителя как 3d max анимация персонажа кости, где 3d max анимация персонажа кости— индекс кости, а 3d max анимация персонажа кости— индекс её родительской кости. Для родителя корневой кости будем использовать индекс 3d max анимация персонажа кости, символизирующий локальную систему координат модели в целом. Данную матрицу можно получить из RT-структуры как комбинацию матриц поворота и перемещения.

Другой важной характеристикой кости будет являться матрица перехода из пространства модели в систему координат кости в bind-позе (inverse bind pose matrix). Обозначим её за 3d max анимация персонажа кости. Данная матрица создаётся на этапе привязки скелета и больше не изменяется.

Позицию вершины в bind-позе (xyz-вектор) обозначим за 3d max анимация персонажа кости, а искомую позицию в анимированной позе — 3d max анимация персонажа кости.

Рассмотрим на примере следующего скелета:

3d max анимация персонажа кости

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

3d max анимация персонажа кости

Другими словами, сначача мы переводим координаты вершины в систему координат кости 3 в bind-позе с помощью матрицы 3d max анимация персонажа кости, а затем последовательно применяем матрицы преобразований костей, следуя к корню скелета.

Так как на данном этапе система координат корневой кости не совпадает с системой координат модели, также требуется преобразование 3d max анимация персонажа кости.

Можно заметить, что обратная матрица bind-позы является постоянной для кости, а матрицы перехода 3d max анимация персонажа костибудут определяться временем клипа, но являются общими для всех привязанных к кости вершин.

Для уменьшения количества матричных умножений в этом случае удобно сгенерировать так называемую матричную палитру (matrix palette), в которой для каждой кости хранится предварительно посчитанное произведение матриц bind-позы и матриц перехода. Данное произведение также представляет собой матрицу и позволяет для заданной вершины за одно умножение выполнить переход из bind-позы в анимированную позу.

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

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

Проигрывание анимации

Теперь, когда задача о позиционировании модели с помощью скелета решена, проигрывание анимации не должно составить труда. В произвольный момент времени 3d max анимация персонажа костидля каждой из костей можно найти два соседних ключевых кадра (предыдущий и следующий) и получить текущую позицию путём интерполяции значений в них. Для координат часто применяется линейная интерполяция, а для ориентации, если она задана кватернионом, — сферическая линейная (позволяет избежать резких поворотов и неестественных углов).

Реализация

Итак, настало время переходить к непосредственной реализации. Рассмотрим структуры данных, которые можно использовать для хранения анимированной модели и для проигрывания анимации.

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

Начнём с костей. Для их хранения создадим следующую структуру:

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

Скелет будет представлять собой обычный массив костей (удобно будет заполнять этот массив так, чтобы дочерние кости находились в нём после родительских):

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

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

Метод getBoneMatrix() предназначен для получения матрицы перехода из пространства дочерней кости в пространство родительской, то есть той самой матрицы 3d max анимация персонажа кости. Данная матрица является комбинацией перемещения и поворота, заданного кватернионом, причём поворот выполняется первым, так как ассоциативность операций правая. Позицию вершины мы также будем умножать на матрицу справа.

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

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

Определим структуру матричной палитры:

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

Теперь можно переводить модели в произвольные позы с помощью скелета. Осталось реализовать механизм проигрывания анимации во времени и связать данный механизм с отрисовкой модели.

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

Далее, реализуем простой метода, который увеличивает счётчик прошедшего с начала анимации времени:

Данный метод имеет единственный параметр — приращение времени. Внутри происходит увеличение значения счётчика прошедших с начала анимации кадров (получить вещественный номер кадра в данном случае — нормальное явление).

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

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

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

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

Осталось определить недостающие методы для интерполяции векторов и кватернионов ( getInterpolatedValue() ), для получения позиции или ориентации из ключевого кадра ( getKeyframeValue() ) или значения по-умолчанию ( getIdentity ).

Как упоминалось выше, для интерполяции векторов используется обычная линейная интерполяция ( glm::mix() ), а для кватернионов — сферическая линейная интерполяция ( glm::slerp() )

Отрисовка анимации

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

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

Заметим, что и индексы, и веса костей хранятся как целые однобайтовые числа. Так как изначально вес представляет собой вещественное число от 0 до 1, придётся выполнить переход к границам от 0 до 255 и округление. В данном случае к одной вершине можно привязать до 4-х костей одновременно.

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

Модификации вершинного шейдера:

Где-нибудь в коде обновления состояния сцены будем увеличивать счётчик анимационного клипа:

А в коде отрисовки будем получать матричную палитру и передавать её в шейдер:

Заключение

Таким образом, в данной статье была рассмотрена базовая реализация скелетной анимации на C++. Демо-видео под спойлером.

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *