2

I am having a hard time understanding how the local axis rotation works in ThreeJS. I saw this Rotate around local axis answer and it is not working quite the way I expected.

If I create a a cylinder and rotate it

const geometry = new THREE.CylinderBufferGeometry( 10, 10, 20 );
geometry.rotateX(Math.PI/2)

How do I then rotate the cylinder along its long axis?

I expect this to do the job: geometry.rotateY(Math.PI/5) but that appears to be rotating it around the world axis. I want to just rotate it around the local axis to make it look the same as if I had done

geometry.rotateY(Math.PI/5)
geometry.rotateX(Math.PI/2)

Can anyone help explain how to rotate around the objects internal axis?

What actually happens: https://jsfiddle.net/h20hnn3n/46/

What I want it to look like: https://jsfiddle.net/81j6g2ms/1/

My use case requires me to rotate around the X and arbitrary amount first and then I need to rotate around the old Y axis, so it would be great if I could do it in this order

Edit: It appears that it matters whether you rotate the geometry vs a mesh. Shouldn't it be equivalent to do it either way?

I'm really confused why this doesn't act the same way: https://jsfiddle.net/10L8se71/2/

schlaegerz
  • 377
  • 2
  • 12
  • I think this has been answered here: https://stackoverflow.com/questions/28848863/threejs-how-to-rotate-around-objects-own-center-instead-of-world-center – Alex Pakka Dec 06 '17 at 18:39
  • 1
    I'm not sure this is the same. I'm confused about the axis of rotation after you rotate it once, this is just showing how to change what it pivots it around, which I think I do understand. – schlaegerz Dec 06 '17 at 18:57
  • If I understood better what you miss, I would help you. I will throw in some facts. Cylinder is created with long side (20 units height) being vertical and aligned to the world origin. WebGL axes are X (right-left), Y (top-down), Z (forward-back). So, long axis is Y axis, you rotate around Y first. Order of rotation matters. If you then rotate around X, it will tilt towards or away from you, already rotated around vertical axis. Not sure where the confusion comes from. – Alex Pakka Dec 06 '17 at 19:14
  • Take a look at [this answer](https://stackoverflow.com/questions/45210465/how-to-change-the-circle-radius-when-i-click-on-them-with-three-js/45217002#45217002). The concept is the same, except you want to manipulate the `rotation` property, instead of `scale`. Basically, it's better to rotate the `Mesh` rather than the `Geometry` because then you aren't altering the geometry, just the transformation of the object. – TheJim01 Dec 06 '17 at 19:17
  • @shlaegerz Ok. I understand now. The initial state of your cylinder for this task is that it is already rotated around X axis (i.e. tilted towards you). But you want to rotate around pivot Y axis as if it happened before the X rotation. Since order of rotations matters, you need to undo the rotations, apply your local transformation (rotateY) and then re-apply the X rotation. – Alex Pakka Dec 06 '17 at 19:20
  • @TheJim01 I am acutally trying to rotate the geometry and have to stick like that. Essentially so I can reset the mesh rotation later and have still be the one I started with. – schlaegerz Dec 06 '17 at 19:33
  • @AlexPakka do you know anyway around this? My exact use case could have a whole series of rotations. I think I am going to completely change my implementation to use vectors instead, but I am just kinda curios why there is a difference between if I rotate the mesh, vs rotate the geometry before it. – schlaegerz Dec 06 '17 at 19:35
  • So why not actually store your original rotation? `myMesh.userData.originalRotation = myMesh.rotation.clone();` and then when you want to "reset", just do: `myMesh.rotation.copy(myMesh.userData.originalRotation);` Transforming geometry is not as efficient as mesh transformations. – TheJim01 Dec 06 '17 at 21:56
  • Yeah, it was really inconvenient for my entire system so I was trying to avoid doing that. I ended up doing what I needed to with vectors instead of rotation, but I guess the answer is it doesn't work on geometry that way. – schlaegerz Dec 07 '17 at 18:40

1 Answers1

3

In case anyone else runs into this I'll post a solution.

Rotating a geometry works differently than rotating a mesh. So you need to add it to a mesh first. The following ends up with the right result:

const mesh = new THREE.Mesh( geometry, material ) ;
mesh.rotateX(Math.PI/2)
mesh.rotateY(Math.PI/5)
schlaegerz
  • 377
  • 2
  • 12