Я работаю над написанием собственного импортера COLLADA. Я зашел довольно далеко, загружая модели, материалы и тому подобное. Но я наткнулся на загвоздку с анимацией, а именно с вращением суставов.
Формула, которую я использую для скиннинга своих мешей, проста:
weighted;
for (i = 0; i < joint_influences; i++)
{
weighted +=
joint[joint_index[i]]->parent->local_matrix *
joint[joint_index[i]]->local_matrix *
skin->inverse_bind_pose[joint_index[i]] *
position *
skin->weight[j];
}
position = weighted;
И что касается литературы, это правильная формула. Теперь COLLADA определяет два типа поворота для суставов: локальный и глобальный. Вы должны объединить повороты вместе, чтобы получить локальное преобразование для соединения.
Документация COLLADA не различает локальное вращение сустава и глобальное вращение сустава. Но в большинстве моделей, которые я видел, вращения могут иметь идентификатор rotate
(глобальный) или JointOrient
(локальный).
Когда я не обращаю внимания на глобальные вращения и использую только локальные, я получаю позу привязки для модели. Но когда я добавляю глобальные повороты к локальному преобразованию сустава, начинают происходить странные вещи.
Это без использования глобального вращения:
И это с глобальным вращением:
На обоих скриншотах я рисую скелет, используя линии, но в первом он невидим, потому что суставы находятся внутри меша.На втором скриншоте вершины повсюду!
Для сравнения, вот как должен выглядеть второй снимок экрана :
Трудно увидеть, но на втором снимке экрана видно, что суставы находятся в правильном положении.
Но теперь самое странное. Если я проигнорирую обратную позу связывания, заданную COLLADA, и вместо этого возьму обратное локальное преобразование родительского сустава, умноженное на локальное преобразование сустава, я получу следующее:
На этом снимке экрана я рисую линию от каждой вершины до суставы, которые имеют влияние. Тот факт, что я принимаю позу связывания, не так уж странен, потому что формула теперь выглядит так:
world_matrix * inverse_world_matrix * position * weight
Но это заставляет меня подозревать, что обратная поза связывания COLLADA находится в неправильном месте.
Итак, мой вопрос: в каком пространстве COLLADA указывает свою обратную позу связывания? И как я могу преобразовать позу обратной привязки в нужное мне пространство?