在babylon.js中数据加载和渲染是异步执行的,这中间就会有等待的时间,那这时间内,如何实现我们的动画呢?我们如何知道模型加载了多少?什么时候结束?当模型比较大,渲染时间较长,我们怎么知道场景什么时候渲染完成了呢?下面我们就一起探索一下
异步加载模型
babylon.js中提供了大量的加载不同格式的数据的类,在不借助插件的情况下gLTF, obj, stl等常见的数据格式,最常用的例如
BABYLON.SceneLoader.Append("./", "duck.gltf", scene, function (scene) {
// do something with the scene
});
通过这些常用的方法,模型会在加载和渲染的时候用默认的加载中动画,这方法好处就是用法简单,而且这个加载中的动画也不丑;但是会有一个缺点,可能你已经发现了,你没有办法再回调中获取到加载进来的模型,只能在场景中便利找到,还有加载的进度也看不到
那如何自定义动画或者获取模型加载的进度呢
首先要加载动画我们就需要先隐藏默认的动画,方法如下
engine.hideLoadingUI = () => {
}
加载模型不再用上面那个方法,而是用BABYLON.SceneLoader.LoadAssetContainer,由于也是异步的我们封住一下返回一个Promise然后用async.await的方式调用,看起来更加简介
public loadAsset(
rootUrl: string,
sceneFilename: string,
callback?: (event: BABYLON.ISceneLoaderProgressEvent) => void
): Promise<BABYLON.AssetContainer> {
return new Promise((resolve, reject) => {
BABYLON.SceneLoader.LoadAssetContainer(
rootUrl,
sceneFilename,
this._scene,
(container) => {
resolve(container);
},
(evt) => {
callback && callback(evt);
},
() => {
reject(null);
}
);
});
用此方法的好处就是我们在回调中拿到的就是我们刚刚加载的模型,而不用去便利整个场景,而且回调里面也有我们要的加载进度数据,最后我们可以在scene.executeWhenReady将动画隐藏,该方法会在数据加载并渲染完成后执行
scene.executeWhenReady(() => {
map.showSceneLoading = false
engine.runRenderLoop(() => {
scene.render();
});
})