是否可以旋转世界轴而不是物体?
我需要对物体进行一些旋转,但在第一次旋转后,我无法像我想的那样进行其他旋转。
如果无法在世界轴上进行旋转,我的第二个选择是在第一次旋转后重置轴。这有什么功能吗?
我无法使用object.eulerOrder
,因为在我进行一些轮换后设置object.eulerOrder="YZX"
时,它会更改对象的方向。
答案 0 :(得分:15)
是的,您可以使用在three.js github问题上提供的函数来执行此操作:
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);
rotWorldMatrix.multiply(object.matrix); // pre-multiply
object.matrix = rotWorldMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}
然后
//rotate 30 degrees on world X
rotateAroundWorldAxis(cube, new THREE.Vector3(1,0,0), 30 * Math.PI/180);
请参阅我的示例 - http://jsfiddle.net/SCXNQ/156/
答案 1 :(得分:2)
这是一个小变化。用r56测试。
THREE.Object3D._matrixAux = new THREE.Matrix4(); // global auxiliar variable
// Warnings: 1) axis is assumed to be normalized.
// 2) matrix must be updated. If not, call object.updateMatrix() first
// 3) this assumes we are not using quaternions
THREE.Object3D.prototype.rotateAroundWorldAxis = function(axis, radians) {
THREE.Object3D._matrixAux.makeRotationAxis(axis, radians);
this.matrix.multiplyMatrices(THREE.Object3D._matrixAux,this.matrix); // r56
THREE.Object3D._matrixAux.extractRotation(this.matrix);
this.rotation.setEulerFromRotationMatrix(THREE.Object3D._matrixAux, this.eulerOrder );
this.position.getPositionFromMatrix( this.matrix );
}
THREE.Object3D.prototype.rotateAroundWorldAxisX = function(radians) {
this._vector.set(1,0,0);
this.rotateAroundWorldAxis(this._vector,radians);
}
THREE.Object3D.prototype.rotateAroundWorldAxisY = function(radians) {
this._vector.set(0,1,0);
this.rotateAroundWorldAxis(this._vector,radians);
}
THREE.Object3D.prototype. rotateAroundWorldAxisZ = function(degrees){
this._vector.set(0,0,1);
this.rotateAroundWorldAxis(this._vector,degrees);
}
最后三行只是为了重新同步矩阵中的(position,rotation)
...我想知道是否有更有效的方法来做到这一点......
答案 2 :(得分:2)
在r59左右,这变得更加容易(围绕x旋转):
bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
obj.position.applyEuler(euler);
}
答案 3 :(得分:2)
@Neil的最新答案(已在r98
上进行了测试)
function rotateAroundWorldAxis(obj, axis, radians) {
let rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
rotWorldMatrix.multiply(obj.matrix);
obj.matrix = rotWorldMatrix;
obj.setRotationFromMatrix(obj.matrix);
}
答案 4 :(得分:0)
@acarlon你的答案可能已经结束了一周的挫折。我已经完善了你的功能了。这是我的变化。我希望这可以节省别人花费20多个小时来解决这个问题。
function calcRotationAroundAxis( obj3D, axis, angle ){
var euler;
if ( axis === "x" ){
euler = new THREE.Euler( angle, 0, 0, 'XYZ' );
}
if ( axis === "y" ){
euler = new THREE.Euler( 0, angle, 0, 'XYZ' );
}
if ( axis === "z" ){
euler = new THREE.Euler( 0, 0, angle, 'XYZ' );
}
obj3D.position.applyEuler( euler );
}
function calcRotationIn3D( obj3D, angles, order = 'XYZ' ){
var euler;
euler = new THREE.Euler( angles.x, angles.y, angles.z, order );
obj3D.position.applyEuler( euler );
}
这在r91中效果很好。 希望它有所帮助。