首页 文章

如何将节点添加到SceneKit / ARKit场景,保留其位置,但重置其方向/旋转

提问于
浏览
0

我想在场景中添加一个节点,保持相对于相机的位置,但保持场景的方向/旋转 . 到目前为止我到底在哪里......

当我点击屏幕时,我会在场景中添加一个锚点,其变换等于相机的变换 . 然后在 didUpdateNode 中,当锚节点具有其位置信息设置时,我添加一个包含模型的子节点,该模型具有 position.z = -0.5 . 模型节点直接添加到摄像机前面的场景中,并反映摄像机的旋转属性 . 随着手机向下倾斜并以一定角度倾斜,这可能是这样的:

受锚节点的旋转数据影响的模型节点以与摄像机相同的方式旋转 . 这个特殊的模型出现在它的一边 - 我并不关心它,它只是一个占位符 . 同时忽略顶部的红色按钮,用于调试 .

到现在为止还挺好 .

我想要发生的事情而不是这个,因为旋转信息基本上是“重置”,所以它显示在与我的相机相同的高度,并面向默认的面向前方位置 . 如果我以不同的方式旋转相机并在房间内移动,则会在不同的位置添加其他模型,但仍然处于相同的高度和相同的方向 .

这可能看起来像这样 . 想象一下,我只是点击屏幕添加对象,它出现在标准高度,旋转与场景相关,而不是相机 .

我've tried playing around with the node' s eulerAnglesrotationorientation 属性但是我可以't get this to work satisfactorily. Here'是我目前的代码..我've created a blank scene, and I' m使用标准SceneKit项目中的 ship.scn 作为模型:

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

1 回答

  • 0

    我是否遗漏了某些东西,或者您只是希望每个模型具有相同的方向,而不管相机方向如何?

    在这种情况下,您可以将每个模型的方向设置为与会话开始运行时添加的节点相同吗?

    即当会话开始时,您向场景添加一个节点(可见或隐藏),保存其方向,然后再使用它?

相关问题