Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > C++

Ответ
 
Опции темы
Старый 17.10.2013, 23:52   #1
pozitiffcat
Мастер
 
Аватар для pozitiffcat
 
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений
(для 533 пользователей)
Сообщение Как я осилил скелетную анимацию.

Для своего движка (Indie engine), понадобилось использовать ms3d модели со скелетной анимацией, причем что бы это все работало на мобильных устройствах. Мучился с этим я долго, я не понимал вообще ничего, и наконец-то получилось. Я хочу поделиться опытом.

Стоит запомнить несколько правил.
- Создайте отдельный класс скелета
- Класс скелета хранит структуры костей
- Кость знает про своего родителя, имеет позицию и поворот в локальной системе координат, так же кость знает про ключевые кадры анимации
- Кадр знает про СМЕЩЕНИЕ позиции и поворота (это важно), и время кадра
- вершина должна знать про порядковый номер кости из скелета (несколько костей и вес для каждой)

пример структуры вершины:
struct Vertex
{
    Vertex(float x = 0, float y = 0, float z = 0, float nx = 0, float ny = 0, float nz = 1, float u = 0, float v = 0,
           int joint1 = 0, float weight1 = 0, int joint2 = 0, float weight2 = 0, int joint3 = 0, float weight3 = 0, int joint4 = 0, float weight4 = 0)
        : x(x), y(y), z(z), nx(nx), ny(ny), nz(nz), u(u), v(v)
    {
        if (joint1 < 0) joint1 = 0;
        if (joint2 < 0) joint2 = 0;
        if (joint3 < 0) joint3 = 0;
        if (joint4 < 0) joint4 = 0;

        joint[0] = joint1;
        weight[0] = joint1 >=0 ? weight1 : 0;

        joint[1] = joint2;
        weight[1] = joint2 >=0 ? weight2 : 0;

        joint[2] = joint3;
        weight[2] = joint3 >=0 ? weight3 : 0;

        joint[3] = joint4;
        weight[3] = joint4 >=0 ? weight4 : 0;
    }

    float x, y, z;
    float nx, ny, nz;
    float u, v;
    float joint[4];
    float weight[4];
};
Со структурой разобрались. Можно заполнять скелет данными.

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

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

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

Ах да забыл про шейдер. Приведу его код:

const std::string texturedAnimShaderVs = ""
        "attribute vec4 position;\n"
        "attribute vec2 texcoord;\n"
        "attribute vec4 jointId;\n"
        "attribute vec4 weight;\n"
        "uniform mat4 mvp;\n"
        "uniform mat4 joints[64];\n"
        "varying vec2 vTexcoord;\n"
        "void main(){\n"
        "   vec4 newVertex;\n"
        "   mat4 newMat = joints[int(jointId.x)] * weight.x;\n"
        "   newMat += joints[int(jointId.y)] * weight.y;\n"
        "   newMat += joints[int(jointId.z)] * weight.z;\n"
        "   newMat += joints[int(jointId.w)] * weight.w;\n"
        "   newVertex = newMat * position;\n"
        "   gl_Position = mvp * newVertex;\n"
        "   vTexcoord = texcoord;\n"
        "}\n";

const std::string texturedAnimShaderFs = ""
        "uniform sampler2D texture0;\n"
        "varying vec2 vTexcoord;\n"
        "void main(){\n"
        "   gl_FragColor = texture2D(texture0, vTexcoord);\n"
        "}\n";
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо pozitiffcat за это полезное сообщение:
ABTOMAT (18.10.2013), Gector (19.10.2013), mr.DIMAS (19.10.2013), St_AnGer (20.10.2013)
Старый 20.10.2013, 03:27   #2
pozitiffcat
Мастер
 
Аватар для pozitiffcat
 
Регистрация: 09.05.2010
Адрес: Самара
Сообщений: 1,083
Написано 254 полезных сообщений
(для 533 пользователей)
Ответ: Как я осилил скелетную анимацию.

Сейчас заметил такую важную вещь. Я использовал для вращения углы эйлера (обычные XYZ), оказывается в некоторых сложных ситуациях они ведут себя неадекватно, поэтому нужно использовать кватернионы. Учтите это.
(Offline)
 
Ответить с цитированием
Старый 25.10.2013, 00:01   #3
jimon
 
Сообщений: n/a
Ответ: Как я осилил скелетную анимацию.

в общую солянку

скелет на дуал кватернионах, скелет и все анимации располагаются в сплошном куске памяти (можно за один fread читать)
https://github.com/tatemgames/tateng...r/teSkeleton.h

шейдер скининга на дуал кватернионах
https://github.com/tatemgames/tateng....cpp#L186-L220
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо за это полезное сообщение:
HolyDel (25.10.2013), pozitiffcat (25.10.2013)
Старый 25.10.2013, 00:41   #4
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Ответ: Как я осилил скелетную анимацию.

говорят, под дуалы надо чтобы артисты скинили заранее.
говорят, далеко не все так умеют и вообще мало принято.
в существующих играх (например, red dead redemption) наблюдается создание множества промежуточных костей между основными, чтобы фиксить всякие скрючивания.
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Старый 25.10.2013, 23:20   #5
jimon
 
Сообщений: n/a
Ответ: Как я осилил скелетную анимацию.

Mr_F_
я так понял что дуалы нормально только в последних maya можно делать, там надо скининг режим сразу выставить в dual quaternion и тогда maya будет корректно их рендерить и никаких проблем

из заюзали в cryengine и кроме нормала на стыках проблем не имели (TBN привет говорит на дуал кватах)

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


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 17:27.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com