40

我对three.js 中的旋转有一个很大的问题我想在我的一个游戏中旋转我的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 提供了这三个函数来围绕对象轴旋转对象。

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

这是我使用的两个函数。它们基于矩阵旋转。并且可以绕任意轴旋转。要使用世界轴旋转,您需要使用第二个函数 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

以防万一...在 r52 中调用该方法setEulerFromRotationMatrix而不是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 回答
2

我是这样解决的:

我为 ThreeJS 创建了“ObjectControls”模块,它允许您旋转单个 OBJECT(或组),而不是 SCENE。

包括库:

<script src="ObjectControls.js"></script>

用法:

var controls = new ObjectControls(camera, renderer.domElement, yourMesh);

你可以在这里找到一个现场演示:https ://albertopiras.github.io/threeJS-object-controls/

这是回购:https ://github.com/albertopiras/threeJS-object-controls 。

于 2017-09-20T16:06:25.497 回答