预加载 Scenekit 场景
Preload Scenekit Scene
我的 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 卡入完成之前我仍然可以看到白色。
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
如果您要 运行 此代码(我没有),您应该会在应用程序启动时立即看到该框。两秒后球体将添加到场景中。
我的 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 卡入完成之前我仍然可以看到白色。
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
如果您要 运行 此代码(我没有),您应该会在应用程序启动时立即看到该框。两秒后球体将添加到场景中。