SceneKit:用一个手势围绕点轨道摄像机,同时允许摄像机以不同的手势旋转

时间:2016-08-05 01:16:05

标签: ios uigesturerecognizer scenekit scnnode scnscene

假设SceneKit场景提供类似于Minecraft的视角。有一台相机。摄像机节点的作用类似于" head"一个人的父节点就像"身体一样。"摄像机节点是父节点的子节点,称为" userNode。"

目标:

  • 让用户用一根手指平移以旋转相机。换句话说,相机位置保持固定,但是#34; head"旋转并让用户观看场景,就好像在一个圆圈中转身一样。

  • 让用户用两根手指平移,围绕给定点绕相机运行。换句话说,相机的位置和旋转现在会改变,以便让用户从不同的角度观察同一个点。

到目前为止,下面的代码实现了单指平移行为。问题是如何结合双指泛行为。

选项1:关注this answer,其中介绍了如何绕摄像机旋转。然而,这似乎是次优的,因为场景中已经存在相机节点并且需要额外的节点,同时还在不同相机之间移动场景的视点。

选项2:计算摄像机的新位置和旋转,这样可以避免添加另一个摄像机节点和另一个轨道节点。这感觉就像是更好的答案,但可能更复杂。

func sceneViewPannedTwoFingers(sender: UIPanGestureRecognizer) {
    // Get pan distance & convert to radians
    let translation = sender.translationInView(sender.view!)
    var xRadians = GLKMathDegreesToRadians(Float(translation.x))

    // Get X radians only since only moving horizontally
    xRadians = (xRadians / 10) + curXRadians

    // Rotate & move camera horizontally
    userNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: -xRadians)

    // Compute new position for camera?
}


func sceneViewPannedOneFinger(sender: UIPanGestureRecognizer) {
    // Get pan distance & convert to radians
    let translation = sender.translationInView(sender.view!)
    var xRadians = GLKMathDegreesToRadians(Float(translation.x))
    var yRadians = GLKMathDegreesToRadians(Float(translation.y))

    // Get x & y radians
    xRadians = (xRadians / 10) + curXRadians
    yRadians = (yRadians / 10) + curYRadians

    // Limit yRadians to prevent rotating 360 degrees vertically
    yRadians = max(Float(-M_PI_2), min(Float(M_PI_2), yRadians))

    // Set rotation values to avoid Gimbal Lock
    cameraNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: yRadians)
    userNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: xRadians)

    // Save value for next rotation
    if sender.state == UIGestureRecognizerState.Ended {
        curXRadians = xRadians
        curYRadians = yRadians
    }

    // Set preview block
    setPreviewBlock()
}

问题:

1)在SceneKit中有更简单的方法吗?

2)如果没有,两个选项是否只有两个选项,如果是,那么哪个选择更好?

3)对于选项2,更新userNode或" body"的位置似乎很简单:只计算中心原点的圆周新位置,即轨道点)。对于" head",除了更新rotation(或" head")的cameraNode属性之外还有什么需要注意的吗?似乎将摄像机定向为始终面向轨道点可能更复杂,因为有一部分SceneKit API专用于它,例如SCNLookAtConstraint.

0 个答案:

没有答案