[SOLVED] It seens quaternions got me again

I trying to put an cannon up in my ship, this cannon should point into the mouse direction.
The camera is allways looking into the ship from up like in the picture.


And the ship is rotating with the camera arround an sphere (planet), and just move up/down , left/right, but also from random collisions (rigidbody).

I am using the following code to get the angle :

    Vector3f ship2dpoint = chaseCam.getCamera().getScreenCoordinates( spatial.getWorldTranslation() );
    Vector3f direction = Utils.get2dPointToMouse_Vector(new Vector2f(ship2dpoint.x,ship2dpoint.y) , inputManager , settings);

    float[] angles = new float[3];  // Set Shoot direction from the mouse

    double mouseangle = Math.atan2(direction.getX(), direction.getZ()) * 360 / (Math.PI*2);
    float angleToApply = (float)mouseangle - angles[1]*FastMath.RAD_TO_DEG;

Its working, but when the ship is rotated this rotate angle is missing in the calculation.
How can I get the z angle from the ship to add in this formula ?
Obs: In the picture the angle is something like -45º.

An video of the problem : https://youtu.be/W4Kj1xEpXnU

Ok… again with quaternions.

Imagine you created a Quaternion with rotation 200 degrees. What do you think you’d get back as rotation around y? (hint, not 200 degrees). What about 180 degrees? Do you think you’d get 180 degrees out again? (could be, could be not.)

Bottom line, and I cannot emphasize this enough… if you need to know ANGLES then you must keep angles and construct your quaternions from them.

I’m not really convinced you need to know angles at all (exceedingly rare to need to know them) but if you do then you cannot reliably get them back from a quaternion. How many different ways to say that, I don’t know.

A quaternion represents the most compact form of a rotation. And that may have no real relation to the angles you gave it.

So many questions on the forum lately about this. “I want to do all of my math in spherical coordinates but how do I get them back from a quaternion…” you can’t.

Anyway, “pointing to the mouse” is actually what you need to tease out here because you don’t need angles to do that at all. Basic steps: find out how far your cannon is away from the camera (dot product on the camera direction) then use cam.getWorldCoordinates() to project the mouse location into 3d space (remember to convert z distance to projection space)… once you know the world space position you want to look at the rest should be more straight forward.

you don’t need angles to do that at all

You are suggestion to do a lookat in the turret into the mouse point right ?
I did try that, I had some problems to get the up vector, but I maybe didnt try enough…


…is the up vector for the cannon.

Humm, good call !
I never used this function, and it seens to be doing the magic :

    Vector3f posOnZSpatial = spatial.getWorldTranslation().mult( new Vector3f(0,1,0) );
    Vector3f posOnZCamera  = chaseCam.getCamera().getLocation().mult( new Vector3f(0,1,0) );
    float distanceFromCamera=posOnZCamera.distance(posOnZSpatial);
    Vector2f posMouse2d = inputManager.getCursorPosition();
    Vector3f posMouse3d = chaseCam.getCamera().getWorldCoordinates(new Vector2f(posMouse2d.x, posMouse2d.y), 0.95f).clone();

I am not sure how to use it thought, it seens it expects the range from the camera fustrum and it is betewen 0 and 1 ? I just put 0.95 and it seens to be working, but I guess its not precise.

I guess I have the diference in Z on the distanceFromCamera, so how do I map it into this function ?

If only there were javadoc to explain it all:

Note: The above looks a little silly… as it’s effectively spatial.getWorldTranslation().y
…same with the camera one. Not sure why you do that.

I was using this code because y in both objects maybe different, when the ship moves its not always in the center, but the camera is, also the camera zoom in and out in some cases.
I didnt figure out how to make the parameter projectionZPos works, if I put 1 in the value it gets the correct mouse pos, but in the far deep, if I put less than 1 it mess up with the mouse pos. I tried to convert the distance using diverse formules from the javadoc, none get closes to the results I was expecting.
I tried to use the getViewToProjectionZ it kind of works, but only when the ship is in the middle :

Repeating myself: the distance from the camera to the ship is the dot product of the ship location with the view vector.

Vector3f shipPosition = …
Vector3f cameraPos = …
Vector3f relative = shipPosition.subtract(cameraPos);
float distance = relative.dot(camera.getDirection());

Then read the javadoc I linked because I don’t think you have.

Whaatttt !!! That getDirection did the magic mister wizard !!!
Once again thank you !

Note: that wasn’t the point of what I was saying.

someVector.mult(0, 1, 0) is going to be someVector.y no matter what you do.

Heheh… well, I said it before.