当前位置: 首页 > Web前端 > HTML

WebGL加载本地模型

时间:2023-03-27 22:47:07 HTML

前言threejs、babylon等大多数webgl框架都可以加载obj和gltf模型。我们的引擎,在这三个包的基础上,也有加载模型的loader,所以加载obj和gltf模型也是很简单可以实现的。但是加载的文件都是在线文件,即以url的形式加载。团队开发的3D可视化平台框架需要能够上传obj、gltf等格式的模型。在上传之前,需要预览模型,这就涉及到如何加载本地模型。加载本地模型本文以gltf为例进行说明。加载本地模型的思路是这样的:由于引擎可以通过url机制来加载模型。那么如果有一种机制可以将本地文件及其相关资源(例如纹理)转换为url,则可以使用加载程序访问它们。Blob&File首先,让我们了解一下Blob和File对象。以下内容来自MDN:Blob对象表示一个不可变的、原始数据文件类对象。它的数据可以以文本或二进制格式读取,也可以转换为ReadableStream进行数据操作。Blob不一定代表JavaScript原生格式的数据。File接口基于Blob,继承了blob的功能并对其进行了扩展以支持用户系统上的文件。文件对象是一种特殊类型的Blob,可以在任何Blob类型的上下文中使用。例如,FileReader、URL.createObjectURL()、createImageBitmap()(en-US)")和XMLHttpRequest.send())可以处理Blob和File。createObjectURL对象上的方法createObjectURL可以采用Blob对象或File对象,转换成url对象,语法如下:objectURL=URL.createObjectURL(object);其中object代表一个Blob或File对象,返回的是一个url地址对象加载本地模型有了上面的基础知识,大致思路是出来的:先加载本地文件,读取文件对象(可能是多个File对象,因为一个模型可能包含多个资源文件)。找到主文件(gltfglb等格式)文件,通过createObjectURL方法将主文件转换成url对象找到其他文件,通过createObjectURL方法转换成url对象加载主文件的url,以及通过加载过程中的地址方法重写地址,将相关资源替换为文件的url对象。以上思路的大致代码如下:letfiles=document.getElementById("file-input").files;如果(!files.length)返回;控制台日志(文件);让根文件;constfileMap=newMap();Array.from(files).forEach((file)=>fileMap.set(file.name,file));Array.from(fileMap).forEach(([path,file])=>{if(file.name.match(/\.(gltf|glb)$/)){rootFile=file;rootPath=path.replace(文件名,””);}});constfileUrl=URL.createObjectURL(rootFile);constgltf=awaitload(fileUrl,rootPath,fileMap);函数加载(url,rootPath,assetMap){constindex=url.lastIndexOf("/");常量baseURL=索引===-1?"./":url.substr(0,index+1);constmanager=newdt.LoadingManager();//加载。returnnewPromise((resolve,reject)=>{manager.setURLModifier((url,path)=>{constnormalizedURL=rootPath+decodeURI(url).replace(baseURL,"").replace(/^(\.?\/)/,"");如果(assetMap.has(normalizedURL)){constblob=assetMap.get(normalizedURL);constblobURL=URL.createObjectURL(blob);blobURLs.push(blobURL);返回blobURL;}返回(路径||“”)+网址;});constloader=newdt.GLTFLoader(manager).setCrossOrigin("anonymous");loader.setDRACOLoader(newdt.DRACOLoader());loader.setMeshoptDecoder(MeshoptDecoder);constblobURLs=[];让时间=newDate().getTime();loader.load(url,(gltf)=>{constscene=gltf.scene||gltf.scenes[0];constclips=gltf.animations||[];if(!scene){thrownewError("This模型不包含场景");}console.log("delta",newDate().getTime()-时间);blobURLs.forEach(URL.revokeObjectURL);解决(gltf);},未定义,拒绝);});可以编写简单的工具来帮助开发人员和建模人员随时检查模型的状态。除了gltf模型,其他格式的模型,比如fbx或者obj,也可以进行类似的操作。对可视化感兴趣的可以和我交流,微信541002349。关注公众号“ITMan表叔”,及时收到更多有价值的文章。