Вычисление матрицы bindPose (скелетная анимация)

Я успешно проанализировал формат 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 * rotation


        joint->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());

Расчет связывания корневой кости должен быть правильным (по крайней мере, я так думаю), потому что голова находится в нужном месте, а глаза тоже (которые в настоящее время не влияют на кости)

0 ответов

Другие вопросы по тегам