Slow Rotation Causes Unexpected Behavior

This is the first time I’ve tried JME. I created a modified copy of the flybycamera for android that used touch input on the left to move and touch input on the right to rotate. I noticed at one point that if I rotated slowly at a certain angle the camera appeared to stop and jiggle at a certain point. I was able to replicate it using a test.

Code:
[java]
private void rotateCamera(float value, Vector3f axis){
Matrix3f mat = new Matrix3f();
mat.fromAngleNormalAxis(rotationSpeed * value, axis);

Vector3f up = cam.getUp();
Vector3f left = cam.getLeft();
Vector3f dir = cam.getDirection();

mat.mult(up, up);
mat.mult(left, left);
mat.mult(dir, dir);

Quaternion q = new Quaternion();
q.fromAxes(left, up, dir);

cam.setAxes(q);

}
[/java]
rotationSpeed is 1.
[java]
@Override
public void update(float tpf){
float hRotation = .1f;
rotateCamera(-hRotation*tpf, initialUpVec);
}
[/java]
this always occurs when the camera is facing the following direction: (0.86890936, 0.0, 0.50035083).

I assumed that this was a floating point error, but I am at a loss of how to fix the problem.

Hm you could for example smooth the rotation, by using the last x values averaged.

The flybycam rounds at a few points to avoid gimbal lock afaik, that might be your issue.

1 Like

It seems that calling [java]q.normalizeLocal();[/java] before calling [java]cam.setAxes(q);[/java] fixed the problem. I’m not certain mathematically why this works though. I do know that it wasn’t a floating point issue. I discovered the solution while researching gimbal lock. Thanks.

FlyByCam is written in such a way that it could support things like roll and truly relative orientation… even though it doesn’t actually do any of those things. But consequently, the code is a bunch more complicated than it needed to be.

A simpler fly by cam would be an app state and would simply track yaw and pitch from the mouse… and the just reconstruct the quaternion when those change. The movement would be nice and smooth. It also resets the base rotation every time instead of constantly building on itself and accumulating errors. FlyByCam can’t really help but accumulate errors because it has no idea where it is (yaw/pitch-wise) at any given time because everything is done in a complicated relative way (not even the best way, in fact).