ARKit根据触摸位置设置ARAnchor变换

时间:2017-08-03 15:42:12

标签: ios sprite-kit transform arkit

我在XCode 9上玩AR启动应用程序,在场景中创建锚点:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  guard let sceneView = self.view as? ARSKView else {
    return
  }

  // Create anchor using the camera’s current position
  if let currentFrame = sceneView.session.currentFrame {

    // Create a transform with a translation of 0.2 meters in front     
    // of the camera
    var translation = matrix_identity_float4x4
    translation.columns.3.z = -0.2
    let transform = simd_mul(currentFrame.camera.transform, translation)

    // Add a new anchor to the session
    let anchor = ARAnchor(transform: transform)
    sceneView.session.add(anchor: anchor)
  }
}

这总是导致在屏幕中间创建锚点而不管我在哪里点击,这是有道理的,因为我们正在获取当前的相机变换并且仅在z轴上应用平移。

我想把锚放在我用手指轻拍的地方。我可以使用touches.first?.location(in: sceneView)来获取点击的位置,即,只是距离屏幕左上角的点数,但我不确定如何将这些2D点坐标应用于锚点变换米,它们适用于哪个轴。

1 个答案:

答案 0 :(得分:5)

我假设您指的是Apple的ARKitExample项目“将虚拟对象置于增强现实中”。

查看在屏幕中移动(已经放置)模型时调用的方法VirtualObject.translateBasedOnScreenPos(_:instantly:infinitePlane:) - 基本上需要解决您描述的相同问题。

您会发现这会依次调用ViewController.worldPositionFromScreenPosition(_:objectPos:infinitePlane:)

从这种方法中提取出来的方法是:

  
      
  1. 首先对现有的飞机锚点进行命中测试。 (如果任何此类锚点存在且仅在其范围内。)

  2.   
  3. 通过针对特征点云的点击测试收集有关环境的更多信息,但不要返回结果。

  4.   
  5. 如果需要或必要(没有好的功能命中测试结果):对无限水平面进行测试(忽略现实世界)。

  6.   
  7. 如果可用,如果针对无限平面的命中测试,则返回针对高质量特征的命中测试结果   跳过或没有无限飞机被击中。

  8.   
  9. 作为最后的手段,对功能执行第二次未经过滤的命中测试。如果场景中没有任何功能,则结果   返回这里将是零。

  10.   

如您所见,他们会考虑可能或可能不适用于您的用例的各个方面。考虑研究和重复使用(部分)他们的方法。