Построение матрицы вида через мировые координаты в OpenGL
Я использую библиотеку assimp для импорта 3d сцены. С мешами проблем нет. Проблемы с камерой. У меня не получается построить корректную матрицу вида. Если брать не gltf, то в качестве импортируемых данных будут данные перспективы и мировые координаты позиция и вращение. У меня было несколько десятков попыток, но в каждой из них всё что я вижу - это чёрный экран. При этом если поставить lookAt матрицу, где eye в {0.0f, 0.0f, z}, то я вижу объект, хотя по мировому расположению не должен. Но я понимаю что сам по себе OpenGL не знает ни что такое мировые координаты, ни что такое камера. Но как научить не знаю. При этом я даже пробовал импортировать сцену во всякие Web редакторы. Там всё ОК. Значит я что-то делаю не так. При этом я проверял и позиция и углы приходят верно. Если я открою ту же сцену в 3d редакторе и задам камеру в позиции и с углами которые я получил (ниже в коде переменная euler) всё будет ОК.
aiVector3D d;
aiQuaternion k;
for (unsigned int i = 0; i < scene->mNumAnimations; i++)
{
d = scene->mAnimations[i]->mChannels[0]->mPositionKeys[0].mValue;
k = scene->mAnimations[i]->mChannels[0]->mRotationKeys[0].mValue;
}
glm::quat ua{k.w, k.x, k.y, k.z};
glm::vec3 euler = glm::eulerAngles(ua);
auto mTrans = glm::translate(glm::mat4{1.0f}, glm::vec3{d.x, d.y, 0.0f});
glm::mat4 rotM = glm::mat4(1.0f);
glm::mat4 transM;
rotM = glm::rotate(rotM, euler.x, glm::vec3(1.0f, 0.0f, 0.0f));
rotM = glm::rotate(rotM, euler.y, glm::vec3(0.0f, 1.0f, 0.0f));
rotM = glm::rotate(rotM, euler.z, glm::vec3(0.0f, 0.0f, 1.0f));
ooo.mView = mTrans * rotM;
Просьба помочь. Что я делаю не так? И наверное, важно добавить что исходная позиция камеры находится примерно в {10, 5, 0}. Т.е. она смотрит в ось X, а не в ось Z.
Сама цена выглядит так
Это вид с камеры. Плейн находится в точке 0,0,0
Попробовал упростить. Gltf файл:
"cameras":[{
"type":"perspective",
"perspective":{
"znear":0.009999999776482582,
"zfar":10000000000.0,
"aspectRatio":1.0,
"yfov":0.9272952079772949
}
}],
"nodes":[{
"translation":[10.896925926208496,
5.699595928192139,
-3.3627376297927987e-31],
"name":"cam0",
"rotation":[0.11757808923721314,
-0.6972627639770508,
-0.11757808923721314,
-0.6972627639770508],
"scale":[1.0,
1.0,
1.0],
"camera":0
},
{
"translation":[0.0,
0.0,
0.0],
"name":"plane",
"rotation":[0.0,
0.0,
0.0,
-1.0],
"scale":[1.0,
1.0,
1.0],
"mesh":0
}],
Это камера и сам меш. Ведь по логике оно должно работать так:
Camera Importer::processCam(aiCamera *cam, const aiScene *scene)
{
glm::vec3 translation{10.896925926208496f, 5.699595928192139f, -3.3627376297927987e-31f};
glm::quat rotation{0.11757808923721314f, -0.6972627639770508f, -0.11757808923721314f, -0.6972627639770508};
glm::vec3 planeTrans{0.0f, 0.0f, 0.0f};
glm::quat planeRot{0.0f, 0.0f, 0.0f, -1.0f};
Camera ooo{};
glm::mat4 proj = glm::perspective(0.9272952079772949f, 1.0f, 0.009999999776482582f, 10000000000.0f);
auto view = glm::translate(glm::mat4{1.0f}, translation) * glm::mat4_cast(rotation);
auto model = glm::translate(glm::mat4{1.0f}, planeTrans) * glm::mat4_cast(planeRot);
ooo.mView = proj * view * model;
return ooo;
}
Сейчас mView - это перемножение всех матриц: проекции, вида и самого объекта. Но по прежнему чёрный экран
UPD: Я вообще больше практикую Vulkan. Но тут решил опробовать OpenGL. ВРоде говорят быстрее разработка. Я перенёс код в проект на вулкане. Да, с таким кодом тоже не особо работало. Но быстро получилось всё там. А в OpenGL такое ощщущение что он принудительно смотрит в ось Z.
Код идентичный:
glm::lookAt(glm::vec3(-10.8969f, 5.6996f, 0.1f), glm::vec3{0.0f, 0.0f, 1.0f}, glm::vec3{0.0f, 1.0f, 0.0f});
Я даже ставил дебаг и проверял матрицу (proj * view * model). Выходная матрица идентична. Я слышал что в OpenGL ось Y развернута, но я пробовал и отрицательные углы, и отрицательную позицию.
UPD: Я пока ищу подходящую формула для преобразования мирового пространства в координатную систему OpenGL, но возник ещё один вопрос. Это дальность камеры. Я пока в 3d редакторе сделал камеру, разместил её по оси Z и просто перекопировал координаты. В Vulkan-е выглядит ровно также как и в редакторе. А в OpenGL дальность другая. При этом данные как перспективы, так и сами координаты идентичные.


