保持节点的X和Z轴平行于地面,同时将Y轴旋转到面对摄像机

时间:2018-05-24 23:20:30

标签: swift scenekit augmented-reality ios11 arkit

我试图让SCNNode始终离相机前方一米远,并操纵节点,使X轴和Z轴始终与地面平行,同时节点围绕Y轴旋转,该节点始终面向摄像头。

下面的代码大部分都达到了我的目标,但是当顺时针或逆时针旋转超过90˚时,节点开始转动。我该如何解决这个问题?

override func viewDidLoad() {
    super.viewDidLoad()

    boxParent.position = (sceneView.pointOfView?.position)!
    boxParent.orientation = (sceneView.pointOfView?.orientation)!
    boxParent.eulerAngles = (sceneView.pointOfView?.eulerAngles)!
    sceneView.scene.rootNode.addChildNode(boxParent)

    boxOrigin.position = SCNVector3(0,0,-1)
    boxParent.addChildNode(boxOrigin)

    box = SCNNode(geometry: SCNBox(width: 0.5, height: 0.2, length: 0.3, chamferRadius: 0))
    box.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
    box.position = SCNVector3(0,0,0)
    boxOrigin.addChildNode(box)
}
    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    boxParent.eulerAngles = (sceneView.pointOfView?.eulerAngles)!
    boxParent.orientation = (sceneView.pointOfView?.orientation)!
    boxParent.position = (sceneView.pointOfView?.position)!

    box.position = boxOrigin.worldPosition
    box.eulerAngles.y = (sceneView.pointOfView?.eulerAngles.y)!
    print(box.eulerAngles)

    sceneView.scene.rootNode.addChildNode(box)
}

1 个答案:

答案 0 :(得分:1)

您同时使用两种类型的旋转。这是不对的!

@Bean
RouterFunction<ServerResponse> routerFunction() {
     route(GET("/redirect"), { req ->
          ServerResponse.temporaryRedirect(URI.create(TargetUrl))
                    .build()
        }
    })

}

此变量使用节点的方向,表示为boxParent.orientation = (sceneView.pointOfView?.orientation)! //quaternion (4个分量:x,y,z,w)。

quaternion

节点的旋转,以俯仰,偏航和滚转角度表示,以弧度为单位(3个分量:x,y,z)。

  

您需要决定使用哪个变种:boxParent.eulerAngles = (sceneView.pointOfView?.eulerAngles)! orientation。我想你会选择方向

阅读this useful articlethis one关于eulerAngles以及Quaternions的内容。

此外,使用Gimbal Lock对象(节点的负z轴指向约束的目标节点)或SCNLookAtConstraint对象(自动调整节点的方向,使其局部z轴始终指向节点的pointOfView)用于自动调整节点的方向,因此摄像机将始终指向另一个节点。