是否可以以世界而不是物体的轴为轴进行旋转?
我需要对一个对象进行一些旋转,但是在第一次旋转之后,我不能像我想要的那样进行其他旋转。
如果无法在世界轴上进行旋转,我的第二个选择是在第一次旋转后重置轴。有什么功能吗?
我不能使用,因为当我在一些旋转后object.eulerOrder
设置时它会改变我的对象的方向。object.eulerOrder="YZX"
是否可以以世界而不是物体的轴为轴进行旋转?
我需要对一个对象进行一些旋转,但是在第一次旋转之后,我不能像我想要的那样进行其他旋转。
如果无法在世界轴上进行旋转,我的第二个选择是在第一次旋转后重置轴。有什么功能吗?
我不能使用,因为当我在一些旋转后object.eulerOrder
设置时它会改变我的对象的方向。object.eulerOrder="YZX"
更新:三 - 0.125.2
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 的更新答案(在 上测试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);
}
@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 中效果很好。希望能帮助到你。