Прежде всего, я не был уверен, что этот вопрос приветствуется здесь, и я проверил 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);
Я нашел этот грязный код методом проб и ошибок, и он работает. Но, как вы видите, есть отрицания, компоненты swizzling и типы конверсий с помощью разных типов кватернионов. Я думаю, что многие из них не нужны, и задача может быть выполнена гораздо проще.
Не могли бы вы объяснить, почему мои преобразования действительно работают и как их упростить? Кстати, я хочу посмотреть, как это выглядит, если преобразование не работает, вот screenshot ...
Является ли конверсия обратимой? I.e., что произойдет, если вы преобразуете углы Эйлера в кватернион и обратно, не изменяя их? Кроме того, нет ли ошибки в порядке аргументов в первой строке? Не должно быть 'input.x, input.y, input.z'? –
Это кажется ошибкой, но это то, к чему я случайно придумал. Последовательный порядок, который вы считаете правильным, не работает. Я проверил, является ли обращение обратимым, а это не так. Например, углы Эйлера '2, 5, 52' возвращаются как« -3.15, 51.9, 5.56'. Но не знаю, представляет ли это тот же поворот. Насколько я знаю, существует бесконечный различный способ представления одного и того же вращения по углам Эйлера. – danijar