5

下面的代码旨在模拟 SceneKit 中的默认相机控件,特别是缩放和旋转功能。

但是,代码并不像默认控件那样流畅和通用。

例如,如果您加载这两个模型,则默认缩放对两个模型都有效。然而,下面的代码只适用于模型 1,但对于模型 2 来说缩放速度太快了。

任何帮助,将不胜感激。

模型一:https ://poly.google.com/view/6mRHqTCZHxw

模型 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

1 回答 1

2

我尝试在默认相机控制器中重新创建 SCNCamera 旋转。但它不如默认相机那么流畅。因此,我添加了具有两个最小触摸的平移手势,并将该功能留空,什么也不做。这将单独使用默认相机旋转属性,并避免https://developer.apple.com/documentation/scenekit/scnview/1523171-allowscameracontrol中提到的默认相机的以下两个属性

1.用两根手指平移以在其局部 xy 平面上平移相机 2.用三指垂直平移以将相机向前向后移动

//Pan Gesture
let gesture = UIPanGestureRecognizer(target: self, action: #selector(panDetected(sender:)))
gesture.maximumNumberOfTouches = 3
gesture.minimumNumberOfTouches = 2
self.sceneView.addGestureRecognizer(gesture);

//Doing nothing in pan gesture other than  printing
@objc func panDetected (sender: UIPanGestureRecognizer) {
    print("two pan detected")
}

接下来将捏合手势添加到场景视图,以便控制最小和最大缩放级别


//pinch gesture
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinched(sender:)))
    

self.sceneView.addGestureRecognizer(pinchGesture);
@objc func pinched(sender:UIPinchGestureRecognizer){
    let pinchVelocity = Double.init(sender.velocity)
    //print("PinchVelocity \(pinchVelocity)")

    self.sceneView.pointOfView?.camera!.orthographicScale -= (pinchVelocity/pinchAttenuation)

    if (self.sceneView.pointOfView?.camera!.orthographicScale)! <= 0.5 {
        self.sceneView.pointOfView!.camera!.orthographicScale = 0.5
    }

    if self.sceneView.pointOfView!.camera!.orthographicScale >= 1 {
        self.sceneView.pointOfView?.camera!.orthographicScale = 1
    }
}

添加 UIRotationGestureRecognizer 以禁用或修改默认相机旋转(用两根手指旋转以滚动相机(在相机节点的 z 轴上旋转)

于 2020-12-18T07:50:21.290 回答