我想在我的场景中添加一个节点,保持相对于相机的位置,但保持场景的方向/旋转。到目前为止我在哪里...
当我点击屏幕时,我在场景中添加了一个锚点,其变换等于相机的变换。然后在 中didUpdateNode
,也就是锚节点设置其位置信息时,我添加了一个包含模型的子节点,该模型具有position.z = -0.5
. 模型节点直接添加到摄像机前面的场景中,并反映摄像机的旋转属性。随着手机向下倾斜并成一定角度,这可能看起来像这样:
模型节点,受锚节点旋转数据的影响,以与相机相同的方式旋转。这个特殊的模型出现在它的一边——我不担心,它只是一个占位符。也忽略顶部的红色按钮,用于调试。
到目前为止,一切都很好。
我想要做的是让旋转信息基本上被“重置”,因此它出现在与我的相机相同的高度,并面向默认的正面位置。如果我以不同的方式旋转相机并在房间内四处移动,则会在不同的位置添加额外的模型,但仍处于相同的高度和相同的方向。
这可能看起来像这样。想象一下,我刚刚点击了屏幕以添加对象,它以标准高度显示,并且与场景相关,而不是与相机相关的旋转。
我已经尝试过使用节点的eulerAngles
,rotation
和orientation
属性,但不能让它令人满意地工作。这是我到目前为止的代码。我创建了一个空白场景,我使用ship.scn
标准 SceneKit 项目作为模型:
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var anchors = [ARAnchor]()
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Create a new scene
let scene = SCNScene(named: "scene.scn")!
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
if anchors.contains(anchor) {
// Create a new scene
let scene = SCNScene(named: "art.scnassets/ship.scn")!
let shipNode = scene.rootNode.childNode(withName: "ship", recursively: true)!
shipNode.position.z = -5
node.addChildNode(shipNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let currentFrame = sceneView.session.currentFrame {
let translation = matrix_identity_float4x4
let transform = simd_mul(currentFrame.camera.transform, translation)
let anchor = ARAnchor(transform: transform)
anchors.append(anchor)
sceneView.session.add(anchor: anchor)
}
}
}
}