0

If I got it right: an Object3D has on one side the set of properties (position, scale, rotation) [*] and on the other side the matrix - this later contains esentially the same information, it's computed from the others in Object3D.updateMatrix() and is the one really used internally by the renderer computations. Instead, the set (position, scale, rotation) is the one that is usually manipulated by the programmer (translations, rotations...).

Sometimes, however, one manipulates directly the matrix, and, further, instead of setting matrixAutoUpdate=false and forgetting about (position, scale, rotation), one wants to keep the properties in sync, i.e. do what Object3D.updateMatrix() does but in the other direction. Is there some implemented/efficient/recommended procedure to accomplish this?

[*] Caveats: 1) if useQuaternion=true, the quaternion is used instead of rotation 2) rotation is complemented by eulerOrder 3) I'm not sure what role play up in this picture, I guess it's not important here.

leonbloy
  • 69,336
  • 20
  • 133
  • 185

2 Answers2

1

You can call the applyMatrix(matrix) method on a 3D object. To see what it does, see here.

Either:

1) you can feed it an identity matrix, or

2) you could copy what the function does:

this.scale.getScaleFromMatrix( this.matrix );
var mat = new THREE.Matrix4().extractRotation( this.matrix );
this.rotation.setEulerFromRotationMatrix( mat, this.eulerOrder );
this.position.getPositionFromMatrix( this.matrix );

I'm not sure how quaternions are relevant if you do the above, I don't know the circumstances under which the useQuaternion flag is set to true. But in Object3D objects by default it's false. I have a feeling it uses quaternions only when calculating certain rotations so to avoid gimbal lock.

I think the following code taken from the lookAt() method would update the quaternion:

this.quaternion.copy( this.matrix.decompose()[ 1 ] );
CL22
  • 14,026
  • 26
  • 90
  • 153
1

The routine

Matrix4.decompose( position, quaternion, scale ) // revision 57dev

will compute the position, quaternion, and scale vectors from a matrix.

(In r.56 the arg names were unfortunately misnamed, and this has been fixed in r.57dev.)

If you want the rotation vector instead, you will have to compute it from the just-computed quaternion like so:

rotation.setEulerFromQuaternion( quaternion, eulerOrder );

The up vector is not relevant to your question.

WestLangley
  • 97,891
  • 9
  • 255
  • 258
  • Thanks. Strange for me that the quaternion alternative is prefered. Looking at the dev branch, I'd say that `Object3D.applyMatrix()` should use that, no? I'd also suggest that that method (and others similar, that manipulate the matrix) should _optionally_ do the sync (via some flag, in the method arguments, or in the object itself). I wonder which is the place to make these kind (devel) suggestions -not exactly issues? – leonbloy Feb 26 '13 at 16:17
  • `Object3D.applyMatrix()` supports quaternions in dev57. And, no, your suggestion is not appropriate because it is based on a false assumption. `matrixAutoUpdate = false` is to be used when the object is static -- to save CPU cycles. It is not intended to allow the user to update the matrix in lieu of updating the `position`, `rotation`, or `scale`. – WestLangley Feb 26 '13 at 16:39