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, тогда углы Эйлера не будут использоваться. Это решит вашу проблему?