I used to set values of xFov
and yFov
of SCNCamera
to values calculated from camera field of view
and my view frame size
. This was working fine in my AR
engine implementation (with SceneKit
, not ARKit
). In new Xcode I see warning, that xFov
and yFov
were deprecated and I should use fieldOfView
and focalLength
instead. I would like to update my code, but I don't know how to set these variables to correspond exactly to what I used to have. The closest thing is to set fieldOfView
to value I used before for xFov * 2 - but it's not exactly the same, objects are actually appear a little smaller. Is there some way to calculate these new values to work just like if I set xFov and yFov
with given values? What I have are these values that I used to have before for xFov and yFov
so I would like to calculate fieldOfView
and focalLength
from it.
This is how I get xFov
and yFov
values:
private func updateSceneInformation() {
guard let captureDevice = captureDevice, captureDevice.hasMediaType(AVMediaType.video) else { return }
let xFov: Double, yFov: Double
let cameraFieldOfView = Double(captureDevice.activeFormat.videoFieldOfView)
let videoDimentions = CMVideoFormatDescriptionGetDimensions(captureDevice.activeFormat.formatDescription)
let aspect = Double(videoDimentions.width) / Double(videoDimentions.height)
let videoSize: CGSize
if UIApplication.shared.statusBarOrientation.isPortrait {
yFov = cameraFieldOfView
xFov = yFov / aspect
videoSize = CGSize(videoDimensions: videoDimentions).rotated90Degrees
}
else {
xFov = cameraFieldOfView
yFov = xFov / aspect
videoSize = CGSize(videoDimensions: videoDimentions)
}
let aspectSize = videoSize.aspectFill(fitToSize: bounds.size)
let originPoint = CGPoint(x: (bounds.width - aspectSize.width) / 2, y: (bounds.height - aspectSize.height) / 2)
let sceneFrame = CGRect(origin: originPoint, size: aspectSize)
let fieldOfView = FOV(horizontal: xFov, vertical: yFov)
let newSceneInformation = SceneInformation(fieldOfView: fieldOfView, frame: sceneFrame, interfaceOrientation: UIApplication.shared.statusBarOrientation)
if sceneInformation != newSceneInformation {
sceneInformation = newSceneInformation
}
}
On iPhone 6s horizontal this gives me
SceneInformation(fieldOfView: (58.63214874267578, 32.98058366775513), frame: (0.0, -0.09375, 667.0, 375.1875), interfaceOrientation: .landscapeRight)
Frame
Is the frame of SCNView
.
And this is how I was applying these values before (which was working as expected)
override var sceneInformation: SceneInformation {
didSet {
cameraNode.camera?.xFov = Double(sceneInformation.fieldOfView.horizontal)
cameraNode.camera?.yFov = Double(sceneInformation.fieldOfView.vertical)
sceneView.frame = sceneInformation.frame
}
}