Если у камеры никогда нет рулона (как это часто бывает во многих играх, например, в шутерах от первого лица), решение простое.Если есть бросок, то есть дополнительный шаг.Я начну с того, что делать, если нет крена, и обобщу решение о том, что делать, если есть.
Пусть qc будет поворотом камеры.Позвольте qy вращение с тем же рысканием, что и qc, но с нулевым шагом.Если крена нет, вращение камеры - это вращение вокруг оси, за которым следует поворот шага:
qc = qp * qy
Мы можем восстановить вращение шага qp как вращение от qy до qc:
qp = qc * qy^-1
Хитрость заключается в том, чтобы построить qy, поэтому мы можем включить его в вышеприведенное уравнение для решения для qp.Пусть vc будет единичным вектором, указывающим из объектива камеры, или «вектором вперед».Пусть vy будет тем же вектором, но спроецирован на горизонтальную плоскость и нормализован.Наконец, пусть v0 будет прямым вектором, когда поворот камеры qc является единичным поворотом.Вращение, которое вращает v0 в vy, является вращением рыскания.Угол может быть задан как:
yaw = asin(Norm(cross(v0, vy)))
Соответствующее вращение вокруг оси равно:
qy = { cos(yaw/2), up * sin(yaw/2) }
Где «вверх» - единичный вектор в направлении вверх, то есть ось для поворотов рыскания.,Вставьте это в qp = qy ^ -1 * qc выше, чтобы получить кватернион высоты тона qp.Наконец, получим угол тангажа из qp следующим образом:
pitch = 2*asin(Dot(right, [qp[1], qp[2], qp[3]]))
Где «право» - это единичный вектор в правильном направлении, то есть ось для вращения тангажа.
Как я уже говорил, вещиусложняется, если камера также имеет рулон, но общая стратегия та же.Вы формулируете поворот камеры как произведение компонентов вращения, а затем изолируете нужный компонент (в данном случае шаг).Например, если последовательность эйлера, которую вы используете для определения «высоты тона», является обычной последовательностью вращения рыскания-рыскания, вы определяете qc как:
qc = qr * qp * qy
. Мы можем определить переменную qx как объединенную высоту иВращения броска:
qx = qr * qp
Теперь мы можем записать qc как:
qc = qx * qy
Мы уже знаем, как решить для qx в этой форме, повторяя шаги, которые мы использовали выше для решения дляQP.Переставляя определение для qx, мы получаем:
qp = qr^-1 * qx
Мы только что решили для qx, поэтому, чтобы найти вращение основного тона qp, нам нужен только бросок qr.Мы можем построить его, используя векторы, как мы делали ранее.Пусть vc снова будет вектором вперед.Бросок будет вращением вокруг этого вектора.Пусть vu будет вектором работы камеры (в мировых координатах), и пусть vu0 будет вектором работы камеры с нулевым креном.Мы можем построить vu0, спроецировав глобальный вектор вверх на плоскость, перпендикулярную vc, а затем нормализовав.Вращение крена qr - это поворот от vu0 к vu.Ось этого вращения - прямой вектор vc.Угол крена равен
roll = asin(Dot(vc, cross(vu0, vu)))
Соответствующий кватернион равен:
qr = { cos(roll/2), forward * sin(roll/2) }
Где «вперед» - ось вращения крена.