我试图让 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)
}
最佳答案
您同时使用了两种类型的旋转。这是不对的!
boxParent.orientation = (sceneView.pointOfView?.orientation)! //quaternion
此变量使用节点的方向,表示为四元数
(4 个分量:x、y、z、w)。
boxParent.eulerAngles = (sceneView.pointOfView?.eulerAngles)!
节点的旋转,表示为俯仰角、偏航角和滚动角,以弧度为单位(3 个分量:x、y、z)。
You need to decide which var you'll be using:
orientation
oreulerAngles
. I suppose you'll choose orientation.
阅读this useful article和 this one关于 Quaternions
以及什么是 Gimbal Lock
。
此外,使用 SCNLookAtConstraint
对象(节点的负 z 轴指向约束的目标节点)或 SCNBillboardConstraint
对象(自动调整节点的方向,使其局部 z- axis always point toward the node's pointOfView) 以自动调整节点的方向,因此您的相机将始终指向另一个节点。
关于swift - 保持节点的 X 轴和 Z 轴与地面平行,同时旋转 Y 轴以面向相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50519465/