保持节点的 X 轴和 Z 轴平行于地面,同时旋转 Y 轴以面对相机 [英] Keep node's X and Z axes parallel to ground while rotating Y axis to face camera

查看:23
本文介绍了保持节点的 X 轴和 Z 轴平行于地面,同时旋转 Y 轴以面对相机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让 SCNNode 始终距离相机前部一米,并操纵节点以使 X 轴和 Z 轴始终与地面平行,而节点则围绕 Y 轴旋转节点始终面向相机.

I'm trying to keep an SCNNode always one meter away from the front of the camera, and manipulate the node so that the X and Z axes are always parallel to the ground, while the node rotates around the Y-axis so that the node is always facing the camera.

下面的代码大部分实现了我的目标,但是当顺时针或逆时针旋转超过 90˚ 时,节点开始旋转.我该如何解决?

The code below achieves my goal for the most part, but when turning more than 90˚ clockwise or counterclockwise, the node starts turning. How can I fix that?

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)
}

推荐答案

您同时使用两种类型的旋转.这是错的!

You're simultaneously using two types of rotation. It's wrong!

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

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

This variable uses the node’s orientation, expressed as quaternion (4 components: x, y, z, w).

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

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

The node’s rotation, expressed as pitch, yaw, and roll angles, in radians (3 components: x, y, z).

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

You need to decide which var you'll be using: orientation or eulerAngles. I suppose you'll choose orientation.

阅读这篇有用的文章这个 关于 Quaternions 以及什么是 Gimbal Lock 是.

Read this useful article and this one about Quaternions and what a Gimbal Lock is.

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

Also, use SCNLookAtConstraint object (node's negative z-axis points toward the constraint's target node) or SCNBillboardConstraint object (automatically adjusts a node's orientation so that its local z-axis always points toward the node's pointOfView) for automatically adjusting a node’s orientation, so you camera'll be always pointing toward another node.

这篇关于保持节点的 X 轴和 Z 轴平行于地面,同时旋转 Y 轴以面对相机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