8

回転軸ごとに個別の親を持つオブジェクトがあります (X 回転用に 1 つ、Y 回転用に 1 つ、Z 回転用に 1 つ)。それらはすべて、この順序でも互いに関連しています: X 回転オブジェクトは Y 回転オブジェクトの子です。Y 回転オブジェクトは Z 回転オブジェクトの子です)。

ユーザーがシーン内のすべてのオブジェクトを一緒に回転できるようにする機能を作成しようとしています (それらはすべて単一の Object3D に含まれています)。その Object3D が回転するとき、プログラムは、プログラムが各オブジェクトの新しい値を出力できるように、すべてのオブジェクトの絶対位置とワールドに対する回転を見つける必要があります。

これを行うには、現在、Object3D である「シーン回転子」内の位置が世界に対する絶対位置に設定されるように、オブジェクトを移動するように設定しています。今、私はオブジェクトの回転を世界に対するオブジェクトの絶対回転にしようとしているので、「シーンローテーター」の回転が変更されるとそれに応じて変化します。また、setFromRotationMatrix メソッドを子オブジェクトで 1 回だけ実行しようとすると正しく動作しなかったため、代わりに親オブジェクトごとに再度実行し、それに応じて個別の回転を取得する必要がありました。

これは私が現在持っているコードで、世界に対するオブジェクトの絶対回転を取得することになっています:

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;

2 番目の親の 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

しかし、2 番目の親の 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
4

1 に答える 1