I still don’t know what the problem is, but it has something to do with setting an object’s orentation by using a Quaternion. Specifically the Vector.to_track_quat() method.
I don’t usually use AlignAxisToVect() since it often gives buggy results if you use the Y axis, so I usually use something like the following:
lerp_speed = 0.02
target_vector = target.worldPosition.copy() - own.worldPosition.copy()
own.worldOrientation = own.getAxisVect([0.0,1.0,0.0]).lerp(target_vector,lerp_speed).to_track_quat("Y","Z")
Usually this isn’t a problem, since Zeno’s paradox ensures I never reach the target angle. Lerping with a set number like 0.02 will never reach the destination, though it gives a pleasing smooth action getting slower as it gets nearer.
However today I was trying out lerping with a timer which allows full traversal of the range from start to finish. so I re-discovered this problem. In the past I disabled lerping during testing and saw it too.
The solution is to use a safe transformation:
Either use matrix math:
mat_loc = own.worldTransform
mat_rot = mathutils.Matrix.Rotation(math.radians(-90.0), 4, 'Z')
mat_out = mat_loc * mat_rot
start = own.worldTransform
end = mat_out
or convert the Quaternion to a 4x4 matrix before using it to set the transform:
camera_directions = [(0,1,0),(1,0,0),(0,-1,0),(-1,0,0)]
start = mathutils.Vector(camera_directions[2]).to_track_quat("Y","Z").to_matrix().to_4x4()
end = mathutils.Vector(camera_directions[3]).to_track_quat("Y","Z").to_matrix().to_4x4()
I don’t know why this happens, but I think it could also be the source of the problems with AlignAxisToVect() which cause flipping on the y axis.