Posts

Post not yet marked as solved
4 Replies
1.5k Views
SwiftUI Gestures like MagnificationGesture seem well targeted to manipulating a View. In an app using SceneKit, I am usually most interested in manipulating the SceneView’s scene (SCNScene type) contents. As in this example, in which I’m using MagnificationGesture to change the FOV of SceneView’s pointOfView node's camera. What I’ve coded works, but I long ago learned that working code doesn’t mean it works well or performantly. So my question is whether I am doing the MagnificationGesture correctly to change the FOV of the camera in the pointOfView node? Please use simple words in small sentences in your advice and criticisms. import SwiftUI import SceneKit struct ContentView: View { &#9;&#9;@State private var magnify&#9;&#9;&#9;&#9;&#9;= CGFloat(1.0) &#9;&#9;@State private var doneMagnifying&#9; = false &#9;&#9;@GestureState var magnifyBy&#9;&#9;&#9;&#9; = CGFloat(1.0) &#9;&#9;var magnification: some Gesture { &#9;&#9;&#9;&#9;MagnificationGesture() &#9;&#9;&#9;&#9;&#9;&#9;.updating($magnifyBy) { (currentState, gestureState, transaction) in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;gestureState = currentState &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print("magnifyBy = \(self.magnifyBy)") &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;.onChanged{ (value) in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.magnify = value &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;.onEnded { _ in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.doneMagnifying = true &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9;// The camera node for the scene. &#9;&#9;var cameraNode: SCNNode? { &#9;&#9;&#9;&#9;get{ &#9;&#9;&#9;&#9;&#9;&#9;var node = SCNNode() &#9;&#9;&#9;&#9;&#9;&#9;node = aircraftScene.rootNode.childNode(withName: "distantCameraNode", recursively: true)! &#9;&#9;&#9;&#9;&#9;&#9;let maximumFOV: CGFloat = 25 // This is what determines the farthest point into which to zoom. &#9;&#9;&#9;&#9;&#9;&#9;let minimumFOV: CGFloat = 90 // This is what determines the farthest point from which to zoom. &#9;&#9;&#9;&#9;&#9;&#9;let currentFOV = node.camera?.fieldOfView &#9;&#9;&#9;&#9;&#9;&#9;if !doneMagnifying { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print("Still magnifying") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;node.camera?.fieldOfView *= magnifyBy &#9;&#9;&#9;&#9;&#9;&#9;} else { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print("Done magnifying. Yippeee!!!") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;node.camera?.fieldOfView *= magnify &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;if node.camera!.fieldOfView <= maximumFOV { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;node.camera!.fieldOfView = maximumFOV &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;if node.camera!.fieldOfView >= minimumFOV { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;node.camera!.fieldOfView = minimumFOV &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;return node &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9;var aircraftScene: SCNScene { &#9;&#9;&#9;&#9;get { &#9;&#9;&#9;&#9;&#9;&#9;print("Loading Scene Assets.") &#9;&#9;&#9;&#9;&#9;&#9;guard let scene = SCNScene(named: "art.scnassets/ship.scn") &#9;&#9;&#9;&#9;&#9;&#9;else { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print("Oopsie, no scene") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;return SCNScene() &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;return scene &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;ZStack { &#9;&#9;&#9;&#9;&#9;&#9;Color.black.edgesIgnoringSafeArea(.all) &#9;&#9;&#9;&#9;&#9;&#9;SceneView ( &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;scene: aircraftScene, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;pointOfView: cameraNode, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;options: [] &#9;&#9;&#9;&#9;&#9;&#9;) &#9;&#9;&#9;&#9;&#9;&#9;.background(Color.black) &#9;&#9;&#9;&#9;&#9;&#9;.gesture(magnification) &#9;&#9;&#9;&#9;&#9;&#9;VStack() { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Hello, SceneKit!").multilineTextAlignment(.leading).padding() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.foregroundColor(Color.gray) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.font(.largeTitle) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Pinch to zoom.") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.foregroundColor(Color.gray) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.font(.title) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Spacer(minLength: 300) &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;} }
Posted Last updated
.