Three.js : Как повернуть сферу вокруг оси, используя значения поворота камеры

#three.js #rotation

#three.js #вращение

Вопрос:

У меня есть специальный control вызов SphericalControls . Это похоже на OrbitControls , но оно удерживает камеру в нужном положении 0,0,0 и вместо этого поворачивает камеру на x и y, чтобы осмотреть сцену. Он помещается в середину a SphereBufferGeometry , на которую проецируется равноугольное изображение на 360 градусов. Пользователь может просматривать изображение на 360 градусов, и при этом значения поворота камеры x и y меняются.

Когда пользователь нажимает кнопку, мне нужно взять эти значения поворота по x и y и повернуть сферу в соответствии с поворотом камеры. Затем я вернул камере значения x: 0 и y: 0.

В результате камера сбрасывается, и сцена на 360 градусов теперь повернута, чтобы показать тот же вид поворота, на который ранее смотрела камера. Таким образом, для пользователя представление остается в основном статичным, просто значения для camera.rotation и вращения сферы поменялись местами.

Это отлично работает, если я смещаю текстуру на сфере:

 sphereObj.material.map.wrapS = THREE.RepeatWrapping;
sphereObj.material.map.offset.x = ((camera.rotation.x) / (Math.PI * 2));
sphereObj.material.map.needsUpdate = true;
sphereObj.material.needsUpdate = true;

camera.rotation.set(0, 0);
// Success!
  

Но то, что мне нужно сделать, это не смещать текстуру, а поворачивать всю геометрию. Я пробовал:

 var axis = new THREE.Vector3(0, 1, 0).normalize();;
var offsetRadian = ((camera.rotation.x) / (Math.PI * 2));
sphere.rotateOnAxis(axis, offsetRadian);
// Fail
  

Но в результате вращение сферы отключено примерно на 30%. Любая помощь приветствуется.

Ответ №1:

Данные о вращении каждого объекта хранятся в соответствующем .quaternion объекте. Оба camera и sphereObj имеют кватернион, поэтому вы можете скопировать данные вращения камеры в сферу:

 // Get camera's rotation
targetRotation = camera.quaternion;

// Invert rotation
targetRotation.inverse();

// Set sphere's rotation
sphereObj.quaternion.copy(targetRotation);
camera.rotation.set(0, 0, 0);
  

Я не совсем уверен, нужна ли вам .inverse() линия… если вы заметили, что сфера вращается в противоположном направлении, просто избавьтесь от нее, чтобы получить желаемый результат.