Допустим, текущую перспективу сцены можно представить как q_c . Когда мышь перемещается вправо, вы хотите, чтобы q_c начал вращаться вокруг своей собственной оси y (при условии, что y равно up, x равно вправо и -z равно вперед ) на величину, возможно, пропорциональную смещению мыши. Таким образом, вы обычно формируете новый кватернион из представления оси / угла q_y = quatFromAxisAngle(turnRate,0,1,0)
: поверните на turnRate вокруг оси y . Затем вы применяете это преобразование к своему кватерниону, чтобы получить новую перспективу на сцене: q_c ' = q_y * q_c (конечно, с использованием умножения кватернионов).
Теперь, если вы хотите добавить некоторый локальный «крен» в перспективу, вам просто нужно сделать то же самое вокруг оси z , но сохранить копию «развернутого» перспектива:
q_z = quatFromAxisAngle(roll,0,0,-1)
q_d = q_z * q_c '.
Затем вы используете q_d для отображения сцены, но потом выбрасываете ее и всегда работаете с q_c . Таким образом, вы сохраняете постоянную ось up , чтобы вращаться, и когда вы закончите «катиться», вы просто прекращаете применять это окончательное вращение вокруг локальной оси «z».