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

查看:93
本文介绍了使节点的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).

您需要确定将使用哪个var:orientationeulerAngles.我想您会选择方向.

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

阅读这篇有用的文章关于以及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天全站免登陆