In an instance where I rotate the camera by PI/2 about the x-axis via a keyframe animation (x-y plane is the screen plane), it inadvertently appears to be also snap-rotate by PI/2 about the y-axis (y axis now out of the screen) once the animation completes. When making it rotate ever so slightly less than PI/2 (say - 0.0001), it behaves as expected.
camera.rotation starts at 0, pi, 0
I couldnt get it to do the strange behavior in the playground so I’m doubly confused.
I know that this isn’t a great deal to go on, but if anyone has any ideas as to what might be causing it I would love to hear them.
From my project code (there’s a lot more to it than this just to be clear–but these are the parts directly concerned with the rotation animation in question):
var targetViewRot = new BABYLON.Vector3( ( Math.PI / 2 - 0.0001), Math.PI, 0); //look down
var viewChangeRot_keys = [];
//start
viewChangeRot_keys.push({
frame: 0,
value: camera.rotation
});
//end
viewChangeRot_keys.push({
frame: animFrameRate,
value: targetViewRot
});
viewChangeRot.setKeys(viewChangeRot_keys);
scene.beginDirectAnimation(camera, [viewChangeRot], 0, 1*animFrameRate, false);
It is to do with the target direction being in line with the camera’s upvector. When rotation about x axis is PI / 2 the camera’s direction is in line with (0, 1, 0) the default upvector.
The simplest solution for you is not to allow the x rotation to be exactly PI / 2.
In the following playground https://www.babylonjs-playground.com/#AEXD0L#1 the camera’s up vector is set in line with the z axis and you can see that the rotation does not flip around at the end as camera direction and upvector are not in line. However if in this PG you use the mouse to move around the scene the image flips around with the mouse movements. This is because the upvector is no longer in line with our expectation of what up should be.
That’s all right-- there’s a lot to be worked on in the project. Thanks for the reply!
So in that playground, I believe I get the same result when the rotation is PI/2 and slightly less (upVector being different seems not to matter):
and both do a small snap when you use the mouse to move around (upVector present or not appears to not make a difference)
I wonder if perhaps correcting the upVector after the animation finishes will fix the issue in our project…
I may be saying something stupid, but isn’t a Gimbal Lock problem?
It might worth trying to animate the quaternionRotation property rather than the rotation property.
@Nodragem is correct. Remember that in Euler angles (pitch, roll, yaw) -180 degrees is the same orientation as 180 degrees on a single axis. So once you pass 180 degrees in either direction, the camera will flip. However, if you work in Quaternions, you can rotate endlessly on any axis.
Here’s a topic from the old forum that covers many aspects of working in Cartesian space. If you’re not familiar with this, I recommend spending some time reviewing this topic. However, I just saw an error I made where I wrote the limits in Euler angles was -90 to 90 degrees. I used to write posts in the middle of the night (like tonight), and I can’t believe no one caught it.
So are there any downsides to using Quaternions to do the rotations instead using say var abcQuaternion = BABYLON.Quaternion.RotationAlphaBetaGamma(alpha, beta, gamma); ?
I was doing some reading on the topic and it was suggested that it may also be computationally more efficient to be dealing with Quaternions rather than the Euler angles as well, which if true would make a pretty compelling case for using Quaternions instead.
I’ll probably test out changing the rotation to be Quaternion based once I revisit this aspect of the project (its in a brainstorming phase and familiarity phase so everything can change still).