The trick is, that you accept the new rotation after you’ve done something:
1st frame
Roll a little to the left, accept
Pitch a little up, accept
Strafe a little sideways, accept
next frame
Roll a little to the left, accept
Pitch a little up, accept
Strafe a little sideways, accept
next frame
Roll a little to the left, accept
Pitch a little up, accept
Strafe a little sideways, accept
=>
Otherwise you are stuck with what is called the “gimbal lock” and several other problems.
The trick is to do these things with a little delta time, e.g. 0.01 second or 0.05 seconds
So:
label a:
Roll a little to the left, accept
Pitch a little up, accept
Strafe a little sideways, accept
add 0.01 seconds to time
if(have reached time end of this frame) {
go to next frame;
}
else {
goto a;
}
Note: You can use Quaternion.multLocal
and Quaternion.set
to operate on the same Quaternion object - creating three Quaternion objects for each rotation calculation would be overkill (because it’s 400 Quaternion
objects for one ship for one second when using 0.01 seconds as time delta). See: https://javadoc.jmonkeyengine.org/com/jme3/math/Quaternion.html
Another approach that others like @MoffKalast and @joehot200 have taken is to use the physics engine or to mimic how physics engines do rotations. See this thread: [SOLVED] Realistic-looking airplane rotation
Hope any of the two ideas help,