Clone object along with "world" rotation

I have a simple scenario: an Object3D that belongs to a Group. The rotation is naturally done on the Group, so that all the objects belonging to the group (i.e. its children) rotate as well, visually.

Since it’s a simple scenario, it also causes a simple problem: when cloning the said Object3D, the clone’s rotation is the default (0, 0, 0) since it’s relative to the group and technically it’s the group that is rotating.

A simple problem thus yields a simple question: how can I also “clone” the object’s rotation - but not the one relative to the group which stays the same at all times, but the “absolute” / “world” one - in order to avoid the slightly odd / unintuitive situation where I clone the object but clone the group’s rotation instead?

In code, how can I better write the last two lines of:

somegroup.add(someobject);

someclone = someobject.clone();
someclone.rotation.copy(somegroup.rotation);

to refer to the absolute someobject.rotation? Alternatively, can the absolute someobject.rotation be transferred to the clone directly, in a single operation (obviously, without altering the original)?

Object3D.getWorldPosition, Object3D.getWorldQuaternion, and Object3D.getWorldScale seem to be precisely what you’re looking for :thinking: ?

And you can use them directly on the clone, ex:

originalMesh.getWorldPosition(worldAlignedClone.position);
1 Like

You can also copy quaternions from one object to another, whether it’s a mesh or a group, like so:

object1.quaternion.copy(object2.quaternion);

for example, like here:

1 Like

Thanks, @tfoller and @mjurczyk , both solutions are excellent! I think I’ll use @mjurczyk’s one, since the whole point here is to not involve the group’s properties in any way and set the clone exclusively using the original’s values (after they’ve been transformed from relative / local to absolute / world ones). In fact, I was using .getWorldDirection and .getWorldPosition in the case of the camera later on in the same function, but for some reason didn’t realize I had to do it for the object as well … and then I was wondering why I got the same value for the clone since it didn’t rotate like the original.

I have two more side questions, if I may:

  • first, when logging the resulting rotation values, the clone’s ones are displayed as different from the original’s ones (something that didn’t happen when using the code in the initial question), although visually they are the same; I guess this is normal, in the case of Eulers and quaternions?
Euler {isEuler: true, _x: 0.0074152932221089336, _y: 6.1086523819801535, _z: 0, _order: 'XYZ', …}
Euler {isEuler: true, _x: 0.007415293222108934, _y: -0.17453292519943306, _z: -1.10092773860612e-19, _order: 'XYZ', …}
  • following your suggestions, I looked into the other Object3D methods and I wondered if by any chance I could set scale, position and rotation all at once via .applyMatrix4() or something similar; in my code, I scale the clone to a different value compared to the original (albeit based on it), while I keep the clone’s position and rotation the same as the original’s equivalents but in world space; I’m curious if all these properties can be transformed / transferred collectively, considering the different operations that are performed on each one of them

I’ll wait for a little while before marking the solution, in case someone replies to the last two (optional, not that important) questions.