Я работаю над симулятором движения с 2 DOF (pitch and roll). Я читаю матрицу преобразования из игры, и мне нужно получить углы и отправить аппаратное обеспечение для управления двигателями. Поскольку углы Эйлера имеют особенности, я не могу их использовать. Он ведет себя следующим образом:
когда ему это должно понравиться:
Я подготовил онлайн-пример, чтобы лучше показать проблему:
// Get euler angles from model matrix
var mat = model.matrix;
mat.transpose();
var e = new THREE.Euler();
e.setFromRotationMatrix(mat, 'XZY');
var v = e.toVector3();
var pitch = -v.z;
var roll = -v.x;
http://jsfiddle.net/qajro0ny/3/
Насколько я понимаю, здесь есть две проблемы.
- На симуляторе нет оси рыскания.
- Даже если есть ось рыскания, двигатели просто не ведут себя как компьютерная графика, т.е. им нужно время, чтобы добраться до целевого положения.
Я читал о блокировке карданного вала и даже реализовал фильтр Эйлера, но это не сработало, как ожидалось. Большинство советов о блокировке карданов состояли в том, чтобы использовать кватернионы, но я не могу управлять физическим двигателем с кватернионом (или я могу?).
Осевой порядок здесь не имеет особого значения, поскольку его изменение только сдвигает сингулярность от одной оси к другой.
Мне нужно обработать это каким-либо другим способом.
Я попробовал умножить оси векторы на матрицу, а затем с помощью кросс-точечного произведения получить углы, но это тоже не удалось. Я думаю, что для того, чтобы получить это право, должна быть также осевая репроцессия, но я не мог понять это. Но что-то говорит мне, что это правильный способ сделать это. Это было примерно так: http://jsfiddle.net/qajro0ny/53/
Тогда я придумал другую идею. Я знаю предыдущую позицию, поэтому, возможно, выполните следующие действия:
- Преобразование матрицы в кватернион
- Вычислить разницу между текущим и предыдущим кватернионами
- Преобразование результирующего кватерниона в углы эйлеров
- Добавьте эти углы к переменным статического тона, рулона и рыскания.
Итак, я пробовал это и... это сработало! Никаких особенностей в любом из направлений, идеального вращения на 360 градусов в поле, рулоне и рыскании. Идеальное решение! Кроме... это не так. Кадры не синхронизировались, поэтому через некоторое время углы были вдали от того, чем они должны быть. Я думал о каком-то механизме синхронизации, но я решил, что это не правильный путь.
Это выглядело так: http://jsfiddle.net/qajro0ny/52/
И та же логика, но непосредственно с матрицами: http://jsfiddle.net/qajro0ny/54/
Я искал веб-страницы высоко и низко, я читал десятки статей и других вопросов/сообщений, и я просто не могу поверить, что на мой случай ничего не работает.
Я мог бы не понимать или пропустить что-то, поэтому вот все, что я нашел и попробовал:
Ссылки: http://pastebin.com/3G0dYLvu
Код: http://pastebin.com/PiZKwE2t (я собрал все это вместе, чтобы оно было грязным)
Мне что-то не хватает, или я смотрю на это с неправильного угла.