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

**URL:** <https://discourse.threejs.org/t/rotateonworldaxis-rotating-descendant-meshes-from-imported-gltf-model-on-local-axes-instead-of-global-axes/86961>\
**Category:** Questions\
**Tags:** rotation, transform, gltf-loader, gltf\
**Created:** [September 13, 2025, 2:29am UTC](https://discourse.threejs.org/t/rotateonworldaxis-rotating-descendant-meshes-from-imported-gltf-model-on-local-axes-instead-of-global-axes/86961 "2025-09-13T02:29:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![GiftGiwa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/giftgiwa/32/15010_2.png) [@GiftGiwa](https://discourse.threejs.org/u/GiftGiwa)\
**Post date:** [September 13, 2025, 2:29am UTC](https://discourse.threejs.org/t/rotateonworldaxis-rotating-descendant-meshes-from-imported-gltf-model-on-local-axes-instead-of-global-axes/86961/1 "2025-09-13T02:29:59Z")

</div>

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):

```javascript
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.

---

<div class="post-metadata">

**Author:** ![GiftGiwa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/giftgiwa/32/15010_2.png) [@GiftGiwa](https://discourse.threejs.org/u/GiftGiwa)\
**Post date:** [September 13, 2025, 3:57am UTC](https://discourse.threejs.org/t/rotateonworldaxis-rotating-descendant-meshes-from-imported-gltf-model-on-local-axes-instead-of-global-axes/86961/2 "2025-09-13T03:57:30Z")

</div>

Update: I tried out this [prototype I found on Stack Overflow](https://stackoverflow.com/a/32038265/17799976) (copied and pasted in file) and it worked:

```javascript
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 )
}

```
