#c #3d #glm #quaternions #euler-angles
Вопрос:
У меня есть структура, которую я передаю в качестве аргумента. Идея заключается в том, чтобы создать кватернион с помощью slerp
функции, сравнивая кватернион объекта камеры и некоторую другую целевую amp;t
ориентацию.
Проблема, вероятно, в том, что я не понимаю математику. В настоящее время камера работает с углами Эйлера (в настоящее время у меня с этим проблем нет). Поэтому я хочу взять кватернион slerp, преобразовать его в Эйлера, применить преобразование к векторам камеры, а затем сохранить новую четверть на основе новых значений Эйлера для использования в качестве сравнения.
Структура ниже с функцией сравнения кватернионов. Изо всех сил пытаюсь предложить больше, чтобы описать визуальную ошибку, кроме того, что камера значительно выходит из себя. Спасибо.
Структура, которую я передаю, передается в качестве аргумента для std::function
члена в другом месте:
struct panning_camera_handle { Camera* cam; bool operator ()(glm::quatamp; s, const glm::quatamp; t) { float dps{ 180.0f }; // degrees per second //first calculate the distance (angular magnitude between two rotation quaternions) float cosOmega = glm::dot(s, t); float sinOmega = glm::sqrt(1.0f - cosOmega * cosOmega); float omega = glm::degrees(atan2(sinOmega, cosOmega)); // the diff. angle if (omega lt; 1.0f) { // CALC QUAT TO MOVE ORIENTATION TO TARGET auto q = glm::slerp(s, t, 1.0f); //single slerp step cam-gt;update_camera_vectors(q); return true; //if angular distance is very small } //we are done, return true. else { float min = dps * ejn::deltaTime * 0.001f; // min ang. displacement this cycle if (omega lt; min) { //CALC AS ABOVE auto q = glm::slerp(s, t, 1.0f); //single slerp step cam-gt;update_camera_vectors(q); return true; } else { //CALC THE INCREMENT AND UPDATE CAMERA VECTORS float tt = min / omega; auto q = glm::slerp(s, t, tt); cam-gt;update_camera_vectors(q); return false; //test for completion on next cycle } } } };
Текущая редакция функции камеры (их было несколько…), которую я хотел бы изменить. Обратите внимание на orient
элемент, который является переменной, которую я хочу использовать для дальнейших сравнений в приведенной выше структуре.
void enjyn_Camera::update_camera_vectors(glm::quat q) { eul = glm::degrees(glm::eulerAngles(q)); if (eul.x gt; 89.0f) eul.x = 89.0f; if (eul.x lt; -89.0f) eul.x = -89.0f; glm::vec3 front; front.x = cos(glm::radians(eul.y)) * cos(glm::radians(eul.x)); front.y = sin(glm::radians(eul.x)); front.z = sin(glm::radians(eul.y)) * cos(glm::radians(eul.x)); Front = Front glm::normalize(front); Right = glm::normalize(glm::cross(Front, WorldUp)); // normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. Up = glm::normalize(glm::cross(Right, Front)); orient = glm::quat(glm::radians(eul)); }