Прежде всего, я не был уверен, что этот вопрос приветствуется здесь, и я проверил FAQ и обнаружил, что "я хотел бы, чтобы другие объясните" вопросы.
Основная проблема заключается в том, что мне нужно дважды сохранять повороты всех объектов в моем приложении. Это связано с тем, что, с одной стороны, физическое моделирование, для которого я использую Bullet Physics, сохраняет его представление. С другой стороны, я храню собственные повороты, общие для всех объектов, независимо от того, находятся ли они в физической симуляции или нет, например, источники света, цели квестов и так далее. В дополнение к физической библиотеке я использую математическую библиотеку GLM.
Я должен синхронизировать оба представления. Кстати, с позициями и масштабом проблем нет. Сложность в том, что симуляция физики и мое собственное представление отличаются, поэтому я не могу просто скопировать значения. Я не обнаружил всех этих различий, но это может быть связано с левой и правой системой координат, градусами и радианами и координатой Y вверх по сравнению с Z вверх.
Мое собственное представление просто хранит углы Эйлера в векторе glm::vec3
. Поскольку я использую OpenGL для рисования, я предполагаю, что пространство правостороннее. Для углов Эйлера порядок имеет значение. Что я делаю для вычисления матрицы вращения, так это сначала создаю матрицу каждого компонента, а затем умножаю их в порядке X * Y * Z
. Более того, в моем собственном представлении положительная координата Y указывает вверх.
Моделирование физики использует кватернионы для хранения вращений. После некоторых исследований я прочитал предположение, что пространство в этой библиотеке левостороннее. У меня нет информации о том, какая координата выше и в каком порядке возвращаются углы Эйлера.
Вот код для преобразования вращения из физического моделирования в мое собственное представление и наоборот.
#include <GLM/glm.hpp>
#include <GLM/gtc/quaternion.hpp>
#include <BULLET/btBulletDynamicsCommon.h>
/*******************************************************************
* euler angles "glm::vec3 input" from my own representation
* to quaternion "btQuaternion output" of physics simulation
*******************************************************************/
glm::quat quaternion(glm::vec3(input.x, input.z, input.y) * 3.14159f / 180.f);
btQuaternion output(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
/*******************************************************************
* quaternion "btQuaternion input" from physics simulation
* to euler angles "glm::vec3 output" of my own representation
*******************************************************************/
glm::quat quaternion(input.getW(), -input.getX(), -input.getY(), -input.getZ());
glm::vec3 angles = glm::eulerAngles(quaternion);
glm::vec3 output(-angles.x, -angles.y, -angles.z);
Я нашел этот грязный код методом проб и ошибок, и он работает. Но, как вы можете видеть, есть отрицания, перебор компонентов и преобразования типов через разные типы кватернионов. Я предполагаю, что многие из них не нужны, и задачу можно выполнить намного проще.
Не могли бы вы объяснить, почему мои преобразования работают и как их упростить? Кстати, я хочу посмотреть, как это выглядит, если преобразование не работает, вот скриншот...
input.x, input.y, input.z
? - person F.X.   schedule 30.04.20132, 5, 52
возвращаются как-3.15, 51.9, 5.56
. Но не знаю, представляет ли это то же вращение. Насколько я знаю, существует бесконечное множество способов представить одно и то же вращение углами Эйлера. - person danijar   schedule 30.04.2013