Controlling roll rotation when travelling along bezier curves

Controlling roll rotation when travelling along bezier curves

I am currently working on a curve implementation for use in Unity which includes an editor:

The aim is to get an object to follow the path represented by the curve at a constant velocity. Currently you can place nodes in the curve and modify the weights of each node via handles to control the curve segments between nodes. The curve implementation is a standard Bezier curve.
It works as described except that sometimes the rotation of the object along the path is not great. For instance doing a vertical loop can cause the object to suddenly flip over at certain points. I am currently setting the rotation of the object as follows:
transform.LookAt(bezier(waypoints, handles, lookAhead));

This is computing the point in the curve slightly ahead of the current point and setting the object to "look at" that point. The pitch and yaw of the object will therefore be correct but the roll cannot be easily controlled.
I am currently trying to implement a way to control the roll as the object travels along the path but my maths skills are failing me once again. In the editor I am thinking of placing "roll" nodes along the path which represent the desired roll angle of the object when it reaches that node and interpolating between these nodes for the points in between. My questions are as follows:

How would you determine the yaw and pitch manually at each point? My objects are airplanes so they will always be facing "forward".
How would you know the direction to turn towards to get to the next nodes roll angle? It could be anticlockwise or clockwise I assume. Would I need to also add a control to say which way to turn?
How would I determine what is "up" to orientate myself when controlling the roll angle of the objects along the path?

The linked youtube video shows the problem I am experiencing with using
 transform.LookAt(bezier(waypoints, handles, lookAhead));

alone to control the rotation Quaternion. Watch the plane object rotate when looping vertically. The box sticking out is on the top of the plane object.
When the object reaches the point when it should be "upside down" in the loop it spins quickly to be the facing upwards again. If I can make it so that the up vector of the object along the path follows the "natural" rotation along the curve I can then apply Quaternion control points to properly control rotation. Sorry if this is not entirely clear, I don't know the proper terminology for a lot of this stuff.


Answer 1:

You could just stare the roll value before each

transform.LookAt(bezier(waypoints, handles, lookAhead));

And then just adjust the roll value as you want in a separate algorithm and then reassign it to the airplane’s roll. The Euler roll 0 is always straight and 360 = 0.

So the questions drictly:

  1. Use a quaternion and do a slerp to rotate to that orientation.

  2. Roll values loop at 360 so 270 = -90. You could just test if the value is larger than 180 then the other direction is faster and then do a lerp or some control algorithm.

  3. Roll=0 is always up.

If this did not help pleas clarify what is unclear an I will clarify.

One way to work around this is to store the rotation and whenever the yaw has a difference (remember the 360 looping so 5 to 355 is only 10) from the previous frame is greater than 170 (the yaw will flip 180 when the flip ocur) degreas just add 180 to the roll value.