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

Ios 如何将节点添加到SceneKit/ARKit场景中,保留其位置但重置其方向/旋转,ios,scenekit,scnnode,arkit,arscnview,Ios,Scenekit,Scnnode,Arkit,Arscnview,我想向场景中添加一个节点,保持相对于摄影机的位置,但保持场景的方向/旋转。到目前为止我在哪里 当我轻触屏幕时,我会向场景添加一个锚定,其变换等于摄影机的变换。然后在didUpdateNode中,即锚节点具有其“位置信息设置”时,我添加了一个子节点,其中包含一个模型,该模型具有position.z=-0.5。模型节点直接添加到摄影机前面的场景中,并镜像摄影机的旋转特性。当手机向下倾斜并成一定角度时,这可能看起来是这样的: 受锚节点旋转数据影响的模型节点的旋转方式与摄影机相同。这个特殊的模型出现在

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

当我轻触屏幕时,我会向场景添加一个锚定,其变换等于摄影机的变换。然后在
didUpdateNode
中,即锚节点具有其“位置信息设置”时,我添加了一个子节点,其中包含一个模型,该模型具有
position.z=-0.5
。模型节点直接添加到摄影机前面的场景中,并镜像摄影机的旋转特性。当手机向下倾斜并成一定角度时,这可能看起来是这样的:

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

到目前为止,一切顺利

我想做的是,旋转信息基本上是“重置”的,因此它显示在与我的相机相同的高度,并面向默认的面部向前位置。如果我以不同的方式旋转相机并在房间内移动,则会在不同的位置添加其他模型,但仍然保持相同的高度和方向

可能看起来像这样。想象一下,我刚刚点击屏幕来添加对象,它以标准高度显示,并且旋转与场景相关,而不是与摄影机相关

我尝试过使用节点的
eulerAngles
rotation
orientation
属性,但无法令人满意地使用这些属性。这是我到目前为止掌握的代码。。我创建了一个空白场景,并使用标准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)
        }
    }
  }
}
类ViewController:UIViewController、ARSCNViewDelegate{
@IBVAR场景视图:ARSCNView!
变量锚=[ARAnchor]()
重写func viewDidLoad(){
super.viewDidLoad()
//设置视图的委托
sceneView.delegate=self
//显示统计信息,如fps和计时信息
sceneView.showsStatistics=true
//创建一个新场景
让scene=SCNScene(名为:“scene.scn”)!
//将场景设置为视图
sceneView.scene=场景
}
覆盖函数视图将出现(uo动画:Bool){
超级。视图将显示(动画)
//创建会话配置
let configuration=ARWorldTrackingSessionConfiguration()
配置.planeDetection=.horizontal
//运行视图的会话
sceneView.session.run(配置)
}
覆盖函数视图将消失(u动画:Bool){
超级。视图将消失(动画)
//暂停视图的会话
sceneView.session.pause()
}
func渲染器(渲染器:SCNSceneRenderer,didUpdate节点:SCNNode,用于锚点:ARAnchor){
如果锚定.contains(锚定){
//创建一个新场景
让场景=SCNScene(命名为:“art.scnassets/ship.scn”)!
让shipNode=scene.rootNode.childNode(名称为“ship”,递归:true)!
shipNode.position.z=-5
node.addChildNode(shipNode)
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
super.touchesbeated(touches,with:event)
如果让currentFrame=sceneView.session.currentFrame{
让平移=矩阵\单位\浮动4x4
let transform=simd_mul(currentFrame.camera.transform,transform)
让anchor=ARAnchor(变换:变换)
锚。追加(锚)
sceneView.session.add(锚定:锚定)
}
}
}
}

是我遗漏了什么,还是您只是希望每个模型都有相同的方向,而不考虑摄像头的方向

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


也就是说,当会话开始时,将节点添加到场景中(可见或隐藏),保存其方向,然后稍后再次使用该方向

是我遗漏了什么,还是你只是想让每个模型都有相同的方向,而不考虑摄像机的方向

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


也就是说,当会话开始时,将节点添加到场景中(可见或隐藏),保存其方向,然后稍后再次使用该方向

关于模型位置:您希望重置什么?是否希望飞机显示在您的相机高度?在一个固定的高度?飞机总是出现在你相机的北面?在镜头前,是不是?关于模型方向:您希望它具有一个与相机无关的常数(如始终向北,始终垂直)还是一个混合(如始终面向相机,始终垂直)?也许可以查看一下。@Guig理想情况下,我希望在世界上创建一个平面,z坐标从南向北移动,x坐标从西向东移动,所以在我的初始节点中,我尝试创建它。我确实遗漏了使飞机与北面对齐的细节,因为这涉及到核心位置,这是下一步。现在我只需要它,用外行的话来说,是平的,不旋转的,就像它笔直地坐在地板上一样。关于模型的位置:你到底想重置什么?是否希望飞机显示在您的相机高度?在一个固定的高度?飞机总是出现在你相机的北面?在镜头前,是不是?关于模型方向:您希望它具有一个与相机无关的常数(如始终向北,始终垂直)还是一个混合(如始终面向相机,始终垂直)?也许可以查看一下。@Guig理想情况下,我希望在z坐标所在的世界中创建一个平面