问题
I'm setting my SceneKit camera to the current CMDeviceMotion
attitude using the CMDeviceMotion extension described in this answer:
func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {
if let motion = motion {
let orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation)
cameraNode.orientation = orientation
}
}
This works beautifully, however, I'd like to block the rotation (roll) and only allow the camera to turn around (yaw) and pitch.
I tried to convert the quaternion back to Euler angles and simply leave roll at 0:
cameraNode.eulerAngles = SCNVector3(
x: orientation.pitch(),
y: orientation.yaw(),
z: 0)
However, this works for only one half of the yaw movement. For the other half, the camera is turned upside down. I suspect this is a Gimbal Lock issue involving Euler angles.
Quaternions are a bit like black magic for me, but is there a way to remove the roll component directly on the quaternion level so I can avoid Euler angles?
来源:https://stackoverflow.com/questions/39026329/how-to-avoid-roll-in-scenekit-camera-controlled-by-core-motion