40

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 [1...@shape.length]
    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 立方体を世界の軸を中心に回転させるにはどうすればよいでしょうか?

4

9 に答える 9

65

リリース r59 以降、three.js はオブジェクト軸を中心にオブジェクトを回転させるこれら 3 つの関数を提供します。

object.rotateX(angle);
object.rotateY(angle);
object.rotateZ(angle);
于 2015-06-20T14:20:33.477 に答える
55

私が使用している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);
于 2012-06-16T05:01:45.177 に答える
13

関数が必要でした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 );
}
于 2012-10-15T23:11:22.323 に答える
9

r55 では、
rotationMatrix.multiplySelf( object.matrix );を変更する必要があります。 RotationMatrix.multiply( object.matrix );


于 2013-01-22T14:23:53.697 に答える
8

Three.js R59 ではobject.rotation.setEulerFromRotationMatrix(object.matrix);object.rotation.setFromRotationMatrix(object.matrix);

3jsは急速に変化しています:D

于 2013-08-18T06:27:37.443 に答える
6

念のため...r52setEulerFromRotationMatrixでは、代わりにメソッドが呼び出されますgetRotationFromMatrix

于 2012-11-07T20:22:47.517 に答える
4

r59のどこかでこれは簡単になります(xを中心に回転):

bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
    var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
    obj.position.applyEuler(euler);
}
于 2014-05-24T11:21:33.380 に答える
2

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
于 2014-03-11T19:40:02.733 に答える