簡體   English   中英

如何在軸世界three.js上旋轉對象?

[英]How to rotate a object on axis world three.js?

是否可以以世界軸而不是對象軸進行旋轉?

我需要對一個對象進行一些旋轉,但是在第一次旋轉之后,我無法像我想要的那樣進行其他旋轉。

如果無法在世界軸上進行旋轉,我的第二個選擇是在第一次旋轉后重置軸。 有這個功能嗎?

我不能使用object.eulerOrder因為當我在一些旋轉后設置object.eulerOrder="YZX"時它會改變我的對象的方向。

更新:三 - 0.125.2

演示:codesandbox.io

const THREE = require("three");

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.BoxGeometry(1, 1, 1, 4, 4, 4);
const material = new THREE.MeshBasicMaterial({
  color: 0x628297,
  wireframe: true
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// select the Z world axis
const myAxis = new THREE.Vector3(0, 0, 1);
// rotate the mesh 45 on this axis
cube.rotateOnWorldAxis(myAxis, THREE.Math.degToRad(45));

function animate() {
  // rotate our object on its Y axis,
  // but notice the cube has been transformed on world axis, so it will be tilted 45deg.
  cube.rotation.y += 0.008;
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();

這是一個小的變化。 用 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) ......我想知道是否有更有效的方法來做到這一點......

在 r59 附近的某個地方,這變得容易多了(圍繞 x 旋轉):

bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
    var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
    obj.position.applyEuler(euler);
}

來自@Neil 的更新答案(在r98r98

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);
}

@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 中非常有效。 希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM