I am making a 3D board game using SceneKit. The board itself is flat, but the pieces on it are 3D. I want to position the camera such that it is looking down at the board at an angle like this:
camera
/
/
/
/
/
board /
___________
I want to position the camera such that the entire board is in view, and not small. I know the board's dimensions at runtime, but not at compile time though, because the user can choose from many different boards to play the game.
I tried to calculate how far the camera will at least have to be to see the full width of the board. I drew a diagram like this:
and worked out that the distance is the half the width of the board divided by tan(FOV/2).
Translating that to code:
private func setupCamera(boardWidth: CGFloat, maxBoardZ: CGFloat, boardCenterX: CGFloat) {
cameraNode = SCNNode()
let camera = SCNCamera()
cameraNode.camera = camera
let boardRadius = boardWidth / 2
let cameraDistance = boardRadius / tan(degreesToRadians(camera.fieldOfView) / 2)
let cameraHeight: Float = 10
cameraNode.position = SCNVector3(x: Float(boardCenterX), y: cameraHeight, z: Float(maxBoardZ + cameraDistance))
cameraNode.eulerAngles.x = -0.5
}
cameraNode is a property of the scene to which I later set the scene view's pointOfView to.
This looks okay on portrait mode (this is only a portion of the whole phone screen):
The camera couldn't have moved much closer to the board without cutting off parts of the board.
But in landscape, the board is extremely small compared to the SCNView that it is in:
The camera could have moved a lot closer! I would have expected something like:
Notice the white background region - that's the SCNView.
I thought the FOV might have changed in landscape, but when I checked in the debugger, the FOV is always 60 degrees, no matter the orientation. It seems like even though SCNCamera has a fieldOfView property, SCNView also has its own, separate, FOV that depends on its width and height, and I have no idea how to access it.
How can I position the camera such that the whole board just fits inside the SCNView?



