How can I avoid gimbal lock in code?

There’s a related blueprint thread here:

This is the C++ version I’ve implemented, and the results just seem totally broken:

FRotator A = FRotator(0.f, rotationDelta.Yaw, 0.f);
FRotator B = FRotationMatrix::MakeFromZX(GetActorLocation()*-1.f, GetActorForwardVector()).Rotator();

FQuat AQuat = FQuat(A);
FQuat BQuat = FQuat(B);

SetActorRotation(FRotator(BQuat*AQuat));

AddActorLocalRotation(FRotator(rotationDelta.Pitch, 0.f, rotationDelta.Roll));

Am I close? Note that I am adjusting the actor directly, rather than adjusting the controller. I assume that shouldn’t matter if I don’t have the flags set for the pawn to take rotation from the controller.

This ended up working:

FTransform newTransform = GetTransform();
newTransform.ConcatenateRotation(rotationDelta.Quaternion());
newTransform.NormalizeRotation();
SetActorTransform(newTransform);

However, be careful if you’re using a spring arm with your camera. You’ll need to update the spring arm implementation to work w/ 6DoF, as well.