Rotations reprise

Well…i thought i had grasped rotations but obviously i did not…



I know how to rotate the camera about two axis’ independently…



But it doesn’t work with the spatial. I have a sphere, and i thought i should try the same thing i did with the camera. The camera seemed to always rotate based on world rotations and not based on local axis’. Meaning, if the camera got rotated to the right , then up, then to the right again, it would do this correctly, by moving around the original axis (to the right).



This was done by multiplying the quaternions, producing the correct rotation…



When i rotate the spatial by setLocalRotation(quaternion multiplication) the second time i want to rotate about the same axis, the axis has actually moved…I want rotations whose axis’ do not rotate with the object…



Q1.fromAngleAxis(sphereAxisX, Vector3f.UNIT_X);

Q2.fromAngleAxis(sphereAxisZ, Vector3f.UNIT_Z);

RainbowSphere.setLocalRotation(Q1.mult(Q2));



sphereAxisX and sphereAxisZ are variables i increment or decrement based on rotation…I want a rotation that doesn’t change the axis’…Any single rotation works normally…

Note theres local values world values and worldToLocal() as well as localToWorld() methods on all spatials.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:scenegraph_for_dummies

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies

yes that’s what i need!!! thanks!!

the local to world method uses vectors while rotations use quaternions…

found no example of its use :frowning:

Do the tutorials. After you will be able to do anything with rotations and vectors. A Quaternion is a relative rotation, there can not be absolute values.

I did them! I even put animations in it using blender and the ogre exporter! Bullet physics was just fantastic (and i had to learn to set the friction AFTER attaching the object to the bulletappstate)…



Rotations are not my cup of tea it seems…or i’m just dumb :frowning:

The ones I posted here.

I’ve seen these tutorials like 5 times…



Look…



it says, that a quaternion rotates the vector around one axis, and then around another axis…What i’m seeing is that the vector gets rotated based on world axis’…The axis’ don’t rotate with the vector…My sphere should rotate the same way…it doesn’t…i cannot figure this out…i need a sample code of two lines…



I know that we have to learn through the hard way, cause that’s way better, but i’ve been troubled for a while, and would like to continue with my project…if someone has an idea about this problem, pls help, i promise, it will just help because it will help me figure out what i’ve already seen through the tutorials

A quaternion you set as localRotation to a spatial rotates it by the quaternion amount out of the y-up, z-forward position. The parents rotation obviously has to be accounted for when you are about to set a world rotation. As rotation and location influence each other when you combine transforms in a parent-child relation combining them isn’t exactly easy. Use the Transform class and its methods to work with rotation, location and scale at the same time. Its not going to get any easier and I really don’t know how to explain it better than in these tutorials. Please not only click to where you presume your solution is but actually read them.

dimitristrigkakis said:
Q1.fromAngleAxis(sphereAxisX, Vector3f.UNIT_X);
Q2.fromAngleAxis(sphereAxisZ, Vector3f.UNIT_Z);
RainbowSphere.setLocalRotation(Q1.mult(Q2));

sphereAxisX and sphereAxisZ are variables i increment or decrement based on rotation...I want a rotation that doesn't change the axis'..Any single rotation works normally...


setLocalRotation should completely replace the sphere's previous rotation. Does it have another node as parent that also has rotation?

If not then you may need to switch Q1.mult(Q2) to Q2.mult(Q1).

You can also try Q1.fromAngles( sphereAxisX, 0, sphereAxisZ )

Though really, I'm wondering what rotation you want? Is it a quake style rotation? If so then you need to be rotating around x axis and y axis since Y points up. It's very strange to be rotating around X and Z.

He knows that Y = up, he did the tutorial at least 5 times :wink:

First of all, thanks for caring, i know it’s tough when noobs ask the same questions over and over again…


  1. setLocalRotation should completely replace the sphere’s previous rotation. Does it have another node as parent that also has rotation?



    It does have a node without rotation…i removed the node and attached the sphere directly to the rootNode…It doesn’t change something, because as u said, the node didn’t have any rotation…


  2. If not then you may need to switch Q1.mult(Q2) to Q2.mult(Q1).



    I actually tried that, because when i was working with the camera, one of them was correct…However, the one i’m using with the sphere seems to be the correct one…If i change it, it doesn’t change anything…except for the rotation when i try to rotate a third time (first i try X, then Z, then X again) where it rotates wrong again, but in a different way…


  3. You can also try Q1.fromAngles( sphereAxisX, 0, sphereAxisZ )



    I tried that, and the first rotation is always correct…So if i move the sphere to the right, it does work…if i move the sphere up it also works…Then if i move it right again, it produces a weird rotation based on the new axis’…So it’s like the rotation i tried, but a little different, the rotation just spins wrong again in a different direction


  4. Though really, I’m wondering what rotation you want? Is it a quake style rotation? If so then you need to be rotating around x axis and y axis since Y points up. It’s very strange to be rotating around X and Z.



    I’m using a sphere that moves around…I’m trying to make a mmorpg…KIDDING>…i’m trying to make a simple sokoban game where instead of a player u have a rolling ball…So the ball moves around in X and Z…If it moves at X, it rotates on Z…if it moves on Z it rotates on X…



    Yes the Y axis is the vertical axis, but i don’t want to rotate on that, cause no movement of the sphere corresponds to a rotation which makes its waist spin round and round…



    But so that we could just be sure, i put



    Q1.fromAngleAxis(sphereAxisX, Vector3f.UNIT_Y);

    Q2.fromAngleAxis(sphereAxisZ, Vector3f.UNIT_Z);



    and Q1.fromAngleAxis(sphereAxisX, Vector3f.UNIT_X);

    Q2.fromAngleAxis(sphereAxisZ, Vector3f.UNIT_Y);





    now the starting rotation is wrong, so it’s clearly not what i want… thanks though!!



    I really can’t figure this out on my own…But all i can understand is that the sphere rotates correctly when i rotate on X…then when i rotate on Z, it’s also correct…But if i try to rotate on X again it doesn’t rotate the way it previously did, and rotate along a different axis that is angled (45 degrees approximately)

