swift 让RealityKit平面在摄像机移动时保持静止

y0u0uwnf  于 2023-06-21  发布在  Swift
关注(0)|答案(1)|浏览(128)

Keeping model anchored in place when a tracking image is hidden的回答进行跟进
用平面而不是球体来实现答案看起来像这样:

import ARKit
import RealityKit

class ViewController : UIViewController {

  @IBOutlet var arView: ARView!
  var anchorEntity = AnchorEntity(.image(group: "AR", name: "Image"))
  var planeEntity = ModelEntity()

  override func viewDidLoad() {
    super.viewDidLoad()

    arView.session.delegate = self

    // size of image referenced above
    let width = Float(0.2667)
    let height = Float(0.15001875)
    let mesh: MeshResource = .generatePlane(width: width, depth: height)
    let material = SimpleMaterial(color: .systemPink, isMetallic: false)
    self.planeEntity = ModelEntity(mesh: mesh, materials: [material])

    self.anchorEntity.addChild(planeEntity)
    arView.scene.anchors.append(self.anchorEntity)
  }
}

extension ViewController : ARSessionDelegate {

  func session(_ session: ARSession, didUpdate frame: ARFrame) {

    if anchorEntity.isActive {
      anchorEntity.reanchor(.world(transform: planeEntity.transform.matrix),
                      preservingWorldTransform: true)
    }
  }
}

如果你运行你自己的图像,你会看到飞机根本没有牢固地固定在原地。它不会像没有重新锚定的呼叫时那样四处移动,但它仍然是相当移动的。这是我能做的最好的吗?
其次,在我的实际应用中,我希望平面在跟踪图像消失时出现,而不是在它出现时出现,然后保持锚定在图像最后出现的位置。
我一直在修改它,这是我能想到的最好的实现。它不是完全静止的,但它比我尝试过的任何其他方法都要少。有更好的办法吗?我也试过打电话给reanchor,但没有任何区别。

class ViewController: UIViewController {

  @IBOutlet var arView: ARView!
  var anchorEntity = AnchorEntity()
  var planeEntity = ModelEntity()

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    arView.session.delegate = self

    guard let reference = ARReferenceImage.referenceImages(
      inGroupNamed: "AR",
      bundle: nil)
    else { return }

    let config = ARWorldTrackingConfiguration()
    config.detectionImages = reference
    config.maximumNumberOfTrackedImages = 1
    arView.session.run(config)

    let width = Float(0.2667)
    let height = Float(0.15001875)
    let mesh: MeshResource = .generatePlane(width: width, depth: height)
    let material = SimpleMaterial(color: .systemPink, isMetallic: false)
    self.planeEntity = ModelEntity(mesh: mesh, materials: [material])

    self.anchorEntity.addChild(planeEntity)
  }
}

extension ViewController: ARSessionDelegate {

  func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {

    guard let imageAnchor = anchors.first as? ARImageAnchor
    else { return }

    if imageAnchor.isTracked == false {
      arView.scene.anchors.append(self.anchorEntity)
      self.planeEntity.transform.matrix = imageAnchor.transform
      self.anchorEntity = AnchorEntity(anchor: imageAnchor)
    }
  }
}
gk7wooem

gk7wooem1#

我不能回答第二部分,但第一部分也发生在我身上。我使用了相同的reanchor(.world(transform: planeEntity.transform.matrix), preservingWorldTransform: true)解决方案,重新锚定的对象继续移动。最终,我意识到这是因为原始图像锚。图像的大小,如Assets下的AR资源组中所定义的,对于ARKit确定锚与摄像头的距离至关重要;而当我输入错误的大小时,它的放置方式导致了这些运动。
看看它是否也适用于你,更多细节在这里:https://developer.apple.com/documentation/arkit/arreferenceimage/2941027-physicalsize

相关问题