Jump to content

Multiple rotations not as expected.


JohnK
 Share

Recommended Posts

My mesh is a 'hexagonal prism' 

 

It's initial creation places it like this.

 

start.PNG Start

 

rotation of pi/2 about x axis correctly gives

 

rotationX.PNG  Rotate PI/2 about X axis

 

 

Now for a rotation of pi/2 about the z axis I would expect

 

Expect.PNG Expect rotation of PI/2 about Z to give this

 

However I get a rotation about the y axis instead

 

actual.PNG But get this

 

You can try is out at the playground.

 

When Xr is a rotation of pi/2 around the x axis, Yr is a rotation of pi/2 around the y axis and Zr is a rotation around the z axis

 

Any help on how to apply an arbitrary sequence formed from the rotations Xr, Yr, Zr  and obtain the expected result.

 

Thank you

Link to comment
Share on other sites

I think I understand what is happening - not only does rotation.x rotate the mesh but also rotates the local axes so the local z axis is now vertical so a rotation.z appears as a rotation about the world y axis.

Link to comment
Share on other sites

Ok

 

In BJS, rotation are appied this order Ry, then Rx, finally Rz.

But the x, y, z I just wrote here aren't the World X, Y, Z axis, but the mesh local system axis.

Let's call them u, v, w instead.

When you create a new mesh u,v,w are the same than X, Y, Z.

 

If you apply a first y rotation (y is always treated first, whatever the order you code your rotation.x, y, z in your script) :

mesh.rotation.y = alpha;

you have to imagine the u and w mesh local axis will turn for alpha radians in the xOz plane. The v vector is invariant (v == Y for now).

Let's call u1, v1 (= v = Y) and w1 this new rotated axis.

So your mesh turns on the xOy for alpha radians, right ?

 

Then, if you've got in your script some :

mesh.rotation.x = phi;

this rotation will be now applied to the formerly rotated system, it is to say u1, v1, w1 and not about X, Y, Z.

This will give a second intermediate system, let's call it : u2, v2, w2.

 

Do you see now what will happen with :

mesh.rotation.z = theta;

 ?

 

u2, v2, w2 will be finally rotated to the final mesh orientation.

 

This doesn't help you, I guess ;)

 

If you want to keep a reference to the original (X, Y, Z) system in order to rotate about one or more of these axis, maybe you should consider the parenting way : http://www.html5gamedevs.com/topic/13916-rotation-question/?p=79415

Link to comment
Share on other sites

that's what I'm working on : knowing the initial state and the target state by their coordinates only, deduct Euler angles so the target state will be the initial state after 3 BJS rotations y, x, z

 

note for you : as DK is really a great vicious, the left-handed BJS system has 2 different orientations (clockwise + counter clockwise) within

http://www.html5gamedevs.com/topic/14352-setting-mesh-updatable-property/?p=82830

Link to comment
Share on other sites

Seem to have solved the problem using quaternion rotation (at least for the specific case or rotation about X then about Z).

 

Created this function to rotate anti-clockwise a given position vector p about an axis through and angle

