不明白visionOS RealityKit的坐标转换

问题描述 投票:0回答:1

我想将世界坐标转换为 RealityKit 实体的本地坐标。 根据 the docs,这应该可以使用

convert(position:from:)
来调用实体。 由于它没有按预期工作,我写了一个小测试项目。我使用了 Apple 的visionOS 沉浸式应用程序模板,并对其进行了轻微修改。这是我的沉浸式视图:

struct ImmersiveView: View {
    var body: some View {
        RealityView { content in
            var defaultMaterial = UnlitMaterial()
            defaultMaterial.color.tint = .brown
            let mesh = MeshResource.generateBox(size: 1)
            let boxEntity = ModelEntity(mesh: mesh, materials: [defaultMaterial])
            let anchorEntity = AnchorEntity(world: SIMD3<Float>(0, 0, -4))
            anchorEntity.addChild(boxEntity)
            content.add(anchorEntity)
            
            let coordinate = SIMD3<Float>(0.1, 0.2, 0.3)
            let coordinateFrom = boxEntity.convert(position: coordinate, from: nil)
            let coordinateTo = boxEntity.convert(position: coordinate, to: nil)
            print("coordinateFrom: \(coordinateFrom)")
            print("coordinateTo: \(coordinateTo)")
        }
    }
}

它包含一个在主窗口前面可见的框。盒子不在原点 (z = -4)。

出乎意料的是,

coordinateFrom
以及
coordinateTo
等于
coordinate
。我预计
coordinateFrom
会有所不同,因为盒子不在原点。
我错过了什么?

entity realitykit coordinate-transformation visionos
1个回答
0
投票

我的一个朋友找到了解决方案:
显然,在坐标转换函数工作之前必须渲染视图。
这是演示转换的扩展代码:

struct ImmersiveView: View {
    @State private var coordinateFrom = SIMD3<Float>(0, 0, 0)
    @State private var coordinateTo = SIMD3<Float>(0, 0, 0)
    @State private var anchorPosition = SIMD3<Float>(0, 0.0, -4)

    var body: some View {
      ZStack {
          RealityView { content in
              var defaultMaterial = UnlitMaterial()
              defaultMaterial.color.tint = .brown
              let mesh = MeshResource.generateBox(size: 1)
              let boxEntity = ModelEntity(mesh: mesh, materials: [defaultMaterial])
              boxEntity.name = "box"
              let anchorEntity = AnchorEntity(world: anchorPosition)
              anchorEntity.name = "anchor"
              anchorEntity.addChild(boxEntity)
              content.add(anchorEntity)

              print("---- not yet rendered coords")
              updateCoordinates(boxEntity: boxEntity)
          }
          update: { content in
              if let anchorEntity = content.entities.first?.findEntity(named: "anchor") as? AnchorEntity {
                  anchorEntity.setPosition(anchorPosition, relativeTo: nil)
              }
              if let boxEntity = content.entities.first?.findEntity(named: "box") as? ModelEntity {
                  updateCoordinates(boxEntity: boxEntity)
              }
          }
          VStack {
              Text("Coordinate From: \(coordinateString(coordinateFrom))")
              Text("Coordinate To: \(coordinateString(coordinateTo))")
              Button(action: {
                  anchorPosition += SIMD3<Float>(Float.random(in: -1..<1), 0, 0)
              }, label: { Text("Move") })
          }
          .padding()
          .background(Color.black.opacity(0.5))
          .cornerRadius(10)
          .foregroundColor(.white)
      }
    }
    private func updateCoordinates(boxEntity: ModelEntity) {
        let coordinate = SIMD3<Float>(0.1, 0.2, 0.3)
        let coordinateFrom = boxEntity.convert(position: coordinate, from: nil)
        let coordinateTo = boxEntity.convert(position: coordinate, to: nil)
        DispatchQueue.main.async {
            self.coordinateFrom = coordinateFrom
            self.coordinateTo = coordinateTo
        }
        print("coordinateFrom: \(coordinateFrom)")
        print("coordinateTo: \(coordinateTo)")
    }
    private func coordinateString(_ coordinate: SIMD3<Float>) -> String {
        String(format: "(%.2f, %.2f, %.2f)", coordinate.x, coordinate.y, coordinate.z)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.