Скелетная анимация: искаженная сетка для файла fbx, но не файл dae? - PullRequest
0 голосов
/ 17 мая 2018

У меня очень странные проблемы с использованием Assimp для загрузки и создания скелетной анимации.Я использую две модели для тестирования своего кода, и обе модели загружаются правильно с Assimp Viewer, поэтому с ними не должно быть ошибок.Однако, когда я загружаю эти две модели с моим кодом, только 1 работает правильно.

enter image description here

Очевидно, что этот не работает.Анимация шеи курицы работает, как и ожидалось, но ноги искажены.

enter image description here

Этот работает отлично.

Единственные различия, о которых я могу думать, это то, что первая модель - это файл fbx, а вторая - файл dae, и что первая имеет несколько сеток, что требует от меня их преобразования обратно в то же корневое пространствоесли я хочу, чтобы статическая модель загружалась правильно, тогда как вторая имеет только одну сетку, которая уже находится в исходном пространстве в корневом пространстве.Неудивительно, что сетки, которые мне нужно преобразовать обратно в одно и то же пространство, - это те, которые содержат ножки курицы.

На самом деле я не использую mOffsetMatrix Ассимп, а вычисляю свой собственный метод inverseBindTransform.Я предполагаю, что я рассчитываю их правильно, потому что 1 из моих моделей работает.Ниже приведен обзор моего умножения матриц:

modelView * toWorldMatrix * desiredPoseMatrix * inverseBindTransform * meshToWorldMat * position 

meshToWorldMat - это преобразование, которое возвращает пространство сетки обратно в мировое пространство.(toWorldMatrix * requiredPoseMatrix) является просто результатом интерполяции ключевого кадра, умноженной на его parentMatrix.

Что не так с моим подходом?

Обновление: я также обнаружил, что некоторые сетки искаженной модели fbx имеют одну и ту же кость, хотя я не уверен, что это важно.

1 Ответ

0 голосов

Я использовал следующее преобразование для каждой кости в скелете:

math::Matrix4F Bone::getTransform(const NodePtr& meshNode) const
{
    math::Matrix4F fullCurrentMesh = meshNode->getWorldTransformation()
                                   * meshNode->getLocalInitTransformation(ETransformation::Geometry);

    math::Matrix4F fullInitMesh = meshNode->getWorldInitTransformation()
                                * meshNode->getLocalInitTransformation(ETransformation::Geometry);

    math::Matrix4F relPose0 = (m_node->getWorldInitTransformation() * m_bindPoseBone).getInverse()
                            * fullInitMesh;

    math::Matrix4F relPoseInv = fullCurrentMesh.getInverse() * m_node->getWorldTransformation();

    return relPoseInv * relPose0;
}

Все матрицы «init» рассчитываются с отметкой времени = 0, «локальные» матрицы - это данные из файла «fbx», m_bindPoseBone - bindпоза для этой кости (также из "fbx")

...