Three.jsの回転に大きな問題があります。ゲームの1つで3Dキューブを回転させたいのです。
//init
geometry = new THREE.CubeGeometry grid, grid, grid
material = new THREE.MeshLambertMaterial {color:0xFFFFFF * Math.random(), shading:THREE.FlatShading, overdraw:true, transparent: true, opacity:0.8}
for i in [[email protected]]
othergeo = new THREE.Mesh new THREE.CubeGeometry(grid, grid, grid)
othergeo.position.x = grid * @shape[i][0]
othergeo.position.y = grid * @shape[i][1]
THREE.GeometryUtils.merge geometry, othergeo
@mesh = new THREE.Mesh geometry, material
//rotate
@mesh.rotation.y += y * Math.PI / 180
@mesh.rotation.x += x * Math.PI / 180
@mesh.rotation.z += z * Math.PI / 180
および(x、y、z)は(1、0、0)
キューブは回転できますが、問題はキューブがそれ自体の軸で回転するため、キューブが回転した後、期待どおりに回転できないことです。
ページが見つかりました 軸を中心にThree.js Vector3を回転させる方法? ですが、Vector3ポイントを世界の軸を中心に回転させるだけですか?
そして、私はmatrixRotationWorldを使用しようとしました
@mesh.matrixRotationWorld.x += x * Math.PI / 180
@mesh.matrixRotationWorld.y += y * Math.PI / 180
@mesh.matrixRotationWorld.z += z * Math.PI / 180
しかし、それは機能しません。間違った方法で使用したか、他の方法があるかはわかりません。
だから、3Dキューブを世界の軸の周りに回転させる方法???
ここに私が使用する2つの関数があります。それらはマトリックスの回転に基づいています。また、任意の軸を中心に回転できます。ワールドの軸を使用して回転するには、2番目の関数rotateAroundWorldAxis()を使用します。
// Rotate an object around an arbitrary axis in object space
var rotObjectMatrix;
function rotateAroundObjectAxis(object, axis, radians) {
rotObjectMatrix = new THREE.Matrix4();
rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
// old code for Three.JS pre r54:
// object.matrix.multiplySelf(rotObjectMatrix); // post-multiply
// new code for Three.JS r55+:
object.matrix.multiply(rotObjectMatrix);
// old code for Three.js pre r49:
// object.rotation.getRotationFromMatrix(object.matrix, object.scale);
// old code for Three.js r50-r58:
// object.rotation.setEulerFromRotationMatrix(object.matrix);
// new code for Three.js r59+:
object.rotation.setFromRotationMatrix(object.matrix);
}
var rotWorldMatrix;
// Rotate an object around an arbitrary axis in world space
function rotateAroundWorldAxis(object, axis, radians) {
rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
// old code for Three.JS pre r54:
// rotWorldMatrix.multiply(object.matrix);
// new code for Three.JS r55+:
rotWorldMatrix.multiply(object.matrix); // pre-multiply
object.matrix = rotWorldMatrix;
// old code for Three.js pre r49:
// object.rotation.getRotationFromMatrix(object.matrix, object.scale);
// old code for Three.js pre r59:
// object.rotation.setEulerFromRotationMatrix(object.matrix);
// code for r59+:
object.rotation.setFromRotationMatrix(object.matrix);
}
したがって、anim
関数(requestAnimFrameコールバック)内でこれらの関数を呼び出す必要があります。その結果、x軸が90度回転します。
var xAxis = new THREE.Vector3(1,0,0);
rotateAroundWorldAxis(mesh, xAxis, Math.PI / 180);
リリースr59以降、three.jsは、オブジェクトをオブジェクト軸の周りに回転させるこれらの3つの関数を提供します。
object.rotateX(angle);
object.rotateY(angle);
object.rotateZ(angle);
rotateAroundWorldAxis
関数が必要でしたが、上記のコードは最新リリース(r52)では機能しません。 getRotationFromMatrix()
がsetEulerFromRotationMatrix()
に置き換えられたようです
function rotateAroundWorldAxis( object, axis, radians ) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis( axis.normalize(), radians );
rotationMatrix.multiplySelf( object.matrix ); // pre-multiply
object.matrix = rotationMatrix;
object.rotation.setEulerFromRotationMatrix( object.matrix );
}
r55では、変更する必要があります
rotationMatrix.multiplySelf(object.matrix);
に
rotationMatrix.multiply(object.matrix);
Three.js R59では、object.rotation.setEulerFromRotationMatrix(object.matrix);
がobject.rotation.setFromRotationMatrix(object.matrix);
に変更されました
3jsは急速に変化しています:D
念のため... r52では、メソッドはsetEulerFromRotationMatrix
ではなくgetRotationFromMatrix
と呼ばれます
R59の周りのどこかでこれは簡単になります(xを中心に回転):
bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
obj.position.applyEuler(euler);
}
Three.js R66では、これが私が使用するものです(CoffeeScriptバージョン):
THREE.Object3D.prototype.rotateAroundWorldAxis = (axis, radians) ->
rotWorldMatrix = new THREE.Matrix4()
rotWorldMatrix.makeRotationAxis axis.normalize(), radians
rotWorldMatrix.multiply this.matrix
this.matrix = rotWorldMatrix
this.rotation.setFromRotationMatrix this.matrix
この方法でこの問題を解決しました。
SCENEではなく、単一のOBJECT(またはGroup)を回転できるThreeJS用の「ObjectControls」モジュールを作成しました。
ライブラリを含める:
_<script src="ObjectControls.js"></script>
_
使用法:
var controls = new THREE.ObjectControls(camera, renderer.domElement, yourMesh);
ここでライブデモを見つけることができます: https://albertopiras.github.io/threeJS-object-controls/
リポジトリは次のとおりです。 https://github.com/albertopiras/threeJS-object-controls 。