复制的 SCNGeometry 在当前运行循环中不会立即工作

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

我观察到一个非常奇怪的行为,复制的 SCNGeometry 不能立即工作。我必须等待一个运行循环(

DispatchQueue.main.async
)才能使其工作。这是一个错误还是我做错了什么?

这是我的代码:

  func helper_cloneGeo(geo: SCNGeometry) -> SCNGeometry {
    let copiedGeo = geo.copy() as! SCNGeometry
    copiedGeo.materials = geo.materials.map { $0.copy() as! SCNMaterial }
    return copiedGeo
  }
  
  override init() {
    super.init()

    let geo = readGeo(fn: "alcohol.usdz", texture: "texture.png").geometry!
    
    // HERE!!!
    // SCNGeometry is only clone-able after async!!
    // DispatchQueue.main.async {
      let copiedGeo = self.helper_cloneGeo(geo: geo)
      let newNode = SCNNode(geometry: copiedGeo)
      self.rootNode.addChildNode(newNode)
    // }
    
  }

readGeo
只是一个读取 3D 模型文件的辅助函数,这应该是正确的,因为原始(非克隆)节点可以工作。

您可以在此处下载我的示例项目:https://drive.google.com/file/d/1kYyqCAJXnXqpZc6vaaXORe_UVmLH6wHL/view?usp=sharing

在这个项目中,当你运行它时,它会显示模型。然后,如果您注释掉

DispatchQueue.main.async
(如上面的代码),模型将不会显示。

enter image description here

ios swift scenekit
1个回答
0
投票

通过进行一些基本的调试,您可以看到

geo.elements
geo.sources
都是空的,这就是为什么没有复制任何内容。我怀疑
SCNNode.flattenedClone
(您在
readGeo
中使用的)以某种方式创建了一个具有“惰性”几何形状的节点,该几何形状不会立即创建。

如果您不想异步执行此操作,您始终可以自己运行运行循环。

let geo = readGeo(fn: "alcohol.usdz", texture: "texture.png").geometry!

RunLoop.main.run(until: .now) // run the run loop for just one iteration

let copiedGeo = self.helper_cloneGeo(geo: geo)
let newNode = SCNNode(geometry: copiedGeo)
© www.soinside.com 2019 - 2024. All rights reserved.