You are not by any chance doing stuff like getLocalRotation().set()? That does not work, you always have to use setLocalRotation/Translation. Also, I suggest working with direction vectors and not using quaternions. You can get a quaternion from that vector using lookAt(vector,Vector3f.UNIT_Y) when you need it. To me its much easier imagining vectors than rotations.

I saw a warning sign against getLocalRotation().set() so i didn’t do that…i just used a setLocalRotation() when i had a quaternion. I will take ur advice for direction vectors, cause it’s true, i prefer 3d…When i tried imagining a hypercube, i was only capable of understanding translations…rotations where out of the question :stuck_out_tongue:

1 Like

Direction vectors are the way to go. What you have been trying to do is apply two rotations… and the order you apply them will very much matter. The previous state of the sphere doesn’t matter at all.



For example, if you tilt your chin down 45 degrees and then tip your head to the side 45 degrees (from that rotation) you will see that your head is in a completely different position than if you tilted sideways first and then put your chin down.



What you really want is to pick the direction of the ball, find the orthogonal vector to direction and up, then rotate around that axis by a single rotation (not two separate ones).



Something like:

[java]

Vector3f dir = normalized ball direction

Vector3f up = Vector3f.Y_AXIS;

Vector3f axis = dir.cross(up);

Quaternion rotate = new Quaternion().fromAngleAxis( rollAngle, axis );

[/java]



If the ball looks like it’s rolling backwards then do up.cross(dir) instead. I inevitably get those switched the first time.

so…the normalized ball direction…hmmmmmm…



RainbowSphere.getLocalRotation().mult(Vector3f.UNIT_Y);



that’s not it…hmm…i wanna cry, give up and jump out the window :frowning: …i’m a sad monkey it seems…

No… “direction” is very much not the same as “rotation”.



Your ball is moving in some direction. It was at some position before… it is at some other position later. The difference between these positions is the direction. A normalized direction is one of length one.



Presumably you are moving the ball around and therefore know what direction is is moving.



Besides, your call was actually asking for a vector pointing up local to the orientation of the sphere. Even if you’d asked for Z properly, this will not help you. You need to figure out what the rotation should be so that you can set it. Doing anything with the current rotation won’t give you the answer you want… at best it will give you an answer to old to do anything with.

Ok i did that. I used a direction variable to figure out where the direction is…



So the ball rotates properly! nice…one problem…When it starts rotating in a different direction, while the rotation works normally, the rotation position is reset…



Vector3f dir = new Vector3f();

if (sphereDirection == 0) {

dir = new Vector3f(0, 0, -1);

}

if (sphereDirection == 90) {

dir = new Vector3f(1, 0, 0);

}

if (sphereDirection == 180) {

dir = new Vector3f(0, 0, -1);

}

if (sphereDirection == 270) {

dir = new Vector3f(1, 0, 0);

}



Vector3f up = Vector3f.UNIT_Y;

Vector3f axis = dir.cross(up);

Quaternion rotate = new Quaternion();

if (sphereDirection == 0 || sphereDirection == 180)

rotate = new Quaternion().fromAngleAxis(sphereAxisX, axis);

else

rotate = new Quaternion().fromAngleAxis(sphereAxisZ, axis);



RainbowSphere.setLocalRotation(rotate);



the ball isn’t moving at 2 direction simultaneously, rather, only one rotation is applied at a time…It just has to remember its old rotation…This thing does what i said, it produces the correct rotations but the ball jerk-rotates to an initial position and starts rotating from there…maybe if i put a node or something?

So, you could do it a little differently. If sphereAxisS and sphereAxisZ are always rotated in fixed increments (and you really don’t need two values anymore anyway) then you can just use a fixed rotation delta * tpf and then multiply it by the current rotation.



rotate = new Quaternion().fromAngleAxis( someFixedAngleDelta * tpf, axis );

sphere.setLocalRotation( sphere.getLocalRotation().mult(rotate) );



I may have the mult backwards. They key is that since this is accumulated rotation you do not need to keep the accumulated angles yourself… in fact it would mess you up.

1 Like
pspeed said:
For example, if you tilt your chin down 45 degrees and then tip your head to the side 45 degrees (from that rotation) you will see that your head is in a completely different position than if you tilted sideways first and then put your chin down.

This is a good neck exercise by the way.