使用RealityKit跟踪相机位置

5

如何使用RealityKit来跟踪相机的位置?有一些使用SceneKit的示例,但我找不到使用RealityKit的示例。我需要一个函数,例如:

func session(_ session: ARSession, didUpdate frame: ARFrame) {
    // Do something with the new transform
    let currentTransform = frame.camera.transform
    doSomething(with: currentTransform)
}
1个回答

13

使用ARView相机变换:

您可以使用以下方法访问ARView相机变换:

var cameraTransform: Transform

当前活动摄像机的转换。

假设您的 ARView 被称为 arView ,则可以通过以下方式访问 Transform

let cameraTransform = arView.cameraTransform

然而,更有用的实现方式是通过使用以下内容使您的ARView观察SceneEvents.Update

```csharp this.sceneSubscriber = SceneEvents.Update.Subscribe(OnUpdate); ```
```csharp private void OnUpdate(Scene scene) { // Your code here. } ```

subscribe(to:on:_:)

func subscribe<E>(to event: E.Type, on sourceObject: EventSource? = nil, _ handler: @escaping (E) -> Void) -> Cancellable where E : Event
这意味着您将拥有一个观察者,可以每帧间隔触发一次,并且您可以使用它来执行每帧的自定义逻辑。
要做到这一点,您需要: 首先导入Combine框架。 然后创建一个Cancellable变量:
var sceneObserver: Cancellable!

然后在ViewDidLoad中添加类似以下的内容:

sceneObserver = arView.scene.subscribe(to: SceneEvents.Update.self) { [unowned self] in self.updateScene(on: $0) }

每次更新都会调用以下内容:

/// Callback For ARView Update Events
/// - Parameter event: SceneEvents.Update
func updateScene(on event: SceneEvents.Update) {

  print(arView.cameraTransform)

}

使用ARSessionDelegate:

您也可以通过订阅ARSessionDelegate来从RealityKit内部访问ARCamera,例如:

arView.session.delegate = self

然后注册以下回调函数:

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

具体的工作示例可能如下所示:

extension ViewController: ARSessionDelegate {

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

    guard let arCamera = session.currentFrame?.camera else { return }
    print("""
      ARCamera Transform = \(arCamera.transform)
      ARCamera ProjectionMatrix = \(arCamera.projectionMatrix)
      ARCamera EulerAngles = \(arCamera.eulerAngles)
      """)

  }

}

希望它能为您指明正确的方向。


1
一如既往的好答案!通过Combine订阅更新的好处是什么?我习惯于在SceneKit中使用会话代理,并且除非Combine带来了好处,否则我也更愿意在RealityKit中这样做。 - Peter Pohlmann

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