Я успешно проанализировал формат iqe (Inter Quake Exporter) и теперь застрял при его отображении в bindpose.
Все вершины имеют странное преобразование, где корневая кость (которая охватывает всю сетку для ориентации) не единственная кость, влияющая на эту вершину. Вы можете видеть это в области руки / должны / шеи сетки. Эта сетка имеет 3 кости. Одна корневая кость перекрывает всю сетку и две кости руки.
Вы можете видеть, как сетка должна выглядеть на заднем плане (экспортируется как obj)
Для лучшего понимания у меня есть следующая система:
1. Я загружаю все данные вершин в один большой VBO
(вершины, uvs, нормали, тангенс, битангенс, boneIndicies (4) (индекс списка соединений) и boneWeights (4))
2. Я добавляю все соединения в список соединений и создаю древовидную систему (простой связанный список с позицией, поворотом и родительским указателем)
3. у меня есть отдельный список под названием boneMatrices, где я храню .. ну мои кости матрицы. в настоящее время каждый кадр, позже я буду предварительно вычислять матрицы для каждого кадра анимации.
Я пытаюсь вычислить матрицу кости следующим образом:
for (int i = 0; i < this->jointList.size(); i++)
{
pixel::CJoint *joint = this->jointList.at(i);std::cout << "Joint ------- " << joint->name << " -------- values: \n";
std::cout << "Translation: " << joint->position.x << " " << joint->position.y << " " << joint->position.z << "\n";
std::cout << "Quaternion: " << joint->rotation.x << " " << joint->rotation.y << " " << joint->rotation.z << " " << joint->rotation.w << "\n";pixel::matrix4 rotation = pixel::CMatrix::fromQuaternion(joint->rotation);
pixel::matrix4 offset = pixel::CMatrix::translateMatrix(joint->position);
pixel::matrix4 baseMatrix = rotation * offset; // translation * rotationjoint->bindPose = baseMatrix;
joint->invBindPose = pixel::CMatrix::inverseMatrix(baseMatrix);
if (joint->parent != NULL)
{
std::cout << "Joint: " << joint->name << " is child of " << joint->parent->name << " \n";
joint->bindPose = joint->bindPose * joint->parent->invBindPose;
joint->invBindPose = pixel::CMatrix::inverseMatrix(joint->bindPose);
}std::cout << "\n";
}
Я сохраняю транспонированный (иначе сетка переворачивается) сустава -> invBindPose в boneMatrices и отправляю его в шейдер:
boneMatrix является стандартным вектором матрицы4
this->material.setParameter("boneMatrix", this->boneMatrices.at(0), this->boneMatrices.size());
Расчет связывания корневой кости должен быть правильным (по крайней мере, я так думаю), потому что голова находится в нужном месте, а глаза тоже (которые в настоящее время не влияют на кости)
Задача ещё не решена.
Других решений пока нет …