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

4

我正在玩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个回答

6

我假设你是在询问苹果的ARKitExample项目“在增强现实中放置虚拟物体”。

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

您会发现,这反过来又调用了ViewController.worldPositionFromScreenPosition(_:objectPos:infinitePlane:)

他们的方法如下所示:

  1. 始终首先针对现有平面锚点进行命中测试。 (如果存在任何此类锚点且仅位于其范围内。)

  2. 通过命中测试特征点云收集更多有关环境的信息,但暂时不返回结果。

  3. 如果需要或必要(没有良好的特征命中测试结果):针对无限制的水平面进行命中测试(忽略真实世界)。

  4. 如果可用,则返回针对高质量特征的命中测试结果,如果跳过了针对无限平面的命中测试或未命中任何无限平面。

  5. 作为最后手段,对特征进行第二次未经过滤的命中测试。如果场景中没有特征,则此处返回的结果将为nil。

如您所见,他们考虑了可能适用于您的用例的各个方面。请考虑学习和重用(部分)他们的方法。


谢谢!我实际上是指在XCode中启动新的增强现实应用程序时获得的骨架项目,但我会查看演示应用程序。 - Elise
不客气。这里是链接:https://developer.apple.com/sample-code/wwdc/2017/PlacingObjects.zip 注意:在应用程序菜单中打开“调试可视化”将会更加清晰明了。 - PDK
我认为苹果的worldPositionFromScreenPosition方法专注于将ARAnchors放置在检测到的平面上,而不是在用户前方给定的z处漂浮。 - Adrian Harris Crowne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接