How to X rotate object using other object as reference?

My point is, I have a need to extract an rotation from an object and exclude the “spin” rotation from it.
I built this example to inspect and show why those methods didnt work, and to try to get some help since I am very new to JMonkey ( 1 week only :slight_smile: ).
For some reason using angles dont work, I also could not guess why, it has strange behavior when you rotate the object for a while in diferent directions, same from this other posts, its easy to check it using the second code in this post.
Anyway, I understand that angles are not precise, but, what I miss is more advanced funcions to work with the Quartenions, like in this case, something that could remove spin rotation from the Quarternion woud fix my problem.

It’s not that are not precise. It’s that euler angles are TOTALLY AMBIGUOUS.

Here, do this experiment:
Quaternon q1 = new Quaternion().fromAngles(0, 0, 0);
Quaternon q2 = new Quaternion().fromAngles(0, FastMath.TWO_PI, 0);
Quaternon q3 = new Quaternion().fromAngles(0, FastMath.TWO_PI * 2, 0);
Quaternon q4 = new Quaternion().fromAngles(0, FastMath.TWO_PI * 97, 0);

…note how all of these should produce exactly the same quaternion. And this is a very simple case.

Now, imagine you rotate your head 180 degrees around the y axis and another 90 degrees around the z axis. You are now looking behind you and upside down. Note that you could have gotten this exact same orientation by just rotating around the x axis 180 degrees… in either direction.

The only way to accurately get all of the random euler angles out of a rotation that you put into it… is to only every use euler angles in the first place and just convert them to quaternions.

The problem from our perspective is that you haven’t explained why you want to do this thing (maybe there is another way) and you often mention “strange behavior” without actually describing or illustrating the strange behavior in any way. So we end up with a 21 post thread circling the drain.

Describe exactly what you are trying to do and we’ll tell you how or if it’s even possible.

What I am trying to do in the game is very hard to explain, I think its easy to explain with the code I put here.
If you run the last code I sent, you will notice that when you rotate the origem cube, the other cubes will represent the rotation, but will only move taking the x,y,z axix in consideration, its working now because I am saving a history of all rotations in variables.
I was expecting the same behavior on the first code, the one with :

        float[] angles = geom1.getLocalRotation().toAngles(null);
        geomX.setLocalRotation(new Quaternion().fromAngles(angles[0], 0, 0));                
        geomY.setLocalRotation(new Quaternion().fromAngles(0, angles[1], 0));
        geomZ.setLocalRotation(new Quaternion().fromAngles(0, 0, angles[2]));

But what happens is something I dont get it, geomx is ok, for some reason it works for geomx, for geomy it gets movements of x and z, I was not expecting that, but its ok, maybe its the way it works, but geomz behavior is something I cant understand, it simple spin in random rotations I dont know why, it looks to be a but to me, but who knows.
If you have some time, run the first code, press Q+Space and keep it pressed for a while, you will see geomx showing the same rotation as the origemcube, if you press A+Space you will see the origem cube rotating in Y and Z+Space in Z, when you rotate in Y and Z the representation is messed on all cubes.
To see what I was expecting, just run the last code I sent , the one with :

        if(storedrotationX!=0) geomX.rotate(storedrotationX,0,0); storedrotationX=0;
        if(storedrotationY!=0) geomY.rotate(0,storedrotationY,0); storedrotationY=0;
        if(storedrotationZ!=0) geomZ.rotate(0,0,storedrotationZ); storedrotationZ=0;

This one is working for me, because its using history variables.

Sorry if it was not clear, its hard to explain I know, if you need I can make some video or draw something, I really think its something to look at.

Just to clarify :

Working code :

if(storedrotationX!=0) geomX.rotate(storedrotationX,0,0); storedrotationX=0;
if(storedrotationY!=0) geomY.rotate(0,storedrotationY,0); storedrotationY=0;
if(storedrotationZ!=0) geomZ.rotate(0,0,storedrotationZ); storedrotationZ=0;

Not working :

float[] angles = geom1.getLocalRotation().toAngles(null);
geomX.setLocalRotation(new Quaternion().fromAngles(angles[0], 0, 0));
geomY.setLocalRotation(new Quaternion().fromAngles(0, angles[1], 0));
geomZ.setLocalRotation(new Quaternion().fromAngles(0, 0, angles[2]));

Yes, well I already kind of explained why these are different. Only about 100 ways to explain it I guess but none will be more clear… and you still really haven’t explained what your ultimate goal is.

It’s like “Why do you want Mario to jump?” and getting answers like “His feet seem to leave the ground at different times.”

I don’t have time to run your code unfortunately. I could quote contracting fees but I think the explanation I already gave probably covers what’s going on.

eulerAngles1 → quaternion ->eulerAngles2
eulerAngles1 != eulerAngles2 (though if you do it again you will get the same eulerAngles2)
eulerAngles2 → quaternion ->eulerAngles3
eulerAngles2 == eulerAngles3

Not sure how else to explain it. For any given orientation, there are an infinite number of euler angles combinations that will give you that orientation. If this isn’t clear or you disbelieve then this is the heart of your misunderstanding.

I just want to remove spinning on a object that is rotating in all directions.
Imagine an ship that have push engine in all directions, and it need to reduce rotation in one selected direction, then in the other. I cant use phisics in this case, so my solution was to change the rotation it self.
Also, I have another game, with a spaceship travelling arround a planet, in orbit and very fast speed, when the ship rotates spinning (left or right), I dont want the planet to rotate, but I do want it to rotate in all other cases ( rolling on it = front/back).
But I still think there is an bug on the fromAngles , or maybe it is just missing an fromLocalAngles and fromWorldAngles.