function rotateParoundAxis(p, axis, angle) { //p is position (Vector3) to rotate clockwise about axis (Vector3) through angle        var _p = new BABYLON.Quaternion(p.x, p.y, p.z, 0);  //change p to quaternion for quaternion multiplication        axis.normalize(); // change axis to unit vector                var q = BABYLON.Quaternion.RotationAxis(axis,angle);  //form quaternion rotation                var qinv = BABYLON.Quaternion.Inverse(q);            var _pdash = q.multiply(_p).multiply(qinv);        _pdash = new BABYLON.Vector3(_pdash.x, _pdash.y, _pdash.z); //change to Vector 3 to return a new position vector;        return _pdash;     }

I have not yet given it any testing so use with a great deal of caution.

 

You can try it on the playground.

Link to comment
Share on other sites

Hello,

 

About your PG, your algo is :

  • create a mesh
  • get its vertex positions
  • compute new rotated positions (nice quaternion, btw)
  • update the mesh positions

Well, this works.

But this doesn't really rotate the mesh in the World. It rather redefines the shape of the initial mesh in its local space.

No rotation (in the meaning of transformation from local to world sytem) is applied here.

Link to comment
Share on other sites

What I needed was a World with X, Y, Z axes and a mesh with local system axes u, v, w where on creation of the mesh  u,v,w are the same as X, Y, Z.

 

I needed to translate the mesh and its local system axes which I could do using mesh.position. Also whatever its position I then needed to rotate the mesh not in the World but within its own local system axes but without rotating the local system axes. So I needed translation and rotation to behave differently, translation to transform the local system axes but rotation should not transform the local system axes.

 

My thinking is like this - When a child is building a structure with blocks they will carry the block to the correct World position but then will rotate it locally to fit.

 

Initially I had not realised that mesh.position translated the local system axes with the mesh so I had lines in the code to translate the the mesh back to the origin before rotation and then translate it back. These lines of code I edited out but left behind a comment related to this. If you had seen this code or read the comment it could have confused you to my intentions.

 

Anyway it does what I want so I am happy and enjoy our discussions and your contribution really move me forward..

Link to comment
Share on other sites

I understand what you want to achieve. :)

However, you create a mesh here with its updatable parameter set to true.

This means you change the mesh vertices themselves. In your case, you've done a rotation in its local sytem.

But you could have done the same way another weirder transformation like morphing the cylinder into a pyramid or a sphere ...

We can do whatever we want with updateVertices() : to change the vertex positions, the faces themselves, the normals, etc. In brief, to change the mesh itself to another mesh.

 

In this case, we don't just give to the child only a simple mesh... we give him some modeling clay :P !

 

In you want to keep your mesh un-updatable (is this english ?), we can set the updatable parameter to false (default value) and then only play with rotations which are local to world transformation.

If you want to keep a reference to the world axis when rotating your mesh, I guess you probably should embbed it into two higher level parents (boxes) and give rotations to parents like in a gimbal.

Link to comment
Share on other sites

Is this what you wanted to achieve? http://www.babylonjs-playground.com/#1VGDNJ#7

Use the rotate function with the right axis and define the coordinate space you want to rotate the object in.

 

I am not sure if updating the mesh's vetices is the right choice here  ;) . All he wanted was to rotate the object correctly 

Link to comment
Share on other sites

Thank you RaananW. Believe it or not I had just come across

mesh.rotate(BABYLON.Axis.X, Math.PI/8, BABYLON.Space.WORLD);

in the Advanced Tutorial on the Babylon.js Docs site. Do not know how I missed it in the first place.

 

Am I right in thinking that you can replace BABYLON.Axis.X  with any unit vector. It seems to work in this example

 

None unit vectors seem to have a scaling factor as well.

 

Jerome was trying to point me away from a method that required updating the mesh but I had found something that gave me exactly what I needed so was happy to use it. Have now changed the code in my project to use

mesh.rotate(BABYLON.Axis.X, Math.PI/8, BABYLON.Space.WORLD);
Link to comment
Share on other sites

 

Am I right in thinking that you can replace BABYLON.Axis.X  with any unit vector. It seems to work in this example

 

 

Yep, you are right. any unit vector will work. Actually, any vector will work, as it is being normalized before it is being used  :D

 

 

Jerome was trying to point me away from a method that required updating the mesh but I had found something that gave me exactly what I needed so was happy to use it. Have now changed the code in my project to use

 

I think Jerome was right, it is also possible to do that with updating the vertices. If your mesh would stay like that "forever", it might be a smart move! I just think that in this case, a simple rotation would do. We sometimes forget that the simplest solution is right in front of us  ;) . happens to me at least 4 times a day 

Link to comment
Share on other sites

Am I right in thinking that you can replace BABYLON.Axis.X  with any unit vector. It seems to work in this example

 

 

You may have noticed already, but behind the scenes "mesh.rotate" is just doing a quaternion rotation around whatever axis you provide, so it's similar to doing your own quaternion rotations and you get all the same benefits.

 

But remember that it will also zero out your mesh.rotation.x/y/z properties - once you do a quaternion rotation on a mesh, Babylon ignores the Euler rotations and assumes you'll keep using quaternions.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...