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

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

我试图保持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)
}
swift scenekit augmented-reality ios11 arkit
1个回答
1
投票

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

boxParent.orientation = (sceneView.pointOfView?.orientation)! //quaternion

此变量使用节点的方向,表示为quaternion(4个分量:x,y,z,w)。

boxParent.eulerAngles = (sceneView.pointOfView?.eulerAngles)!

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

您需要决定使用哪个变量:orientationeulerAngles。我想你会选择方向。

阅读this useful articlethis one关于QuaternionsGimbal Lock是什么。

此外,使用SCNLookAtConstraint对象(节点的负z轴指向约束的目标节点)或SCNBillboardConstraint对象(自动调整节点的方向,使其局部z轴始终指向节点的pointOfView),以自动调整节点的方向,因此相机总是指向另一个节点。

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