Last active
December 8, 2022 17:45
-
-
Save kylehowells/6cee5ee5cb016d6cf08fecd305f767fe to your computer and use it in GitHub Desktop.
Revisions
-
kylehowells revised this gist
Dec 8, 2022 . No changes.There are no files selected for viewing
-
kylehowells revised this gist
Dec 8, 2022 . No changes.There are no files selected for viewing
-
kylehowells created this gist
Dec 8, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,144 @@ import SceneKit struct SceneKitBoundingBox { let backLeftTop: SCNVector3 let backLeftBottom: SCNVector3 let backRightTop: SCNVector3 let backRightBottom: SCNVector3 let frontLeftTop: SCNVector3 let frontLeftBottom: SCNVector3 let fromRightTop: SCNVector3 let fromRightBottom: SCNVector3 init(min: SCNVector3, max: SCNVector3) { self.backLeftTop = SCNVector3(min.x, min.y, max.z) self.backLeftBottom = SCNVector3(min.x, min.y, min.z) self.backRightTop = SCNVector3(max.x, min.y, max.z) self.backRightBottom = SCNVector3(max.x, min.y, min.z) self.frontLeftTop = SCNVector3(min.x, max.y, max.z) self.frontLeftBottom = SCNVector3(min.x, max.y, min.z) self.fromRightTop = SCNVector3(max.x, max.y, max.z) self.fromRightBottom = SCNVector3(max.x, max.y, min.z) } } func convertToScreen(coord: SCNVector3, fromNode: SCNNode) -> CGPoint { let converted: SCNVector3 = fromNode.convertPosition(coord, to: nil) let projectedPoint: SCNVector3 = self.sceneView.projectPoint(converted) let point = CGPoint( x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y) ) return point } struct ScreenBoundingBox { let backLeftTop: CGPoint let backLeftBottom: CGPoint let backRightTop: CGPoint let backRightBottom: CGPoint let frontLeftTop: CGPoint let frontLeftBottom: CGPoint let fromRightTop: CGPoint let fromRightBottom: CGPoint init(boundingBox: SceneKitBoundingBox, fromNode: SCNNode, convertToScreen: (SCNVector3, SCNNode) -> CGPoint) { self.backLeftTop = convertToScreen(boundingBox.backLeftTop, fromNode) self.backLeftBottom = convertToScreen(boundingBox.backLeftBottom, fromNode) self.backRightTop = convertToScreen(boundingBox.backRightTop, fromNode) self.backRightBottom = convertToScreen(boundingBox.backRightBottom, fromNode) self.frontLeftTop = convertToScreen(boundingBox.frontLeftTop, fromNode) self.frontLeftBottom = convertToScreen(boundingBox.frontLeftBottom, fromNode) self.fromRightTop = convertToScreen(boundingBox.fromRightTop, fromNode) self.fromRightBottom = convertToScreen(boundingBox.fromRightBottom, fromNode) } private var points: [CGPoint] { return [ self.backLeftTop, self.backLeftBottom, self.backRightTop, self.backRightBottom, self.frontLeftTop, self.frontLeftBottom, self.fromRightTop, self.fromRightBottom, ] } var minX: CGPoint { return self.points.min(by: { $0.x < $1.x })! } var maxX: CGPoint { return self.points.max(by: { $0.x < $1.x })! } var minY: CGPoint { return self.points.min(by: { $0.y < $1.y })! } var maxY: CGPoint { return self.points.max(by: { $0.y < $1.y })! } } private func fixFieldOfView() { guard let scene: SCNScene = self.scene else { return } if let firstChild: SCNNode = scene.rootNode.childNodes.first { let boundingBox = firstChild.boundingBox let fullBoundingBox = SceneKitBoundingBox(min: boundingBox.min, max: boundingBox.max) let screenBoundingBox = ScreenBoundingBox( boundingBox: fullBoundingBox, fromNode: firstChild, convertToScreen: self.convertToScreen(coord:fromNode:) ) let minX: CGFloat = screenBoundingBox.minX.x let maxX: CGFloat = screenBoundingBox.maxX.x let minY: CGFloat = screenBoundingBox.minY.y let maxY: CGFloat = screenBoundingBox.maxY.y print("minX: \(minX) - maxX: \(maxX)") print("minY: \(minY) - maxY: \(maxY)") let totalWidth: CGFloat = (maxX - minX) let scaleX = totalWidth / self.screenWidth print("totalWidth: \(totalWidth) - screenWidth: \(self.screenWidth) - scaleX: \(scaleX)") if let cameraNode = self.sceneView.pointOfView, let camera = cameraNode.camera { let fieldOfView = String(format: "%.3f", camera.fieldOfView) print("camera: \(camera) - fieldOfView: \(fieldOfView) - position: \(cameraNode.position)") if scaleX > 1 { let fieldOfView: CGFloat = camera.fieldOfView let newFieldOfView: CGFloat = fieldOfView / (1.0 / scaleX) camera.fieldOfView = newFieldOfView print("fieldOfView: \(fieldOfView) - newFieldOfView: \(newFieldOfView)") } } } DispatchQueue.main.async(execute: { self.sceneView.alpha = 1 }) }