Search code examples
three.jsrotationcoordinatestranslationmesh

Does the .position attribute really stores the values ​in local space or in world space in three.js?


https://threejs.org/docs/#api/en/core/Object3D.position

According to the docs above

  • .translateX “Translates object along x axis in object space by distance units”
  • .position storse “A Vector3 representing the object's local position” and
  • .rotateX “Rotates the object around x axis in local space”.

So all these methods/attributes refer to the local coordinate system of the object. And that is what I’m not understanding.

I rotated an object with .rotateX(2). Then I applied .translateY(2). The result was the following:

The .rotation propertie contain the following: .rotation

The matrixWorld looks like this: .matrixWorld

And the position attribute contains: .position

So I would expect that the position attribute contains x: 0, y: 2, z: 0 because the docs says that the .position is in local coordinate and the translate-method works also in local coordinates. But to me it looks like .translate works indeed in the local coordinates but .position stores the position not in local coordinates but in world-coordinates. What supports this view is the fact that the values ​​exactly match the values ​​in the last column in the WorldMatrix.

So I'm confused and would ask if somebody can explain to me why the docs say something different than what I would expect.


Solution

  • Think about looking down from above on a person standing on a big grid. Their feet are at 0, 0. Taking one step forward would put them at 0, 1 (this tells you they are facing the +Y direction).

    Now, you want them to end up at location -2, 0, and facing +X (0, 0). You know to do that they need to move 2 spaces in the -X direction, and turn their body 90° clockwise. So, you give them instructions:

    translateX(-2) and rotateZ(Math.PI/2)
    

    Translating this into instructions local to the person's frame of reference, you get:

    Take 2 steps to the left and turn 90° to the right
    

    Looks good, right? Except when the person executes them, they end up at 0, 2 and facing 1, 2.

    What happened??

    Well, the instructions were good, except they were executed at the same time. When this happens, rotations always happen first. So the instructions were really:

    Turn 90° to the right THEN take 2 steps to the left
    

    When the person turned as the first step, "left" (local to the person) was no longer in the -X direction, but was in the +Y direction.

    The same thing happened with your translation and rotation. When the translation matrix was computed, the rotation made the local X-axis be pointing in a direction you didn't anticipate for the translation. This caused your x and y values to seem like they weren't in the correct position. However, if you look at the result of calling object.position.length(), you will see that the value returned really is 2, which is the amount you wanted to move.

    More info on matrices, and how they are affected by transaltion, rotation, and even scale: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/