How to apply a local transform matrix to an Object?

If I write:

const cube = new THREE.Mesh(
     new THREE.BoxBufferGeometry(50, 50, 50, 1, 1, 1),
     new THREE.MeshPhongMaterial({
       color: 0xffff00
     })
   );
cube.matrix = new THREE.Matrix4();
cube.matrix.set(1,0,0,80, 0,1,0,0, 0,0,1,0, 0,0,0,1);

that doesn’t work. If I write:

const matrix = new THREE.Matrix4();
matrix.set(1,0,0,80, 0,1,0,0, 0,0,1,0, 0,0,0,1);
cube.applyMatrix4(matrix);

that works but I’m not sure if it’s the same as setting .matrix property on an Object or it’s a .matrixWorld or both.

What’s the proper way to make a new object and set a local matrix so it takes hold?

Object3D.matrix is automatically computed based on Object3D.position, Object3D.rotation and Object3D.scale. You can disable this by setting Object3D.matrixAutoUpdate to false.

BTW: Object3D.applyMatrix4() multiplies the given matrix with the existing local one. This is something different than just setting a new matrix. In any event, Object3D.applyMatrix4() also updates Object3D.position, Object3D.rotation and Object3D.scale.

Ok, thank you, so how do I achieve what I want?
I have matrices coming from another software, so I would like to:

  1. Apply them to existing objects without splitting them into position/rotation/scale
  2. Apply them as in “setting a new matrix”, not pre-multiplying the existing one
  3. After matrices are applied, be able to continue using various functions for setting pos/rot/scale individually, as in modifying these matrices further.

Why is this a problem? I suggest you do this and everything should work out of the box:

externalMatrix.decompose( cube.position, cube.quaternion, cube.scale );

Removing solution because decompose() can not be composed back if the matrix has skew/sheer component, decomposition loses information. If I make matrices manually with .matrixAutoUpdate = false; I’ll have to do everything manually because then I can’t use all pos/rot/scale built-in functions.
Also, as I understand, I need to manually recalculate .matrixWorld.

The engine is actually not considered for this use case. I can’t guarantee that manually computing world matrices works. You have a least to set matrixWorldNeedsUpdate to false for all nodes and never use updateMatrix().