Как получить эйлерово вращение твердого тела от 0 до 360 в Bullet Physics?
В настоящее время я пытаюсь получить вращение объекта. Я использую C++ и Bullet Physics. Это мой код:
btScalar x, y, z;
body[0]->getCenterOfMassTransform().getBasis().getEulerZYX(z, y, x);
Однако, когда я поворачиваю объект вокруг по часовой стрелке, число, которое я получаю от оси y (y - вертикальная по пули), изменяется от 0 до -90 до 0 до 90 и, наконец, возвращается к 0 для каждого поворота на четверть. Это близко, но мне нужно, чтобы он прошел весь путь от 0 до 360.
2 ответа
Пуля документации говорит:
void getEulerZYX (btScalar &yaw, btScalar &pitch, btScalar &roll, unsigned int solution_number=1) const
а также
solution_number Which solution of two possible solutions ( 1 or 2) are possible values
это потому, что углы Эйлера неоднозначны. вы пробовали решение 2?
У меня такая же проблема. Я использую LibGDX с движком Bullet, поэтому мой пример кода на Java, но я уверен, что он будет работать и на C++. Вот мое решение (для оси Z):
body.getWorldTransform().getRotation(mRotation);
// That gives you an angle in all range but excluding (85, 95) and (-95, 85). For other axis you can try to get Pitch or Yaw.
float roll = mRotation.getRoll();
// That gives you an angle in range [0, 240). Clockwise and counterclockwise directions isn't detected.
float angle = mRotation.getAngleAround(0, 0, 1);
// Usually 0, but on (85, 95) and (-95, 85) becomes 1 and -1.
int gimbalPole = mRotation.getGimbalPole();
// Using roll (pitch/yaw for other axis) if it's defined, and using angle with gimble pole otherwise.
float rotation = (gimbalPole == 0) ? roll : angle * gimbalPole;
Полученное вращение будет в диапазоне (-180, 180). Его можно легко преобразовать в диапазон [0, 360):
if (rotation < 0) rotation += 360;