IOS: How to simulate default camera controls in SceneKit?

The code below is intended to simulate the default camera controls in SceneKit, in particular, the zoom and rotate functions.

However, the code is not as smooth and versatile as the default controls.

For example, if you load these two models, the default scaling works sequentially for both models. However, the code below only works for model 1, but for model 2 it scales too much.

Any help would be appreciated.

Model 1: https://poly.google.com/view/6mRHqTCZHxw

Model 2: https://poly.google.com/view/cKryD9VnDEZ

    // Create camera
    let camera = SCNCamera()
    camera.automaticallyAdjustsZRange = true
    camera.xFov = 30 
    camera.yFov = 0

    // Compute distance to place camera
    let theta = GLKMathDegreesToRadians(Float(camera.xFov/2))
    let adjacentLength = oppositeLength / Float(tan(theta))

    // Add camera to <cameraNode>
    cameraNode.camera = camera
    cameraNode.position = SCNVector3(x: 0, y: 0, z: adjacentLength)

    // Add <cameraNode> to <orbitNode>
    orbitNode.addChildNode(cameraNode)

    // Add <orbitNode>
    scene.rootNode.addChildNode(orbitNode)

    // Handle pinches
    let pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(didSceneViewPinch))
    pinchRecognizer.delegate = self
    sceneView.addGestureRecognizer(pinchRecognizer)

    // Handle pans
    let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didSceneViewPanOneFinger))
    panRecognizer.minimumNumberOfTouches = 1
    panRecognizer.maximumNumberOfTouches = 1
    panRecognizer.delegate = self
    sceneView.addGestureRecognizer(panRecognizer)

func rotate(recognizer: UIPanGestureRecognizer) {
    // Set throttle value to slow down rotation
    let throttleFactor = Float(40)

    // Compute rotation
    let translation = recognizer.translation(in: recognizer.view!)
    let xRadians = GLKMathDegreesToRadians(Float(translation.x)) / throttleFactor
    let yRadians = GLKMathDegreesToRadians(Float(translation.y)) / throttleFactor

    // Orbit camera via <orbitNode>
    orbitNode.eulerAngles.x -= yRadians
    orbitNode.eulerAngles.y -= xRadians
}


func zoom(recognizer: UIPinchGestureRecognizer) {
    // Set zoom properties
    let minVelocity = CGFloat(0.10)
    let zoomDelta = 0.5

    // Only zoom when gesture changing and when velocity exceeds <minVelocity>
    if recognizer.state == .changed {
        // Ignore gesture on tiny movements
        if abs(recognizer.velocity) <= minVelocity {
            return
        }

        // If here, zoom in or out based on velocity
        let deltaFov = recognizer.velocity > 0 ? -zoomDelta : zoomDelta
        var newFov = cameraNode.camera!.xFov + deltaFov

        // Make sure FOV remains within min and max values
        if newFov <= minXFov {
            newFov = minXFov
        } else if newFov >= maxXFov {
            newFov = maxXFov
        }

        // Update FOV?
        if cameraNode.camera?.xFov != newFov {
            cameraNode.camera?.xFov = newFov
        }
    }
}
+4
source share

Source: https://habr.com/ru/post/1694583/


All Articles