在 Scenekit 中移动相机

Posted

技术标签:

【中文标题】在 Scenekit 中移动相机【英文标题】:Move camera in Scenekit 【发布时间】:2017-03-28 22:35:34 【问题描述】:

我有一个关于在不使用平移手势在 SceneKit 中旋转的情况下向上/向下和向左/向右移动相机的问题。我发现很多关于旋转相机的讨论,我用它来旋转。但是我不知道如何在不旋转相机的情况下移动它。我试图模仿,allowsCameraControl,用户可以用两根手指平移来改变相机的 x 和 y 位置。这是我的平移手势识别器的代码,任何帮助将不胜感激,谢谢!

func handlePan(gestureRecognize: UIPanGestureRecognizer) 

    let numberOfTouches = gestureRecognize.numberOfTouches

    var translation = gestureRecognize.translation(in: gestureRecognize.view!)
    var widthRatio = Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio
    var heightRatio = Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio

    if (numberOfTouches==fingersNeededToPan) 


        self.cameraOrbit.eulerAngles.y = Float(-2 * M_PI) * widthRatio
        self.cameraOrbit.eulerAngles.x = Float(-M_PI) * heightRatio

        //for final check on fingers number
        lastFingersNumber = fingersNeededToPan
    

    if numberOfTouches == 2 

        self.cameraNode.position.x = -(Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio)
        self.cameraNode.position.y = -(Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio)

    


    lastFingersNumber = (numberOfTouches>0 ? numberOfTouches : lastFingersNumber)

    if (gestureRecognize.state == .ended && lastFingersNumber==fingersNeededToPan) 
        lastWidthRatio = widthRatio
        lastHeightRatio = heightRatio
    

【问题讨论】:

澄清一下:你想在不改变摄像机角度的情况下横向移动吗?例如。我面向东北,我一边走一边(向左西北,向右东南),同时继续面向东北? 是的,我只是想在不旋转的情况下向左/向右或向上/向下移动相机,就像使用 allowCameraControl 一样,对不起@HalMueller 【参考方案1】:

如果您想向左/向右或向上/向下滑动,则不需要cameraOrbit 节点(这是Scenekit camera orbit around object 使用的)。

相反,您只想向左/向右(X 轴)或向上/向下(Y 轴)滑动以响应触摸。看起来你正在这样做。但如果cameraNodecameraOrbit 的子代,您将在cameraOrbit 的坐标系中移动,您的手势处理程序也正在旋转该坐标系!使相机节点成为场景根节点的子节点。

现在,当您的相机未与根坐标系对齐时,就会发生令人困惑的事情。如果相机的 X、Y 和 Z 轴平行于场景的 X/Y/Z 轴,您可以调整相机的 X/Y 位置以进行移动。但是如果相机被旋转了,或者指向了 Z 轴,你需要调整相机节点的transform,以便在相机平面内向左/向右或向上/向下移动。我会尽快尝试扩展此答案以证明这一点。

【讨论】:

【参考方案2】:

现在你可以很简单地做到这一点:

scnView.allowsCameraControl = true
scnView.defaultCameraController.interactionMode = .orbitTurntable
scnView.defaultCameraController.inertiaEnabled = true
scnView.defaultCameraController.maximumVerticalAngle = 89
scnView.defaultCameraController.minimumVerticalAngle = -89

【讨论】:

【参考方案3】:

使用保存的方向移动相机

func stepLeft() 
        print("stepLeft")
        if let pov = view.pointOfView 
            pov.localTranslate(by: SCNVector3(-0.5, 0, 0))
        
    
    
    func stepRight() 
        print("stepLeft")
        if let pov = view.pointOfView 
            pov.localTranslate(by: SCNVector3(0.5, 0, 0))
        
    

【讨论】:

以上是关于在 Scenekit 中移动相机的主要内容,如果未能解决你的问题,请参考以下文章

SceneKit 移动相机

SceneKit 球体法线似乎随着相机移动而改变?

如何在 SceneKit 中移动旋转的 SCNNode?

SceneKit:围绕任意点进行轨道运行而无需相机跳跃或将锚点移动到中心?

SceneKit 相机没有移动到正确的位置

在 SceneKit 中禁用相机平移