我对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)
然后立方体可以旋转,但问题是立方体在其自己的轴上旋转,因此在旋转后,它无法按预期旋转。
我找到了页面How to rotate a Three.js Vector3 around an axis?,但它只是让一个Vector3点围绕世界轴旋转?
我尝试使用 matrixRotationWorld 作为
@mesh.matrixRotationWorld.x += x * Math.PI / 180
@mesh.matrixRotationWorld.y += y * Math.PI / 180
@mesh.matrixRotationWorld.z += z * Math.PI / 180
但它不起作用,我不知道我是以错误的方式使用它还是有其他方式..
那么,如何让3D立方体绕世界轴旋转???
答案 0 :(得分:52)
从版本r59开始,three.js提供了这三个函数来围绕对象轴旋转对象。
object.rotateX(angle);
object.rotateY(angle);
object.rotateZ(angle);
答案 1 :(得分:47)
以下是我使用的两个功能。它们基于矩阵旋转。并可以围绕任意轴旋转。要使用世界的轴旋转,您需要使用第二个函数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);
答案 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 );
}
答案 3 :(得分:10)
使用r55你必须改变
rotationMatrix.multiplySelf(object.matrix);
到
rotationMatrix.multiply(object.matrix);
答案 4 :(得分:7)
在Three.js R59中,object.rotation.setEulerFromRotationMatrix(object.matrix);
已更改为object.rotation.setFromRotationMatrix(object.matrix);
3js变化如此之快:D
答案 5 :(得分:6)
以防万一......在r52中,该方法被称为setEulerFromRotationMatrix
而不是getRotationFromMatrix
答案 6 :(得分:3)
在r59附近,这变得更容易(围绕x旋转):
bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
obj.position.applyEuler(euler);
}
答案 7 :(得分: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
答案 8 :(得分:1)
我用这种方式解决了这个问题:
我为ThreeJS创建了'ObjectControls'模块,允许您旋转单个OBJECT(或组),而不是SCENE。
包括图书馆:
<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。