главная страница статьи файлы о сайте ссылки |
Георгий Мошкин Обратите внимание - самая новая версия загрузчика моделей Half-Life smd: текущая версия загрузчика SMD. Здесь я хотел бы рассказать немного о своём опыте по применению скелетной анимации в играх. Начну с того, что я никогда не занимался созданием 3d моделей людей. Но когда я впервые увидел программу MilkShape3D, то мне очень понравилось, что я достаточно легко могу создавать новые движения трёхмерных героев. Помимо этого я обратил внимание на маленький размер получающихся файлов: модель была в отдельном большом файле, а разные движения (бег, ходьба и т.п) - в нескольких файлах. Я говорю о файлах с расширением smd, с которыми может работать MilkShape3D.
"Скелетная анимация" казалась мне чем-то сложным. А так как я обажаю Pascal, то мне было ещё сложнее. Ведь исходники Half Life Model viewer были написаны на C++, и на первый взгляд непонятно было как всё это хозяйство приспособить к TMT Pascal или Delphi. Но несмотря на эти трудности в 2002 году на свет вышли две моих программы: Half-Life smd viewer for TMT Pascal и Half-Life smd viewer for Delphi. В дальнейшем в свет вышла ещё "продвинутая" версия под TMT Pascal (c поддержкой animation blend и attach объектов). По мере транслирования функций из C++ в Pascal я осознал, что всё намного проще. Просто вначале я пытался написать свою программу для моделирования скелетной анимации, в то время как нужно было просто сделать проигрыватель и пользоваться моделями в формате Half-Life smd или MilkShape (там всё очень похоже). На сегодняшний день ситуация обстоит несколько иначе. В современных играх уже недостаточно просто проигрывать анимацию, но нужно ешё и реализовывать взаимодействие скелета с окружающим миром (например, Rag Doll). К тому же, некоторые анимации движения можно создавать "на лету". Но и просто скелетная анимация без всяких наворотов вроде совместного влияния костей на одну и ту же часть меша выглядит весьма неплохо.
Ну а теперь, после этого длительного вступления, скажу очень кратко о проигрывании скелетной анимации. Обратите внимание, что принцип действия понять очень просто. И лучше всего это сделать на примере файлов Half Life SMD. Скелет там описывается так: nodes Вначале написано "nodes". Можно переводить это дословно, но лучше считать, что "nodes" - это суставы. Хотя, правильнее называть их узлами. Посмотрим на нулевую строчку (нулевой сустав). Читать нужно так:
Но этих данных для создания скелета недостаточно. Мы не знаем длины костей и их относительного положения. Для этого в файлах SMD есть следующий блок данных: time 14 time 15 - это номер кадра. Читать нужно так:
В файлах с анимацией следует много таких блоков с промежуточными положениями для суставов. (time 0, потом строки 0-44, time 1 и ещё строки 0-44 и т.д). Вот так описывается весь скелет, включая косточки пальцев. И только один раз описывается структура nodes.
Теперь о том, как это всё работает: пусть мы хотим просто вывести анимацию этого скелета: суставы - точками (GL_POINT), а кости - линиями (GL_LINE). У каждого сустава есть своя система координат. И мы знаем какой сустав к какому прикреплён. А только что было написано "сустав 0 перемещён на ...". Относительно чего перемещён? Относительно того сустава, к которому он прикреплён костью. Начнём выводить нулевой сустав. Он прикреплён костью к "минус первому" суставу. А такого сустава нет!! Всё дело в том, что "-1" суставом считается основная система координат. Все манипуляции с системой координат нулевого сустава делаются относительно точки (0,0,0). Длина костей как раз и задаётся тем, насколько рассматриваемый сустав перемещается относительно того, к которому он прикреплён. Рассмотрим более детально структуру скелета:
А теперь повернём сустав, который находится в плече: После поворота этого сустава скелет будет выглядеть так: Если посмотреть на скелет со стороны, то получится следующее: Выводить скелет - это хорошо, но как же быть с mesh? Всё очень просто. В основном файле smd треугольники 3d модели описываются в следующем виде: zombie_legs.bmp Первое число - это номер того сустава (системы координат), в которой следует выводить этот треугольник. Следующие за номером 43 восемь чисел - это координаты вершины (x,y,z), нормаль (nx,ny,nz) и текстурные координаты (u,v). Таким образом, все три точки из треугольника с текстурой zombie_legs.bmp должны трансформироваться в соответствии с цепочкой трасформаций для узла 43 (сустава 43). Плавность движений достигается созданием промежуточных кадров (эти кадры создаются вручную). Выше был показан блок данных для одного из кадров скелетной анимации: time 14 Для подвижной анимации таких блоков должно быть 2 или более. Даже плавную ходьбу можно сделать двумя кадрами, но это будет выглядеть неестественно. Поэтому делают больше ключевых кадров, между которыми и производят интерполяцию. Программы для проигрывания анимации я писал достаточно давно, но всё-таки ещё помню некоторые ньюансы: во-первых, в главном smd файле находится нормальная модель и один кадр анимации ("time 0"). После загрузки я "сверачивал" 3d модель, произведя "инверсные" translation и rotation. Это было как бы подготовкой к последующему её "разворачиванию" при реальной анимации. Потом, при написании проигрывателя анимации в формате milkshape, я обнаружил небольшую разницу в хранении translation или rotation (уже точно не помню). В конце приведу юниты для tmt pascal: Использовать версию для tmtpascal так: |