Я реализовал систему скелетной анимации, где мне, кажется, не хватает одной последней детали, чтобы она работала правильно.Скелетная анимация, преобразование трансформации
Я сделал анимацию, в которой только часть персонажа имеет кости. На этом изображении у патчмена есть размахивающий рукав, но рука движется в неправильном месте по сравнению с остальной палкой. (Вы только видеть его между ногами)
Я попытаюсь изложить основы моей матрицы вычисления, чтобы увидеть, если я делаю что-то неправильно.
Исчисление кости специфической абсолютной и относительной матрицы анимации (на основе моих данных ключевого кадра матрицы):
if (b == this->root) {
b->absoluteMatrix = M;
} else {
b->absoluteMatrix = b->parent->absoluteMatrix * M;
}
b->skinningMatrix = b->absoluteMatrix * inverse(b->offsetMatrix);
if (this->currentAnimationTime == 0) {
cout << "Bone '" << b->name << "' skinningMatrix:\n";
printMatrix(b->skinningMatrix);
cout << "Bone '" << b->name << "' absoluteMatrix:\n";
printMatrix(b->absoluteMatrix);
cout << "Bone '" << b->name << "' offsetMatrix:\n";
printMatrix(b->offsetMatrix);
cout << "---------------------------------\n";
}
skinningMatrix, которые я отправляю в ГПУ. Это печатает следующее:
где offsetMatrix является преобразование, которое переходит из сетки пространства костным пространства в затруднительной позе.
В моем шейдере я тогда делать:
layout(location = 0) in vec4 v; // normal vertex data
newVertex = (skinningMatrix[boneIndex.x] * v) * weights.x;
newVertex = (skinningMatrix[boneIndex.y] * v) * weights.y + newVertex;
newVertex = (skinningMatrix[boneIndex.z] * v) * weights.z + newVertex;
Любые намеки на то, что может быть не так с моими расчетами?
Биты, которые вы опубликовали, выглядят хорошо. Не могли бы вы подробнее рассказать о том, как вы вычисляете 'offsetMatrix'? Вы проверили, что 'skinningMatrix' - это единичная матрица, когда ваш персонаж находится в привязке? Сумма «весов» всегда равна 1? Это работает, если вы используете только одну кость за вершину? –
Анимация руки работает правильно. Сама рука находится не в том месте. Смещение-матрица захватывается для каждой кости из импорта ASSIMP, который документируется как «offsetMatrix - это преобразование, которое преобразуется из пространства сетки в пространство костей в позе привязки». Я конвертирую его из aiMatrix4x4 в glm :: mat4. Я смотрю на мою skinningmatrix во время = 0, и это не единичная матрица. Если я хочу вычислить матрицу bindpose, я бы просто захватил absoluteMatrix во время 0? Или инициализация? – toeplitz
Я добавил в сообщение вывод отладки, если он может помочь. – toeplitz