预加载Scenekit场景

时间:2016-04-12 03:41:51

标签: ios swift scenekit scnnode

我的SCNView准备就绪时似乎有一个延迟,当它实际呈现在我的视图上时 - 在视图出现之前我总是会看到一秒钟的白色。我该怎么做才能防止这种情况发生?

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完成之前看到白色。

1 个答案:

答案 0 :(得分:4)

SCNSceneRenderer协议(您的SCNView)具有接受SCNScene的函数prepareObjects:withCompletionHandler:。这将指示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

如果您要运行此代码(我没有),您应该会在应用启动时看到该框立即显示。两秒钟后,球体将被添加到场景中。