BIM轻量化之路(五)-多文件加载及缓存

一、多文件加载

通过revit将很多专业文件合并成一个文件,稍微大点的文件合并的过程也会很痛苦,然后导出的GLTF文件很大threejs加载往往会内存溢出,一般来说一个文件大于50M,THREEJS就不好加载进来,往往会内存溢出,对于互联网上的加载,超过30M的文件加载用户体验及其差。所以需要对多文件进行分部加载,使用load多个文件加载至场景渲染。
部分代码:

CsscModelCore.prototype.loadGitfDraco = function(instance){
    let gLTFLoader = new THREE.GLTFLoader()
    let dracoLoader = new THREE.DRACOLoader();
    dracoLoader.setDecoderPath('/js/plugin/threejs/examples/js/libs/draco/gltf/');
    dracoLoader.setDecoderConfig({ type: 'js' });
    gLTFLoader.setDRACOLoader(dracoLoader);
    loadCsscModel(instance.settings.urls[0],instance.settings.urls,gLTFLoader,instance);
}
function loadCsscModel(url,urls,gLTFLoader,instance){
    let indexUrl = 0;
    for (let i = 0; i < urls.length; i++) {
        if(urls[i] == url){
            indexUrl = i;
            break;
        }
    }
    $('#loadding_total').html('总计:'+urls.length+"个文件,当前:"+indexUrl+".");
    gLTFLoader.load(url, function(obj) {
        obj.scene.rotateY(Math.PI);
        instance.scene.add(obj.scene);
        instance.setCenter(instance);
        if(indexUrl < urls.length -1){
        //递归加载文件
            loadCsscModel(urls[indexUrl+1],urls,gLTFLoader,instance);
        }else{
            instance.render();
            $('#loading').hide();
        }
    }, onProgress);
}
  • 通过数组和递归将模型加载至场景
  • 加载时可以增加遮罩提示用户加载进度
    效果如下:
    在这里插入图片描述

二、缓存的使用

1.threejs的cache

新版的threejs支持了缓存的机制,load的数据文件会存储在本地

Cache 的结构:

var Cache = {
		enabled: false,
		files: {},
		add: function ( key, file ) {
			if ( this.enabled === false ) { return; }
			// console.log( 'THREE.Cache', 'Adding key:', key );
			this.files[ key ] = file;
		},
		get: function ( key ) {
			if ( this.enabled === false ) { return; }
			// console.log( 'THREE.Cache', 'Checking key:', key );
			return this.files[ key ];
		},
		remove: function ( key ) {
			delete this.files[ key ];
		},
		clear: function () {
			this.files = {};
		}
	};

threejs在加载文件的时候会首先判断Cache中是否存在已加载的文件,如果已经加载直接从缓存中读取
代码片段(示例):

load: function ( url, onLoad, onProgress, onError ) {
			if ( url === undefined ) { url = ''; }
			if ( this.path !== undefined ) { url = this.path + url; }
			url = this.manager.resolveURL( url );
			var scope = this;
			var cached = Cache.get( url );//判断是否存在加载数据
			if ( cached !== undefined ) {
				scope.manager.itemStart( url );
				......

2.Cache与IndexedDB

每次刷新页面都会重新拉取模型文件,不能读取本地缓存,影响用户体验,所以需要将模型数据手动加载至浏览器缓存,对于比较大的数据存储在IndexedDB中是比较合适的,IndexedDB允许储存大量数据,能建立索引,这些都是 LocalStorage 所不具备的,更接近 NoSQL 数据库,可按照key,value的方式操作。
通过与threejs 的Cache结合,我们可以实现首次刷新页面从服务端拉取数据,再次刷新从IndexedDB获取模型数据,减少带宽的使用率,提高threejs加载速度。
代码片段:

function intThreejsCache(){
	let request = window.indexedDB.open("modelDB", 1);
	request.onupgradeneeded = (ev) => {
		modelDb = ev.target.result;
		if (!modelDb.objectStoreNames.contains('info')) {
			 modelDb.createObjectStore('info');
		}
		console.log("数据库创建成功");
	}
	request.onsuccess = (ev) => {
		console.log("数据库打开成功");
		modelDb=ev.target.result;
		THREE.Cache.enabled = true;//开启缓存
		let transaction = modelDb.transaction(["info"], "readwrite");
		let objectStoreModelDB = transaction.objectStore("info");
		objectStoreModelDB.openCursor().onsuccess = function (event) {
			var cursor = event.target.result;
			if (cursor) {
				if(viewer.settings.urls.indexOf(cursor.key)>-1){
					console.log("indexdb加载模型:"+cursor.key);
					//将文件存入到threejs 的cache中
					THREE.Cache.add( cursor.key, cursor.value );
				}
				cursor.continue();
			}
		};
		transaction.oncomplete=function(event)
		{
			viewer.Init();
		}
	}
	request.onerror = (ev) => {
		console.log("打开数据库失败:"+ev.target.message);
	}
}
  • 每次刷新页面判断IndexedDB中是否存在需要加载的URL文件资源,可根据版本号、名称等判断是否为最新资源,存在则直接加载至cache中
  • 每次load完模型后,将url的文件资源更新至IndexedDB中
    在这里插入图片描述
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值