[Solved] Angle problems

I managed to track down and almost fix my shader issue. But now I’m still faced with one last problem.



For my shader I need to figure out the angle of rotation for my model, clockwise. For this, I use the following piece of code:



[java]

float rot = iwc.getRotation().toAngleAxis(Vector3f.UNIT_Y);

System.out.println(FastMath.RAD_TO_DEG * rot);

[/java]



When turning the model clockwise, this works for the odd rotations. So the first rotation yields the correct results, as does the third and so on. The even rotation, the second, the fourth and so on, give weird results.

The same goes for rotating counter clockwise, but the other way around. The odd rotations give odd, and the even rotations give the wanted results.



For the rotations giving the wanted results, I actuall get the angle in the clockwise direction. In the rotations giving the weird results, I get the angle in the counter clockwise rotation.



So, when turning 90 degrees clockwise, I get a result of 90. When turning 90 + 360 = 450 degrees, I would expect to once again get 90 as a result. Instead, I get 270, which is the counter clockwise angle. This, for me, was unexpected.



Can anyone explain this behaviour, and maybe give a hint as to how to fix it?

A Quaternions can give several Euler angles representation.

You cannot foresee the direction of a rotation of more than 180° with a quaternion…usually you’ll have the shorter path.

If you want to do that you have to split your rotation into multiple rotation of less than 180° and multiply them together.

The AnimationFacctory has some code that does that check addRotationAngles or something like that

Ok, I looked at the AnimationFactory. But that’s way more complex then I should need. And it just keeps adding deltas, it never cleans them up as far as I can tell.

This may work for a limited animation, but I’m using it in combo with player movement. This would mean a memory hogger.

“I want to get the angles from this quaternion. I want to convert it to angles… I wonder if there is a method to convert it to angles…”

@ractoc said:
Ok, I looked at the AnimationFactory. But that's way more complex then I should need. And it just keeps adding deltas, it never cleans them up as far as I can tell.
This may work for a limited animation, but I'm using it in combo with player movement. This would mean a memory hogger.


What do you mean adding deltas? modifying (i.e. addLocal, multLocal, etc) doesn't memory leak on either vector or quaternion, you can add to it as many times as you like.. it modifies the internal data but nothing more.

The less obtuse answer:

http://hub.jmonkeyengine.org/javadoc/com/jme3/math/Quaternion.html#toAngles(float[])



toAngleAxis() returns an angle AND an axis… and you are returning the axis right into the UNIT_Y vector. This is all kinds of bad.



toAngles() should do what you want… if you want the rotation around the Y axis then grab the second value in the toAngles() array.

Note: I forgot that since you are doing this in x,y space and not x,z space I think toAngles() will get confused. It will prefer to rotate around Y over X over Z… so for some quadrants you will probably get x,y and odd z rotations.



Instead use:

[java]

Vector3f dir = myRotation.mult(Vector3F.UNIT_Y);

double angleRads = FastMath.atan2( dir.z, dir.x );

[/java]

Yeah, that fixed it, with one slight alteration because I’m in the XY plane, and not in the XZ plane:



[java]

Vector3f dir = iwc.getRotation().mult(Vector3f.UNIT_Y);

double angleRads = FastMath.atan2(dir.x, dir.y);

[/java]

@ractoc said:
Yeah, that fixed it, with one slight alteration because I'm in the XY plane, and not in the XZ plane:

[java]
Vector3f dir = iwc.getRotation().mult(Vector3f.UNIT_Y);
double angleRads = FastMath.atan2(dir.x, dir.y);
[/java]


Hmmm... atan2 is supposed to be y, x. Interesting that this works for you like that.