2017-09-24 70 views
1

我建立一个ARKit + SceneKit应用程序,它需要在现实世界显示模式。每次用户选择一个按钮时,模型都会改变。添加到SceneKit SCNScene多个节点不阻塞主线程

我试图加载APON按下按钮一个新的模型转换为节点,然后将其添加到场景的根节点,但这会导致直到它被添加到场景相机冻结几秒钟。

然后我读,这可能是更好的负载在启动(viewDidLoad或东西)的所有节点,调用场景的prepare方法,然后将节点添加到场景,但这会导致应用程序冻结了几次几秒钟,直到过程完成。这是我目前正在做的事情,而且效果不佳!有任何想法吗?

记住模型文件是相当重(〜15MB每)

func addNodesToScene() { 
    for menuItem in self.menuItems { 
       let tempScene = SCNScene(named: menuItem.modelPath)! 
       let node = tempScene.rootNode 
       node.scale = SCNVector3Make(0.1, 0.1, 0.1) 
       node.isHidden = true 
       self.foodNodes[menuItem] = node 
       print("\(menuItem.title) node loaded") 
      } 

      print("done loading nodes - adding to scene") 
      self.sceneView.prepare(Array(self.foodNodes.values), completionHandler: { (success) in 
       for nNode in self.foodNodes.values { 
        self.sceneView.scene.rootNode.addChildNode(nNode) 
       } 
      }) 
} 

回答

1

的准备方法准备的车型(和纹理)被快速加载到GPU。您的功能基本上将两个功能合并为一个,从.SCN文件加载节点并为GPU进行准备。该准备方法可以防止在高帧率游戏中出现口吃,例如,它无法解决加载15 MB模型的问题。

如果你要加载,你一定在哪儿找个延迟15MB车型。一个15MB的模型应该提供如此多的细节,以至于延迟(在启动应用程序时)是可以接受的。如果你需要多个,那么真正的问题可能就是模型的大小。你能举一个例子吗?

+0

它实际上缓解了问题,工作得很好。一些延误/冻结,但我可以把一些静态的“加载”屏幕在此期间,而它确实是 – royherma

+0

我不介意延迟,但由于主线程被阻塞,我不能提供任何动画加载器之类的东西,这会导致用户体验不佳UX – royherma

+0

prepare方法已在辅助线程上执行,但可能尝试手动运行后台线程上的第一个for循环?有多少菜单项?另外,您是否检查代码的哪一部分实际上会导致延迟? (加载scenefiles或添加节点)。您可以通过将所有模型添加到单个场景文件中来获得一些性能。 – Xartec