我有对象,每个对象对于每个旋转轴都有一个单独的父对象(1 个用于 X 旋转,1 个用于 Y 旋转,1 个用于 Z 旋转。它们也都按该顺序相互关联:X 旋转对象是 Y 旋转对象的子对象。Y 旋转对象是 Z 旋转对象的子对象)。
我正在尝试制作一个功能,允许用户一起旋转场景中的所有对象(它们都包含在单个 Object3D 中)。当 Object3D 旋转时,程序必须找到所有对象相对于世界的绝对位置和旋转,以便程序可以为每个对象输出新值。
为此,我目前将其设置为移动对象,以便将其在“场景旋转器”(一个 Object3D)内的位置设置为相对于世界的绝对位置。现在,我试图让物体的旋转成为物体相对于世界的绝对旋转,这样当“场景旋转器”的旋转改变时,它也会相应地改变。此外,当我尝试在子对象上运行一次 setFromRotationMatrix 方法时,它无法正常工作,因此,我不得不为每个父对象再次运行它并相应地从它们中获取每个单独的旋转
这是我目前拥有的代码,它应该获得对象相对于世界的绝对旋转:
var beforeRotForX = new THREE.Euler();
beforeRotForX.setFromRotationMatrix(objects[i].parent.matrixWorld, "ZYX");
var beforeRotForY = new THREE.Euler(); // Had to be a separate one for some reason...
beforeRotForY.setFromRotationMatrix(objects[i].parent.parent.matrixWorld, "ZYX");
var beforeRotForZ = new THREE.Euler(); // And apparently this one has to be separate too
beforeRotForZ.setFromRotationMatrix(objects[i].parent.parent.parent.matrixWorld, "ZYX");
// Absolute before rotation
objects[i].userData.sceneBeforeRotAbs = {
x: beforeRotForX.x,
y: beforeRotForY.y,
z: beforeRotForZ.z
};
然后,它必须将该绝对旋转应用于对象的相对旋转
objects[i].parent.rotation.x = objects[i].userData.sceneBeforeRotAbs.x;
objects[i].parent.parent.rotation.y = objects[i].userData.sceneBeforeRotAbs.y;
objects[i].parent.parent.parent.rotation.z = objects[i].userData.sceneBeforeRotAbs.z;
当第二个父母的 Y 旋转在 -90 到 90 之间时,这一切都很好
// Results of absolute world rotation when the Y-rotation of the
// second parent is set to 90 degrees (1.5707... as euler)
objects[i].userData.sceneBeforeRotAbs.x === 0
objects[i].userData.sceneBeforeRotAbs.y === 1.5707963267948966
objects[i].userData.sceneBeforeRotAbs.z === 0
但是当第二个父节点的 Y 旋转低于 -90 或大于 90 时,它会因此为绝对世界 X 旋转和 Y 旋转给出错误的值
// Results of absolute world rotation when the Y-rotation of the
// second parent is set to 91 degrees (1.5882... as euler)
objects[i].userData.sceneBeforeRotAbs.x === 3.141592653589793
objects[i].userData.sceneBeforeRotAbs.y === 1.5533438924131038
objects[i].userData.sceneBeforeRotAbs.z === 0