I have the following function that rotates the X and Y axes on the global axes but Z rotates it on the object’s local axis. How can I make the 3 axes rotate Globally? Thanks!!!
function setObjectRotation(object, rotationAngles) {
const xRad = THREE.MathUtils.degToRad(rotationAngles.x);
const yRad = THREE.MathUtils.degToRad(rotationAngles.y);
const zRad = THREE.MathUtils.degToRad(rotationAngles.z);
object.quaternion.identity();
const xAxis = new THREE.Vector3(1, 0, 0);
const yAxis = new THREE.Vector3(0, 1, 0);
const zAxis = new THREE.Vector3(0, 0, 1);
const qx = new THREE.Quaternion().setFromAxisAngle(xAxis, xRad).normalize();
const qy = new THREE.Quaternion().setFromAxisAngle(yAxis, yRad).normalize();
const qz = new THREE.Quaternion().setFromAxisAngle(zAxis, zRad).normalize();
object.quaternion.multiply(qy);
object.quaternion.multiply(qx);
object.quaternion.multiply(qz);
Hi,
To achieve global rotation for all three axes, you should first create a single quaternion that represents the combined rotation of all three axes. This can be done by multiplying the quaternions in the correct order. The correct order for global rotation is to apply the Z rotation first, followed by the Y rotation, and finally the X rotation.
Code here.
function setObjectRotation(object, rotationAngles) {
const xRad = THREE.MathUtils.degToRad(rotationAngles.x);
const yRad = THREE.MathUtils.degToRad(rotationAngles.y);
const zRad = THREE.MathUtils.degToRad(rotationAngles.z);
// Reset the object's quaternion to identity
object.quaternion.identity();
// Create quaternions for each axis
const qx = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), xRad);
const qy = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), yRad);
const qz = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 0, 1), zRad);
// Combine the quaternions in the correct order for global rotation
object.quaternion.multiply(qz); // Z rotation first
object.quaternion.multiply(qy); // Y rotation second
object.quaternion.multiply(qx); // X rotation last
}
1 Like
Thank you very much Mario! I have tried your code but the X axis continues to act in local mode. The Y and Z axes are now in global mode but X rotates in local. It seems that the last axis I multiply is always local.
To fix this issue, we need to change the order of quaternion multiplication. We should multiply the quaternions in the reverse order to ensure that the X-axis rotation is applied first, followed by the Y and Z rotations.
object.quaternion.multiply(qx); // X rotation first
object.quaternion.multiply(qy); // Y rotation second
object.quaternion.multiply(qz); // Z rotation last
I want to hear from you.
With this new change, X rotates well in global, Y is in the global axis of Z and Z is in local. The truth is that I’m going crazy with this
I have tried all 6 order combinations and none of the options work with all 3 axes in global mode.
Could you send me current code and requirement?
1 Like
Hello. I call this function every frame sending it 3 angles. The X and Y axes rotate in global axes but X rotates in the local X axis of the object. Everything works fine but the problem is that X rotates on the local axis.
The code of the entire application is very extensive. What I’m doing is creating a system that saves the total rotations of objects in degrees. For example, an object may have a cumulative rotation of (967,892,-450). I then interpolate these values and call the function that performs the rotation.
const lerpRotation = {
x: { total: THREE.MathUtils.lerp(prevKeyframe.userDataRotation.x.total, nextKeyframe.userDataRotation.x.total, interpolatedT) },
y: { total: THREE.MathUtils.lerp(prevKeyframe.userDataRotation.y.total, nextKeyframe.userDataRotation.y.total, interpolatedT) },
z: { total: THREE.MathUtils.lerp(prevKeyframe.userDataRotation.z.total, nextKeyframe.userDataRotation.z.total, interpolatedT) }
};
setObjectRotation(object, {
x: lerpRotation.x.total,
y: lerpRotation.y.total,
z: lerpRotation.z.total
});
function setObjectRotation(object, rotationAngles) {
const xRad = THREE.MathUtils.degToRad(rotationAngles.x);
const yRad = THREE.MathUtils.degToRad(rotationAngles.y);
const zRad = THREE.MathUtils.degToRad(rotationAngles.z);
// Reset the object's quaternion to identity
object.quaternion.identity();
// Crea cuaterniones para cada eje global
const xAxis = new THREE.Vector3(1, 0, 0);
const yAxis = new THREE.Vector3(0, 1, 0);
const zAxis = new THREE.Vector3(0, 0, 1);
// Create quaternions for each axis
const qx = new THREE.Quaternion().setFromAxisAngle(xAxis, xRad);
const qy = new THREE.Quaternion().setFromAxisAngle(yAxis, yRad);
const qz = new THREE.Quaternion().setFromAxisAngle(zAxis, zRad);
// Combine the quaternions in the correct order for global rotation
object.quaternion.multiply(qz); // X rotation first
object.quaternion.multiply(qy); // Y rotation second
object.quaternion.multiply(qx); // Z rotation last
// Actualizar las matrices del objeto
object.updateMatrix();
object.updateMatrixWorld();
// object.quaternion.multiplyQuaternions(qz, qy); //Z esta en local
}