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