I thought simply setting self.rotation = SCNVector4(0, 1, 0, camera.eulerAngles.y) is enough, but not really good enough in reality. I don't know why it is not.
Nor do I undertand why the sample code does a good job. Especially why yaw is calculated using atan2f(camera.transform.columns.0.x, camera.transform.columns.1.x)?
Can someone explain the underlying math to me? Thanks.
// Correct y rotation of camera square
if let camera = camera {
let tilt = abs(camera.eulerAngles.x)
let threshold1: Float = .pi / 2 * 0.65
let threshold2: Float = .pi / 2 * 0.75
let yaw = atan2f(camera.transform.columns.0.x, camera.transform.columns.1.x)
var angle: Float = 0
switch tilt {
case 0..<threshold1:
angle = camera.eulerAngles.y
case threshold1..<threshold2:
let relativeInRange = abs((tilt - threshold1) / (threshold2 - threshold1))
let normalizedY = normalize(camera.eulerAngles.y, forMinimalRotationTo: yaw)
angle = normalizedY * (1 - relativeInRange) + yaw * relativeInRange
default:
angle = yaw
}
self.rotation = SCNVector4(0, 1, 0, angle)
}