На самом деле, оказывается, что вы не можете иметь «оба пути»: если вы не хотите ощущать «абсолютную ориентацию» на сфере (то есть, если игроки не всегда, например, обращены к полюсам) ), тогда вам нужно иметь представление об ориентации игрока. Это потому, что, вопреки тому, что может предположить интуиция, движение на сфере совсем не похоже на движение на плоскости, даже локально (совсем); Внутренняя кривизна сферы означает, что игроки могут выполнять действия, которые будут вращаться сами!
Для самого экстремального примера из того, о чем я говорю, представьте, что игрок начинает с точки на экваторе (для удобства мы представим циферблат часов, нанесенный сверху на экватор, и поместим игрока в 6 часов). ) лицом вверх, то есть к Северному полюсу. Предположим, игрок проходит весь путь до Северного полюса; тогда они будут направлены прямо к точке 12 часов. Теперь позвольте игроку двигаться прямо направо от Северного полюса обратно к экватору; они окажутся в точке 3 часа - но потому что их лицо не меняется, когда они движутся вправо(идея в том, что их облик не меняется независимо от того, как они двигаются), они все равно будут стоять перед точкой 12 часов - теперь они смотрят вдоль экватора! Теперь позвольте им двигаться «назад» назад к их начальной точке (6 часов); тогда они будут по-прежнему обращены вдоль экватора, поэтому они будут направлены к точке 3 часа - простое движение по сфере без изменения их «личной» ориентации заставило их повернуть лицом к северному полюсу в направлении лицом вдоль экватора! В некотором смысле, это продолжение старой шутки «охотник движется на милю к югу, на милю к западу, а затем на милю к северу» - но здесь мы пользуемся искривлением сферы, чтобы изменить направление. Обратите внимание, что тот же эффект все еще происходит даже в гораздо меньших масштабах;
К счастью, кватернионы (как вы сами отметили) справляются с этой ситуацией; поскольку кватернион представляет собой произвольное вращение, он фактически представляет произвольную «точку плюс ориентация» на сфере: представьте, что вы начинаете с «трехосной оси» в начале координат и задаете ей произвольное вращение, а затем перемещаете одну единицу в любом направлении, в котором повернуты оси ». Точки оси Z; небольшая мысль убедит вас в том, что это приведет вас к точке на сферной единице с некоторой «ориентацией» (т. е. некоторым расположением осей X и Y вашей трехоси) и что вы можете добраться до каждой точки + ориентации на единичная сфера таким образом (просто назначьте свою ось Z так, чтобы она указывала вдоль линии от начала координат до точки на сфере, а затем перенесите ваши триаксы обратно в начало координат вдоль этой линии). Более того, поскольку умножение кватернионов соответствует составу вращений, каждая из описываемых вами операций может быть представлена путем умножения вашей «текущей ориентации» на соответствующим образом выбранный кватернион: в частности, поскольку (единичный) кватернион (qx, qy, qz, qw) означает «повернуть вокруг оси (qx, qy, qz) на arccos (qw)», затем (в зависимости от вашего конкретного выбора системы координат и позволить c_a быть cos (alpha) и s_a sin (alpha)) двумя из три кватерниона M_x = (s_a, 0, 0, c_a), M_y = (0, s_a, 0, c_a) и M_z = (0, 0, s_a, c_a) будут представлять 'вращаться (т.е. двигаться) в направлении I Сейчас я нахожусь лицом к альфе »и« вращаюсь в направлении, перпендикулярном тому, с которым я сейчас сталкиваюсь альфа ». (Третий из этих кватернионов будет представлять «вращать моего персонажа вокруг своей оси»Cur_q = M_x * Cur_q
если игрок нажал вверх, или Cur_q = M_y * Cur_q
если игрок нажал вправо (или, возможно, что-то вроде, Cur_q = M_yinv * Cur_q
если игрок нажал влево, где M_yinv - это «инверсия» кватерниона M_y, представляющая вращение в другом направлении). Обратите внимание, что вы должны быть осторожны, к какой «стороне» вы применяете поворот, будь то предварительное или повторное умножение; Откровенно говоря, это может быть проще всего решить методом проб и ошибок, попробовав умножения и выяснив, какие из них работают.
Переход от обновленного кватерниона к точке на сфере (и к ориентации вашего персонажа) также относительно прост: в соответствии с последним параграфом все, что вам нужно сделать, это использовать свой кватернион на базисных векторах (1, 0,0), (0,1,0) и (0,0,1) вашего кадра с помощью операции «повернуть вектор по кватерниону» v → qvq -1 (где умножения здесь являются умножениями на кватернионы, и мы идентифицируем вектор v = (x, y, z) с «вырожденным кватернионом» (x, y, z, 0)). Например, положение на единичной сфере определяется простым преобразованием вектора z: pos = (qx, qy, qz, qw) * (0, 0, 1, 0) * (-qx, -qy, -qz, qw) = (qx, qy, qz, qw) * (qy, -qx, qw, qz) = (2 (qy * qw + qz * qx), 2 (qz * qy-qw * qx), (qz ^ 2 + qw ^ 2) - (qx ^ 2 + qy ^ 2), 0), поэтому(2(qy*qw+qz*qx), 2(qz*qy-qw*qx), (qz^2+qw^2)-(qx^2+qy^2))
будут координаты «преобразованного» пользователя на единичной сфере (и, чтобы получить координаты на произвольной сфере, конечно, вы просто умножите их на радиус сферы); аналогичные расчеты работают для других осей, например, для определения направления движения пользователя.