Swift(SCNCamera)锁定地球仪绕轴旋转

问题描述 投票:0回答:1

来源:https://github.com/DominicHolmes/dot-globe

您好,我正在尝试使上面的存储库中的 3d 地球仪围绕 z 轴锁定。我希望地球仪仅水平旋转并忽略不需要的旋转。如果可能的话,我希望允许地球底部最多旋转 -30 度,最多允许地球顶部旋转 30 度。我对 SCNScene 或 SCNCamera 不太熟练,所以我很感谢您的帮助。目前水平滑动也会旋转整个地球而不是旋转它。

在存储库中,在函数 setupCamera 中添加了以下代码,以防止不必要的地球旋转。但这不起作用。

constraint.isGimbalLockEnabled = true
cameraNode.constraints = [constraint]
sceneView.scene?.rootNode.addChildNode(cameraNode)

我也尝试过这样做,但也没有成功。

   let constraint = SCNTransformConstraint.orientationConstraint(inWorldSpace: true) { (_, orientation) -> SCNQuaternion in
       // Keep the same orientation around x and z axes, allow rotation around y-axis
       return SCNQuaternion(x: 0, y: orientation.y, z: 0, w: orientation.w)
   }

这是设置相机的代码(应在其中添加这些约束)。其余代码位于上面的存储库中。与此问题和代码相关的所有内容都在上面链接的文件中。

   private func setupCamera() {
       self.cameraNode = SCNNode()
       cameraNode.camera = SCNCamera()
       cameraNode.position = SCNVector3(x: 0, y: 0, z: 5)
       let constraint = SCNLookAtConstraint(target: sceneView.scene?.rootNode)
       constraint.isGimbalLockEnabled = true
       cameraNode.constraints = [constraint]
       sceneView.scene?.rootNode.addChildNode(cameraNode)
       
   }
ios swift camera scnnode scncamera
1个回答
0
投票

我看到您的地球仪位于

SCNScene
的中心,相机位于此处以观看地球仪。并且您遇到的约束无法按预期发挥作用。

SCNLookAtConstraint
旨在使一个节点将自身朝向另一个节点。虽然它提供了类似
isGimbalLockEnabled
的功能来防止万向节锁定,但它不提供对限制特定轴上的旋转角度的直接控制
它更适合您希望相机始终面向目标,而不是控制其倾斜或水平旋转限制的场景。

不要使用

SCNLookAtConstraint
,而是尝试使用
SCNTransformConstraint
来控制相机的方向。定义允许绕 y 轴旋转的范围(水平旋转)。

SCNTransformConstraint
允许您定义节点变换的自定义约束,包括其方向。这使您能够精确控制绕特定轴的旋转,例如将绕 x 轴的旋转限制在一定范围内(倾斜),同时允许绕 y 轴自由旋转(水平旋转)。您可以应用自定义逻辑来确定允许的旋转。

在您的情况下,将地球仪围绕 x 轴的倾斜限制为 +/- 30 度。

private func setupCamera() {
    self.cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 5)

    let constraint = SCNTransformConstraint.orientationConstraint(inWorldSpace: true) { (_, orientation) -> SCNQuaternion in
        let clampedX = max(min(orientation.x, 0.261799), -0.261799) // Clamping to +/- 30 degrees in radians
        return SCNQuaternion(x: clampedX, y: orientation.y, z: 0, w: orientation.w)
    }
    
    cameraNode.constraints = [constraint]
    sceneView.scene?.rootNode.addChildNode(cameraNode)
}

max(min())
功能将旋转限制在 +/- 30 度(转换为弧度)。绕 y 轴旋转(水平旋转)仍然不受限制。

© www.soinside.com 2019 - 2024. All rights reserved.