If we rotate an object which starts at rotation identity and adjust its Pitch, when it reached 90 degrees we hit Gimbal Lock.
EDIT: [“Given the lack of Quaternion support functions in Verse, I don’t currently see a way around this.”] ApplyPitch does not suffer from this issue. Can the same implementation be carried over so we can calculate angles without fear when using MakeRotationFromYawPitchRoll() ?
Repro:
rotation_test := class(creative_device):
@editable Prop : creative_prop = creative_prop {}
OnBegin<override>()<suspends>:void=
Print("Start rotation_test")
loop:
TurnPitch(1.0)
Sleep(0.0)
TurnPitch(TurnDegrees : float):void=
Transform := Prop.GetTransform()
Position := Transform.Translation
Rotation := Transform.Rotation
Print("TurnPitch Initial Rotation {ToString(Rotation)}")
YPR := Transform.Rotation.GetYawPitchRollDegrees()
if (Yaw := YPR[0], Pitch := YPR[1], Roll := YPR[2]):
Print("Yaw {Yaw} Pitch {Pitch} Roll {Roll}")
NewPitch := Pitch + TurnDegrees
Print("New Pitch {NewPitch}")
NewRotation := MakeRotationFromYawPitchRollDegrees(Yaw, NewPitch, Roll)
Print("Setting new Rotation {ToString(NewRotation)}")
if (Prop.TeleportTo[Position, NewRotation]):
AfterTransform := Prop.GetTransform()
AfterRotation := AfterTransform.Rotation
Print("After rotation {ToString(AfterRotation)}")
else:
Print("Unable to teleport to {Position}, {ToString(NewRotation)}")
else:
Print("could not get default YPR")
Logs:
[2023.05.01-23.51.05:921][974]LogVerse: : TurnPitch Initial Rotation Axis: {x=0.000000,y=-1.000000,z=0.000000} Angle: 89.000000
[2023.05.01-23.51.05:922][974]LogVerse: : Yaw 0.000000 Pitch 89.000000 Roll 0.000000
[2023.05.01-23.51.05:923][974]LogVerse: : New Pitch 90.000000
[2023.05.01-23.51.05:924][974]LogVerse: : Setting new Rotation Axis: {x=0.000000,y=-1.000000,z=0.000000} Angle: 90.000000
[2023.05.01-23.51.05:925][974]LogVerse: : After rotation Axis: {x=-0.000000,y=1.000000,z=-0.000000} Angle: 270.000000
[2023.05.01-23.51.05:956][978]LogVerse: : TurnPitch Initial Rotation Axis: {x=-0.000000,y=1.000000,z=-0.000000} Angle: 270.000000
[2023.05.01-23.51.05:957][978]LogVerse: : Yaw -180.000000 Pitch 90.000000 Roll 180.000000
[2023.05.01-23.51.05:958][978]LogVerse: : New Pitch 91.000000
[2023.05.01-23.51.05:959][978]LogVerse: : Setting new Rotation Axis: {x=-0.000000,y=1.000000,z=-0.000000} Angle: 271.000000
[2023.05.01-23.51.05:959][978]LogVerse: : After rotation Axis: {x=0.000000,y=-1.000000,z=0.000000} Angle: 89.000000
[2023.05.01-23.51.05:983][981]LogVerse: : TurnPitch Initial Rotation Axis: {x=0.000000,y=-1.000000,z=0.000000} Angle: 89.000000
[2023.05.01-23.51.05:984][981]LogVerse: : Yaw 0.000000 Pitch 89.000000 Roll 0.000000
[2023.05.01-23.51.05:985][981]LogVerse: : New Pitch 90.000000
Expected behaviour:
Gimbal lock should not happen.
But if it must happen, it should be handled more effectively and not prevent pitch from advancing past 90.
Notes:
Using Quaternions throughout the rotation system entirely solves this issue due to the extra dimension.