如何在轴世界上旋转一个物体three.js?

时间:2012-06-20 12:39:48

标签: javascript three.js

是否可以旋转世界轴而不是物体?

我需要对物体进行一些旋转,但在第一次旋转后,我无法像我想的那样进行其他旋转。

如果无法在世界轴上进行旋转,我的第二个选择是在第一次旋转后重置轴。这有什么功能吗?

我无法使用object.eulerOrder,因为在我进行一些轮换后设置object.eulerOrder="YZX"时,它会更改对象的方向。

5 个答案:

答案 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中效果很好。 希望它有所帮助。