将世界原点自动设置到地板上的新点,并将一个3D模型与之连接。

huangapple go评论103阅读模式
英文:

How do I automatically set the world origin to a new point on the floor and tether a 3D model there

问题

I want to do the followings automatically:

  • (1) 自动异步加载一个3D模型,例如高50厘米的花瓶。
  • (2) 检测地板上垂直于世界原点(设备的初始位置)的点P,并将P设置为新的世界原点。
  • (3) 在(2)中获取的点P处放置(1)中的3D模型。

因此,实际上,如果我侧身走开,我将看到一个花瓶站在我原来的位置上。

在我能执行(3)之前,我需要等待(1)和(2),并且我希望自动执行它们都让我感到困惑。

我应该如何解决这个问题?

我尝试使用以下代码生成一个AnchorEntity:

  1. let floorAnchorEntity = AnchorEntity(plane: [.horizontal],
  2. classification: [.floor],
  3. minimumBounds: [0.5, 0.5])
  4. floorAnchorEntity.name = "floor anchor entity"
  5. arView.scene.addAnchor(floorAnchorEntity)

然后,我尝试“同步”加载一个模型并将其连接到锚定实体:

  1. do {
  2. let modelEntity = try Entity.load(named: modelName)
  3. floorAnchorEntity.addChild(modelEntity)
  4. } catch {
  5. assertionFailure("could not load assets.")
  6. }

我预期在地板上看到模型,但屏幕上没有看到任何内容。另外,锚定实体的“isActive”标志为“false”。

英文:

I want to do the followings automatically:

  • (1) asynchronously load a 3D model, for example a vase 50 cm tall
  • (2) detect the point P on the floor that is vertically down from the world origin (initial location of the device) and set P as the new world origin
  • (3) place the 3D model from (1) at P acquired in (2).

So, in effect, I'd see a vase standing at where I was if I were to step aside.

The fact that I need to wait on both (1) and (2) before I can perform (3), and that I want to perform all of them automatically got me really lost.

How should I approach this problem?

I tried to generate an AnchorEntity with the following:

  1. let floorAnchorEntity = AnchorEntity(plane: [.horizontal],
  2. classification: [.floor],
  3. minimumBounds: [0.5, 0.5])
  4. floorAnchorEntity.name = "floor anchor entity"
  5. arView.scene.addAnchor(floorAnchorEntity)

And load a model 'synchronously' and tether to the anchor entity:

  1. do {
  2. let modelEntity = try Entity.load(named: modelName)
  3. floorAnchorEntity.addChild(modelEntity)
  4. } catch {
  5. assertionFailure("could not load assets.")
  6. }

I was expecting to see the model on the floor but I do not see any thing on the screen. Additionally, 'isActive' flag of the anchor entity is 'false'.

答案1

得分: 1

设置新的世界坐标原点

以下方法可以帮助您异步加载一个Reality Composer场景,提取一个模型,然后创建并跟踪一个水平面锚点(带有一个连接的模型),最后通过Combine的订阅者设置一个新的世界坐标原点。

然而,如果您的跟踪不准确,锚点的姿势和全新的世界坐标原点之间会存在一些差异。因此,在4秒后,我们会修正模型的变换。

  1. import RealityKit
  2. import UIKit
  3. import Combine
  4. class ViewController: UIViewController {
  5. @IBOutlet var arView = ARView(frame: .zero)
  6. var subs: [Cancellable] = []
  7. override func viewDidLoad() {
  8. super.viewDidLoad()
  9. arView.debugOptions = [.showWorldOrigin]
  10. Experience.loadBoxAsync { result in
  11. switch result {
  12. case let .success(scene):
  13. guard let model = scene.steelBox else { return }
  14. let anchor = AnchorEntity(.plane(.horizontal,
  15. classification: .floor,
  16. minimumBounds: [0.5, 0.5]))
  17. anchor.addChild(model)
  18. var sub = arView.scene.subscribe(to: SceneEvents.DidAddEntity.self) { _ in
  19. self.arView.session.setWorldOrigin(relativeTransform:
  20. model.transformMatrix(relativeTo: nil))
  21. }
  22. if subs.count == 0 { subs.append(sub) }
  23. arView.scene.anchors.append(anchor)
  24. DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
  25. print(model.position(relativeTo: nil)) // 1
  26. model.setTransformMatrix(matrix_identity_float4x4, relativeTo: nil)
  27. print(model.position(relativeTo: nil)) // 2
  28. }
  29. case let .failure(error):
  30. print("由于 \(error) 的原因无法异步加载场景")
  31. }
  32. }
  33. }
  34. }

第1次打印结果:SIMD3(-0.011, 0.018, -0.005)

第2次打印结果:SIMD3(0.0, 0.0, 0.0)


附注:

欲了解更多信息,请阅读此帖子

英文:

Setting new World Origin

The following approach helps you asynchronously load a Reality Composer scene, extract a model, then create and track a horizontal plane anchor (with a tethered model), and finally set a new World Origin with the help of Combine's subscriber.

However, there will be some discrepancy between the pose of the anchor and the brand-new World Origin if your tracking is bad. So, after 4 seconds, we rectify model's transform.

  1. import RealityKit
  2. import UIKit
  3. import Combine
  4. class ViewController: UIViewController {
  5. @IBOutlet var arView = ARView(frame: .zero)
  6. var subs: [Cancellable] = []
  7. override func viewDidLoad() {
  8. super.viewDidLoad()
  9. arView.debugOptions = [.showWorldOrigin]
  10. Experience.loadBoxAsync { result in
  11. switch result {
  12. case let .success(scene):
  13. guard let model = scene.steelBox else { return }
  14. let anchor = AnchorEntity(.plane(.horizontal,
  15. classification: .floor,
  16. minimumBounds: [0.5, 0.5]))
  17. anchor.addChild(model)
  18. var sub = arView.scene.subscribe(to: SceneEvents.DidAddEntity.self) { _ in
  19. self.arView.session.setWorldOrigin(relativeTransform:
  20. model.transformMatrix(relativeTo: nil))
  21. }
  22. if subs.count == 0 { subs.append(sub) }
  23. arView.scene.anchors.append(anchor)
  24. DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
  25. print(model.position(relativeTo: nil)) // 1
  26. model.setTransformMatrix(matrix_identity_float4x4, relativeTo: nil)
  27. print(model.position(relativeTo: nil)) // 2
  28. }
  29. case let .failure(error):
  30. print("Failed to asynchronously load scene due to \(error)")
  31. }
  32. }
  33. }
  34. }

  1. // 1st print result: SIMD3<Float>(-0.011, 0.018, -0.005)
  2. // 2nd print result: SIMD3<Float>(0.0, 0.0, 0.0)

P. S.

For more info, read this post.

huangapple
  • 本文由 发表于 2023年5月14日 01:13:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244018.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定