2

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
    }
}
Damian Dudycz
  • 2,622
  • 19
  • 38

0 Answers0