Использование кватернионов для поворота заставляет мой объект масштабироваться под определенным углом - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь построить контроллер вращения для моих объектов ThreeJS.Мой метод вращения следующий:

function rotate(axis, angle) {
    rotMat = new THREE.Matrix4().makeRotationAxis(axis, angle);
    rotMat.multiply(mesh.matrix);
    rotQuat = new THREE.Quaternion().setFromRotationMatrix(rotMat);
    mesh.quaternion.copy(rotQuat);
    mesh.updateMatrix();
}

Мне нужно сделать это таким образом, чтобы иметь возможность вращаться вокруг мировых осей, а не локальных осей (связанных с этой записью -> Я также не могу использовать элемент вращения Эйлера здесь из-за проблемы, которую я описываю здесь )

Как добраться до моей проблемы:

Я сделал это JSFiddle, которая показывает проблему довольно хорошо.

Как воссоздать:

1) Откройте ссылку скрипта.

2) Нажмите X, Y или Z на клавиатуре, чтобы войтирежим вращения для нужной оси.

3) Удерживайте клавишу «Стрелка вверх» и вращайте, пока происходит «странное» масштабирование.Должно происходить под углом 90-100 градусов.Обратите внимание, что масштабирование продолжается, если вы продолжаете вращаться

Также обратите внимание, что я уменьшаю размер шага вращения (скорость вращения) при переходе к определенной области угла.Масштабирование происходит только тогда, когда размер шага вращения довольно мал.

Мой вопрос:

Кто-нибудь знает, почему вращение вызывает масштабирование?

1 Ответ

0 голосов
/ 21 июня 2019

Причина, по которой это происходит, заключается в том, что вам необходимо передать «чистую» матрицу вращения в метод Quaternion.setFromRotationMatrix.Таким образом, изменение функции поворота на следующее будет работать:

function rotate (axis, angle) {
  rotMat = new THREE.Matrix4().makeRotationAxis(axis, angle);
  rotMat.multiply(mesh.matrix);
  var rotMat2 = new THREE.Matrix4().extractRotation(rotMat);
  rotQuat = new THREE.Quaternion().setFromRotationMatrix(rotMat2);
  mesh.quaternion.copy(rotQuat);
  mesh.updateMatrix();
}
...