Three.js Поворот камеры вокруг объекта (который может перемещаться)

У меня есть камера, которая движется несколькими способами в сцене. Камера должна вращаться вокруг целевого положения. В моем случае это точка на сетке, на которую нацелился пользователь. Поскольку камера обычно не требует перемещения относительно этой точки, я не мог использовать здесь сводную идею: https://github.com/mrdoob/three.js/issues/1830. В моем текущем решении используется следующий код:

var rotationY = new THREE.Matrix4();
var rotationX = new THREE.Matrix4();
var translation = new THREE.Matrix4();
var translationInverse = new THREE.Matrix4();
var matrix = new THREE.Matrix4();
function rotateCameraAroundObject(dx, dy, target) {  
    // collect up and right vectors from camera perspective
    camComponents.up = rotateVectorForObject(new THREE.Vector3(0,1,0), camera.matrixWorld);
    camComponents.right = rotateVectorForObject(new THREE.Vector3(1,0,0), camera.matrixWorld);

    matrix.identity();

    rotationX.makeRotationAxis(camComponents.right, -dx);
    rotationY.makeRotationAxis(camComponents.up, -dy);
    translation.makeTranslation(
        target.position.x - camera.position.x,
        target.position.y - camera.position.y,
        target.position.z - camera.position.z);
    translationInverse.getInverse(translation);

    matrix.multiply(translation).multiply(rotationY).multiply(rotationX).multiply(translationInverse);
    camera.applyMatrix(matrix);
    camera.lookAt(target.position); 
}

Проблема заключается в том, что мы не хотим использовать lookAt из-за переориентации. Мы хотим удалить эту строку.

Если мы используем код выше без lookAt, мы вращаемся вокруг точки, но мы не смотрим на точку. Я понимаю, что мой метод должен вращать представление камеры так же сильно, как и сама камера, но вместо этого камера поворачивается только на небольшое количество. Может ли кто-нибудь помочь мне понять, что случилось?

РЕДАКТИРОВАТЬ: очистите исходный пост и код, чтобы, надеюсь, уточнить мой вопрос.

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

Фактически, я тестирую его без использования матриц перевода, поэтому строка умножения матрицы:

matrix.multiply(rotationY).multiply(rotationX);

и, похоже, он ведет себя одинаково. Спасибо за всю помощь до сих пор!

ОДНА БОЛЬШЕ! Часть проблемы заключается в том, что когда камера ведет себя плохо близко к северным или южным полюсам. Я ищу тип "свободного роуминга".

Ответ 1

Поместите в цикл рендеринга следующее:

camera.position.x = target.position.x + radius * Math.cos( constant * elapsedTime );         
camera.position.z = target.position.z + radius * Math.sin( constant * elapsedTime );
camera.lookAt( target.position );

renderer.render( scene, camera );

В качестве альтернативы вы можете использовать THREE.OrbitControls или THREE.TrackballControls. См. Примеры three.js.

Ответ 2

Замок Gimbal, который вы имеете в виду (переориентация), объясняется использованием углов Эйлера при реализации камеры по умолчанию. Если вы установили

camera.useQuaternion = true;

перед вашим вызовом lookat, тогда углы Эйлера не будут использоваться. Это решит вашу проблему?