可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is it possible to do rotations taking axis of the world and not of the object?
I need to do some rotations of an object, but after the first rotation, I can't do other rotations like i want.
If it's not possible to do rotation on the axis of the world, my second option is to reset the axis after the first rotation. Is there some function for this?
I can't use object.eulerOrder
because it changes the orientation of my object when I set object.eulerOrder="YZX"
after some rotations.
回答1:
Yes you can do it with a function which was supplied on three.js github issues:
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.multiplySelf(object.matrix); // pre-multiply object.matrix = rotWorldMatrix; object.rotation.getRotationFromMatrix(object.matrix, object.scale); }
Then
//rotate 30 degrees on world X rotateAroundWorldAxis(cube, new THREE.Vector3(1,0,0), 30 * Math.PI/180);
See my example - http://jsfiddle.net/SCXNQ/156/
回答2:
Here's a small variation. Tested with 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); }
The three last lines are just to resync the params (position,rotation)
from the matrix... I wonder if there is a more efficient way to do that...
回答3:
Somewhere around r59 this gets a lot easier (rotate around x):
bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX) { var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' ); obj.position.applyEuler(euler); }