look at this code:
float rotation = head.getLocalRotation().toAngleAxis(Vector3f.UNIT_Y) * FastMath.RAD_TO_DEG;
if i rotate it -90 deg or I rotate it 90 deg it always returns positive value!
I need to know is it clockwise or counterclockwise??
look at this code:
float rotation = head.getLocalRotation().toAngleAxis(Vector3f.UNIT_Y) * FastMath.RAD_TO_DEG;
if i rotate it -90 deg or I rotate it 90 deg it always returns positive value!
I need to know is it clockwise or counterclockwise??
toAngleAxis() is not at all working like you think and you are also corrupting your Vector3f.UNIT_Y.
You can’t just force an arbitrary rotation to be Y axis based. That’s silly.
You can ask for all of the angles (toAngles()) and hope to get a proper yaw out of it… but you won’t always. A quaternion is a compact representation of rotation and as such has removed all of the ambiguities of the euler angles you seek.
The only real way to keep yaw is to keep yaw separately. Else you will need to calculate it using math and a transformed vector if you need it to always be accurate.
I do have to ask why you even need it, though.
Given that you are interested in the rotation around Y axis.
Jme coordinate system is as:
→ +X
|
V +Z
And +Y goes outside the screen towards the viewer.
Thus given quaternion q you could try:
float clockwise = FastMath.sign(-q.getY()*q.getW());
//clockwise might be 0, not considered here
boolean isClockWise = clockwise == 1.0f;
A test case:
public static void main(String[] args) {
Quaternion q = new Quaternion();
//q (0.0, 0.04997917, 0.0, 0.99875027)
//v (0.9950042, 0.0, -0.099833414)
q.fromAngleNormalAxis(0.1f, Vector3f.UNIT_Y); //anticlock
//q (-0.0, -0.04997917, -0.0, 0.99875027)
//v (0.9950042, 0.0, 0.099833414)
//q.fromAngleNormalAxis(-0.1f, Vector3f.UNIT_Y); //clockwise
float clockwise = FastMath.sign(-q.getY()*q.getW());
boolean isClockWise = clockwise == 1.0f;
System.out.println(isClockWise);
System.out.println("q " + q);
Vector3f v = new Vector3f(1,0,0);
q.multLocal(v);
System.out.println("v " + v);
// -> X
// |
// v Z
}
Do you want to know the head’s full orientation, or simply the direction it is facing? These are two different concepts.
I have a tank model.A node for body a node for head.
I rotated the head in Y to left and right and I want to know what is the shortest way to rotate back to default rotation.
really I dont know whech one is useful direction or the head’s full orientation?
How did you rotate it?
If you rotate it by keeping track of a yaw and calculating the rotation based on that… then you will already know what the yaw is and won’t have to get an incorrect value from the Quaternion.
private boolean is_head_left = false;
public void head_left(float deg) {
is_head_left = true;
mostBeRotation_head_l = head.getLocalRotation().toAngleAxis(Vector3f.UNIT_Y) * FastMath.RAD_TO_DEG + deg;
}
@Override
protected void controlUpdate(float tpf) {
{
if (is_head_left) {
float round = 1;
head.rotate(0, round * FastMath.DEG_TO_RAD, 0);
float rotation = head.getLocalRotation().toAngleAxis(Vector3f.UNIT_Y) * FastMath.RAD_TO_DEG;
if (rotation >= mostBeRotation_head_l) {
is_head_left = false;
mostBeRotation_head_l = 0;
}
}
}
}
Again… that is not doing what you think it is doing. In fact, IT IS CORRUPTING Vector3f.UNIT_Y because it is storing its results back into that value. Do not do it. Cease immediately. At best, you could replace it with
float rotation = head.getLocalRotation().toAngles()[1];
Is that the only way you rotate the head?
If so… keep a yaw value.
I’m not sure how many different ways there are to say that so I’ll just leave it at that. Until you provide some reason why you can’t keep a yaw value then I’m just going to keep suggesting that.
private float yaw;
…then whenever you want to turn the head, adjust the yaw and call:
head.setLocalRotation(new Quaternion().fromAngles(0, yaw, 0));
I needed to an animated head rotation for the tank model so I used SpatialTweens.rotate();
from com.simsilica.lemur.anim.SpatialTweens
and my problem was solved.