Я пытаюсь повернуть камеру WebGL, используя кватернионные преобразования из glMatrix. Проблема в том, что я мало знаю о кватернионах. (Я знаю о них только потому, что пытаюсь сделать камеру без блокировки карданного подвеса.) Приведенный ниже код должен поворачивать камеру вверх / вниз / влево / вправо в зависимости от положения мыши.
glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
var rotateCamera = function (xDiff, yDiff){
// glMatrix.vec3.sub(cameraLookNormal, cameraLookAt, cameraPos);
// glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
// glMatrix.vec3.normalize(cameraLookNormal, cameraLookNormal);
glMatrix.mat3.fromQuat(mat, rotation);
horizontalVect = glMatrix.vec3.fromValues(mat[1], mat[4], mat[7]);
verticalVect = glMatrix.vec3.fromValues(mat[0], mat[3], mat[6]);
glMatrix.quat.setAxisAngle(horizontalQuat, horizontalVect, glMatrix.glMatrix.toRadian(xDiff));
glMatrix.quat.multiply(rotation, rotation, horizontalQuat);
// glMatrix.quat.normalize(rotation, rotation);
glMatrix.vec3.transformQuat(cameraLookAt, cameraLookAt, rotation);
glMatrix.mat4.lookAt(viewMatrix, cameraPos, cameraLookAt, [0, 1, 0]);
gl.uniformMatrix4fv(matViewUniformLocation, gl.FALSE, viewMatrix);
glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
glMatrix.quat.setAxisAngle(verticalQuat, verticalVect, glMatrix.glMatrix.toRadian(yDiff));
glMatrix.quat.multiply(rotation, rotation, verticalQuat);
// glMatrix.quat.normalize(rotation, rotation);
glMatrix.vec3.transformQuat(cameraLookAt, cameraLookAt, rotation);
Однако , этот код просто заставляет камеру сильно дрожать, когда я двигаю мышь (я думаю, она возвращается к исходной точке). Я попытался напечатать положение камеры в положении, чтобы разобраться в рифме или причине дрожания, но безрезультатно. Если вместо использования позиции cameraLookAt я использую вектор cameraLookAt - cameraPos
, то есть текущий вектор обзора в vec3.transformQuat, это позволяет мне вращать камеру, но все еще очень сильно дрожит (объект продолжает прыгать на экране и за его пределами) , Этот вид работает несмотря на встряхивание, но также вносит некоторые непреднамеренные изменения. Код для этой альтернативной версии приведен ниже:
glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
var rotateCamera = function (xDiff, yDiff){
glMatrix.vec3.sub(cameraLookNormal, cameraLookAt, cameraPos);
// glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
// glMatrix.vec3.normalize(cameraLookNormal, cameraLookNormal);
glMatrix.mat3.fromQuat(mat, rotation);
horizontalVect = glMatrix.vec3.fromValues(mat[1], mat[4], mat[7]);
verticalVect = glMatrix.vec3.fromValues(mat[0], mat[3], mat[6]);
glMatrix.quat.setAxisAngle(horizontalQuat, horizontalVect, glMatrix.glMatrix.toRadian(xDiff));
glMatrix.quat.multiply(rotation, rotation, horizontalQuat);
// glMatrix.quat.normalize(rotation, rotation);
glMatrix.vec3.transformQuat(cameraLookAt, cameraLookNormal, rotation);
glMatrix.mat4.lookAt(viewMatrix, cameraPos, cameraLookAt, [0, 1, 0]);
gl.uniformMatrix4fv(matViewUniformLocation, gl.FALSE, viewMatrix);
glMatrix.quat.setAxes([0, 0, 1], [1, 0, 0], [0, 1, 0], rotation);
glMatrix.quat.setAxisAngle(verticalQuat, verticalVect, glMatrix.glMatrix.toRadian(yDiff));
glMatrix.quat.multiply(rotation, rotation, verticalQuat);
// glMatrix.quat.normalize(rotation, rotation);
glMatrix.vec3.transformQuat(cameraLookAt, cameraLookNormal, rotation);
Было бы очень полезно, если бы вы могли объяснить, как исправить этот код, или, альтернативно, как сделать камеру в WebGL (нет библиотек, кроме glMatrix разрешено), что не имеет блокировки карданного подвеса. Программа javascript доступна по адресу: https://codeshare.io/aY1dl3
Я основал свой код на этом предложенном решении, если это поможет: https://gamedev.stackexchange.com/questions/46123/how-can-i-create-a-webgl-camera-based-on-quaternions
Заранее спасибо.