Я работаю над написанием собственного импортера 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 указывает свою обратную привязку? И как я могу преобразовать позыв обратной привязки в нужное мне пространство?