Как я могу применить дельта-вращение двух кватернионов к третьему? - PullRequest
0 голосов
/ 20 января 2020

Я копирую это из обмена математическим стеком по совету из комментария.

Вот код, с которого я начинаю:

func orientation_follow(state, current_basis : Basis, target_basis : Basis):
    var delta : Basis = target_basis * current_basis.inverse();

    var q = Quat(delta);
    var axis = Vector3(q.x, q.y, q.z);

    if (axis.length_squared() > 0.0001):  # bullet fuzzyzero() is < FLT_EPSILON (1E-5)
        axis = axis.normalized();
        var angle = 2.0 * acos(q.w);
        state.set_angular_velocity(axis * (angle / (state.get_step())));
    else:
        state.set_angular_velocity(Vector3(0,0,0));

Основа - это направление в котором каждый вектор объекта был повернут. Это инвертируется и умножается на основание целевого объекта (в данном случае контроллера движения игрока), чтобы получить дельта-вращение от объекта к контроллеру. Эта дельта преобразуется в кватернион, из которого ее ось получена и нормализована перед умножением арккозина на коэффициент z кватерниона на 2, чтобы получить угол и найти произведение угла на эту ось (деленное на время дельты, которое, я полагаю, немного сглаживает вращение), устанавливая скорость angular в соответствии с тем, как объекты RigidBody должны взаимодействовать в Godot.

По крайней мере, я так думаю.

проблема в том, что каждый раз, когда вы берете объект, он по существу привязывается к вращению контроллера, потому что функция интерполирует вращение объекта к вращению контроллера каждый кадр. Поэтому, если вы пытаетесь перевернуть что-то вверх дном, вы должны полностью повернуть свой контроллер, вместо того, чтобы поднимать его, класть его частично повернутым, а затем использовать другой контроллер для завершения вращения.

То, что я хотел бы сделать, это получить разницу во вращении в контроллере между последним и текущим кадром, а затем применить эту разницу к удерживаемому объекту в каждом кадре, но я ничего не пробовал в течение последнего Кажется, несколько часов работают. Конечная цель состоит в том, чтобы объект сохранял свое вращение при первоначальном захвате, но вращал ту же величину, что и контроллер, пока он удерживается, вместо того, чтобы сразу же привязываться к ориентации контроллера, как только он был поднят.

Редактировать: я нашел обходной путь (вместо этого используйте шарнирное соединение), поэтому нет необходимости в ответе на этот вопрос.

...