rotateOnWorldAxis() rotating descendant meshes from imported gltf model on local axes instead of global axes

Hey, I’m working on a project at the moment, and I’m trying to get multiple THREE.Group objects that were descendants of a gltf model I imported to rotate about a global axis. However, it’s not working, and each of these descendant objects are rotating about their local axis instead of global.

The code I had at the moment was the following (cut out irrelevant parts):

const loader = new GLTFLoader()
let rubiksCube = new THREE.Mesh() // create Rubik's cube

function modelLoader(url) {
    return new Promise((resolve, reject) => {
        loader.load(url, (data) => resolve(data), null, undefined, function (error) {
            console.error(error)
        })
    })
}

const gltfData = await modelLoader('/assets/models/rubiks.gltf')
rubiksCube = gltfData.scene

scene.add(rubiksCube)

let rb = new RubiksCube(rubiksCube)

/* skipped extra implementation code */

rb.coordinateMap[0][0][0].mesh = rb.gltf.children[i]

let sampleAxis = new THREE.Vector3(0, 1, 0)

function animate() {
    ...
    // this line causes the piece to rotate on its local axis instead of global
    rb.coordinateMap[0][0][0].mesh.rotateOnWorldAxis(
        /* Axis to rotate around */,
        0.001)
	requestAnimationFrame( animate )
	renderer.render( scene, camera )
}

Does anyone happen to know why this could be happening? For additional context that might be important, when I had the gltf file (which I exported from Blender) created such that the origin of each of the meshes in it were at (0, 0, 0), this big with rotateOnWorldAxis() did not occur. It started to do this after I chanced the original Blender file to have the origins for each of the meshes be located at the center of mass for each one.

Update: I tried out this prototype I found on Stack Overflow (copied and pasted in file) and it worked:

THREE.Object3D.prototype.rotateAroundWorldAxis = function() {
    let q = new THREE.Quaternion();
    return function rotateAroundWorldAxis( point, axis, angle ) {

        q.setFromAxisAngle( axis, angle );
        this.applyQuaternion( q );

        this.position.sub( point );
        this.position.applyQuaternion( q );
        this.position.add( point );
        return this;
    }
}();

...

function animate() {
    ...

    // rotateAroundWorldAxis() function call
    /* mesh */.rotateAroundWorldAxis(
        new THREE.Vector3(0, 0, 0),
        /* Axis to rotate around */,
        0.01)
    
	requestAnimationFrame( animate )
	renderer.render( scene, camera )
}
1 Like