2016-04-12 103 views
1

當我的SCNView準備就緒並且它實際呈現在我的視圖上時,似乎有一段延遲 - 在視圖出現之前,我總是看到一秒的白色。我能做些什麼來防止這種情況發生?Preload Scenekit場景

func loadModels(frame:CGRect, type:ItemViewType, completion: (() -> Void)!) { 
    self.container = self.scene.rootNode.childNodeWithName("Container", recursively: true)! 
    self.item = self.container.childNodeWithName("Item", recursively: true) 
    self.pattern = self.item.childNodeWithName("TopLayer", recursively: true) 
    self.buttom = self.item.childNodeWithName("BottomRubber", recursively: true)! 
    self.shell = self.item.childNodeWithName("Shell", recursively: true)! 

    self.leftRimLit = self.scene.rootNode.childNodeWithName("leftRimLit", recursively: true) 
    self.specDirLit = self.scene.rootNode.childNodeWithName("specDirLit", recursively: true) 
    self.omni = self.scene.rootNode.childNodeWithName("omni", recursively: true) 

    self.scnView = SCNView(frame: frame) 

    self.scnView!.scene = self.scene 

    self.scnView!.autoenablesDefaultLighting = false 

    //default position 
    self.scnView?.pointOfView?.position = SCNVector3Make(-1.41011, -21.553, 3.34132) 
    self.scnView?.pointOfView?.eulerAngles = SCNVector3Make(1.58788, -0.0114007, -0.0574705) 
    self.scnView?.pointOfView?.scale = SCNVector3Make(1, 1, 1.5) 

    self.item.pivot = SCNMatrix4MakeTranslation(0, 0, 4) 
    self.item.position = SCNVector3(x: 0.387027979, y: 9.58867455, z: 3.71733069) 
    self.item.scale = SCNVector3(x: 1.0999999, y: 1.0999999, z: 1.10000002) 
    self.item.rotation = SCNVector4(x: 0.865282714, y: 0.455411941, z: 0.20948948, w: 2.20000005) 

    self.container.pivot = SCNMatrix4MakeTranslation(0, 0, 0) 

    self.setBackground(type) 
    self.setItemPosition(type) 

    completion() 
} 

一旦最終出現,所有定位背景都是正確的。

self.SO3DItemView = SO3DItemModel(frame: self.view.frame) 
    self.SO3DItemView!.loadModels(self.view.frame, type: .Tada, completion: 
     {() -> Void in 
      self.view.insertSubview(self.SO3DItemView!.scnView!, belowSubview:self.overlay) 

    UIView.animateWithDuration(0.7, delay: 0.0, options: .CurveEaseIn, animations: 
        {() -> Void in 
        self.overlay.alpha = 0.0 
        }, completion:{ (finished: Bool) -> Void in 
         self.view.sendSubviewToBack(self.overlay) 
       }) 

現在我有淡出,以減輕一些這方面的覆蓋,但速度較慢的設備(iPhone 5),我仍然可以看到白色的scnView卡之前完成。

回答

3

SCNSceneRenderer協議(您的SCNView)具有功能prepareObjects:withCompletionHandler:,它將接受SCNScene。這將指示SceneKit執行所需的任何初始化,否則在將數據傳輸到GPU之前它將等待現場添加等。

FWIW我已經決定使用後臺線程來解決這個相同的問題。下面的簡單示例...

let scene = SCNScene() 

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
dispatch_async(dispatch_get_global_queue(priority, 0)) { 

    //lengthy scene setup process 
    let slowNode = SCNNode(geometry:SCNSphere(radius:1.0)) 
    sleep(2) 

    dispatch_async(dispatch_get_main_queue()) 
    { 
     scene.rootNode.addChildNode(slowNode) 
    } 
} 

let quickNode = SCNNode(geometry:SCNBox(width:1.0, height:1.0, length:1.0)) 
scene.rootNode.addChildNode(quickNode) 

scnView.scene = scene 

如果您要運行此代碼,而我沒有運行該代碼,則應該在應用程序啓動時立即看到該代碼框。兩秒鐘後,球體將被添加到場景中。

+0

謝謝,這讓我走上了正軌 – Codermonk