There is no bug in fromAngles(). I use it all the time and get exactly what I expect from it.

This is the closest to a good description of what you are trying to do so far… but what is “direction” in this case… ie: relative to what? Relative to the ship? Relative to the world?

What is the “rotation” that you are reducing? This implies some sort of rotational velocity… which is almost always done as euler angles because you would potentially need specific magnitudes in each direction.

I don’t understand why the planet would rotate when you rotate the ship. Sounds like your scene graph is messed up.

The ship will be at the center of the screen, so the planet will roll to simulate movement.
I dont want the planet to rotate when ship turn left or right, only the ship.
So when the player accelerate the ship, the plannet roll down, but when the player turn it, just the ship turns.
In the first case, imagine the ships from the movie interistelar, and a way to apply force to the rotation but only in an specified axix, I dont want to use phisics in this case.

Can the ship only essentially travel in 2D then? If so then just do that and figure out what the planet needs to look like at any given time.

Actually its all in 3d, the ship is in a planet orbit, the camera is behind the chip.
Also, the camera is not exactly on the top of the ship, it is in allways in slerp going on the ship direction.
Hard to explain…
But the idea is that I get the rotation of the ship node that is in the center of the planet, and appy it to the planet, but removing all spin rotation.

Can the ship roll? Can it pitch up or down? Can it move up and down in Z?

Or is it essentially trapped in a 2D orbit around the planet?

I think you might need to search for the “math for dummies” document we have. I can’t find the link in the wiki at first glance which is pretty dumb but you should be able to find it on a search.

…because it sounds like what you really want to understand is how to apply rotations to existing rotations and what that means. (ie: order is important, etc.)

It can roll, pitch up and down, but its trapped in the orbit ( rotating in the node ), its 3d since the camera dont exactly follow the ship, the camera follow the ship, but using slerp.
Its hard to explain, maybe after its ready I can make a video.
To try to simnplify: shipnode simulates orbit so it dont rotate in X, just in Y and Z, the camera is fixed on the ship on the direction of the planet, the planet rotates simulating up and down and left and right from the ship.
I already saw the video math for dumies, I could not find the solution there. My problem is how could I extract and interpret the information in a Quaternion, not exacly how to rotate.
I made a video about the problem with the geoms, but it would require to run the code to fully understand it.
Basicly I would expect the same behavior from this two peace of codes :

            if(storedrotationX!=0) geomX.rotate(storedrotationX,0,0); storedrotationX=0;
            if(storedrotationY!=0) geomY.rotate(0,storedrotationY,0); storedrotationY=0;
            if(storedrotationZ!=0) geomZ.rotate(0,0,storedrotationZ); storedrotationZ=0;

and

            float[] angles = geom_master.getLocalRotation().toAngles(null);                                                   
            geomX.setLocalRotation(new Quaternion().fromAngles(angles[0], 0, 0));                
            geomY.setLocalRotation(new Quaternion().fromAngles(0, angles[1], 0));
            geomZ.setLocalRotation(new Quaternion().fromAngles(0, 0, angles[2]));

but they dont have the same behavior.

Did you look at the math for dummies tutorial? I still think that your base approach is flawed.

I read the doc, its preaty clear on how to handle vectors and use it on quaternion.
But how do I extract the vectors from a Quatenion ?
There is a function getRotationColumn , but on java doc I could not find info on how to use it, I am guessing its 0=left/right , 1=up/down and 2=direction, is that correct ? Should I use this function and multiply Y and Z to get a new Quaternion with out X ? Any example on how to get this vectors and create an new quaternion with out the left/right vector ?

Just a update, that is exactly what I want to do :

Also a solution for this on Ogre :

http://www.ogre3d.org/forums/viewtopic.php?f=5&t=76926

How to convert this to JMonkey ?

Well, to me it sounds like you don’t even need to do yaw pitch and roll separately as you are by trying to “Extract” this from a quaternion.

If you want to rotate the planet some amount relative to the ship then just rotate it. Create a quaternion that represents the rotation and then multiple that by the existing quaternion. Done.

As the tutorial tells you, multiplying the quaternion with a Unit.Z vector rotates that vector, so thats how you “extract” those vectors… But again you’re falling into the trap of doing half of your stuff with your own variables and the other with quaternions and end up wondering how you get from one to the other… We’re going in circles here, I don’t think I can explain it any better, sorry.

Did you read the stack exchange conversation? If you understand that you should be able to better understand the details of what you’re working with.

I know, but how I do that on JMonkey ? I guess is that way right ?

            Vector3f vx = geom_master.getLocalRotation().mult(Vector3f.UNIT_X);
            Vector3f vy = geom_master.getLocalRotation().mult(Vector3f.UNIT_Y);
            Vector3f vz = geom_master.getLocalRotation().mult(Vector3f.UNIT_Z);                

At least it works in my test.

Yes, it supouse to be simple, but if I have the vectors from the ship :

        Vector3f vx = shipnode.getLocalRotation().mult(Vector3f.UNIT_X);
        Vector3f vy = shipnode.getLocalRotation().mult(Vector3f.UNIT_Y);
        Vector3f vz = shipnode.getLocalRotation().mult(Vector3f.UNIT_Z);

How do I aply this vectors to the planetnode ignoring vz ?
I tried rotateUpTo(vx) then rotateUpTo(vy) but it didnt work.