I've found a pretty good solution, which is to simply apply a corresponding geometric transform to the background
property whenever the device orientation changes:
func session(_ session: ARSession, didUpdate frame: ARFrame) {
let image = CIImage(cvPixelBuffer: frame.capturedImage)
filter.setValue(image, forKey: kCIInputImageKey)
let context = CIContext()
if let result = filter.outputImage,
let cgImage = context.createCGImage(result, from: result.extent) {
sceneView.scene.background.contents = cgImage
if let transform = currentScreenTransform() {
sceneView.scene.background.contentsTransform = transform
}
}
}
private func currentScreenTransform() -> SCNMatrix4? {
switch UIDevice.current.orientation {
case .landscapeLeft:
return SCNMatrix4Identity
case .landscapeRight:
return SCNMatrix4MakeRotation(.pi, 0, 0, 1)
case .portrait:
return SCNMatrix4MakeRotation(.pi / 2, 0, 0, 1)
case .portraitUpsideDown:
return SCNMatrix4MakeRotation(-.pi / 2, 0, 0, 1)
default:
return nil
}
}
Make sure you call UIDevice.current.beginGeneratingDeviceOrientationNotifications()
in your viewDidLoad
method first.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…