如何在轴three.js上旋转3D对象?

Ton*_*Han 34 javascript coffeescript 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
Run Code Online (Sandbox Code Playgroud)

和(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
Run Code Online (Sandbox Code Playgroud)

但它不起作用,我不知道我是以错误的方式使用它还是有其他方式..

那么,如何让3D立方体围绕世界轴旋转?

小智 54

从版本r59开始,three.js提供了这三个函数来围绕对象轴旋转对象.

object.rotateX(angle);
object.rotateY(angle);
object.rotateZ(angle);
Run Code Online (Sandbox Code Playgroud)

  • 这不应该用于动画!取自[Three.js文档](http://threejs.org/docs/index.html#Reference/Core/Geometry):`这通常作为一次性操作完成,而不是在循环期间使用Object3D.用于典型实时网格旋转的旋转 (3认同)

Cor*_*oss 49

这是我使用的两个功能.它们基于矩阵旋转.并可以围绕任意轴旋转.要使用世界的轴旋转,您需要使用第二个函数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);
}
Run Code Online (Sandbox Code Playgroud)

因此,您应该在anim函数中调用这些函数(requestAnimFrame回调),从而在x轴上旋转90度:

var xAxis = new THREE.Vector3(1,0,0);
rotateAroundWorldAxis(mesh, xAxis, Math.PI / 180);
Run Code Online (Sandbox Code Playgroud)

  • 我得到了有人在github上发布的这两个函数.我必须编辑它们以使用新的函数名称,例如最新版本的threejs版本.我自己也想知道这件事.垃圾收集器会经常摆脱这些对象.我已经查看了Chrome中的内存使用情况图,它会在创建和销毁对象的地方上下移动,但动画看起来很适合我目前使用的所有内容. (3认同)
  • 我得到'对象未定义'错误 (3认同)
  • 小心这种方法!在 Three.js 中,应该对 Object3D 进行直接矩阵操作(使用 object.matrixAutoUpdate = false)或操作旋转、位置等属性。 [three.js docs](http://threejs.org/docs/# Manual/Introduction/Matrix_transformations)进一步`rotateAroundWorldAxis`不适用于应用于对象的非均匀缩放。您必须从`object.matrix`中提取旋转,乘以`rotWorldMatrix`并设置`object.rotation`的组件从结果。 (2认同)

小智 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 );
}
Run Code Online (Sandbox Code Playgroud)


小智 10

使用r55你必须改变
rotationMatrix.multiplySelf(object.matrix);
to
rotationMatrix.multiply(object.matrix);


min*_*d1n 7

在Three.js R59中,object.rotation.setEulerFromRotationMatrix(object.matrix);已经改为object.rotation.setFromRotationMatrix(object.matrix);

3js变化如此之快:D


Lep*_*osy 6

以防万一...在r52中调用该方法setEulerFromRotationMatrix而不是getRotationFromMatrix