Първо, не бях сигурен дали този въпрос е добре дошъл тук и проверих ЧЗВ и открих, че „Бих искал другите да обясни" въпросите са.
Основният проблем е, че трябва да съхранявам ротациите на всички обекти два пъти в моето приложение. Това е така, защото от една страна физическата симулация, за която използвам 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