cesium模型的本地加载模型

需求

目前有一个需求就是需要从本地拖拽glb文件模型到cesium地球中显示模型

由于相关js库较多 本文章就不涉及拖拽功能了

思路

第一种方案

cesium通过Model.fromGltf函数来读取gltf的url
阅读此函数的源码可知 该函数本身也是从网页下载文件为 arraybuffeer流 后赋值model的gltf属性进行加载模型,但由于gltf只是一个只读属性,所以尝试重写该函数,让本地模型转化为arraybuffer后赋值加载模型

import defined from './Core/defined' import clone from "./Core/clone"; import parseGlb from "./Scene/GltfPipeline/parseGlb"; import getMagic from "./Core/getMagic.js"; import DeveloperError from "./Core/DeveloperError"; import getJsonFromTypedArray from "./Core/getJsonFromTypedArray.js"; function setCachedGltf(model, cachedGltf) { model._cachedGltf = cachedGltf; } CachedGltf.prototype.makeReady = function (gltfJson) { this.gltf = gltfJson; const models = this.modelsToLoad; const length = models.length; for (let i = 0; i < length; ++i) { const m = models[i]; if (!m.isDestroyed()) { setCachedGltf(m, this); } } this.modelsToLoad = undefined; this.ready = true; }; // const gltfCache = {}; // const uriToGuid = {}; Object.defineProperties(CachedGltf.prototype, { gltf: { set: function (value) { this._gltf = value; }, get: function () { return this._gltf; }, }, }); function CachedGltf(options) { this._gltf = options.gltf; this.ready = options.ready; this.modelsToLoad = []; this.count = 0; } function CesiumOverWriteFromGltfFun(options, bimccArrayBuffer) { if (!defined(options) || !defined(options.url)) { throw new DeveloperError("options.url is required"); } options = clone(options); options.cacheKey = 'cacheKey'; options.basePath = 'resource'; const model = new Cesium.Model(options); let cachedGltf = 'gltfCache[cacheKey]'; cachedGltf = new CachedGltf({ ready: false, }); cachedGltf.count = 1; cachedGltf.modelsToLoad.push(model); setCachedGltf(model, cachedGltf); let arrayBuffer = bimccArrayBuffer const array = new Uint8Array(arrayBuffer); if (containsGltfMagic(array)) { // Load binary glTF console.log("Load binary glTF") const parsedGltf = parseGlb(array); cachedGltf.makeReady(parsedGltf); } else { // Load text (JSON) glTF console.log("Load text (JSON) glTF") const json = getJsonFromTypedArray(array); cachedGltf.makeReady(json); } return model; } function containsGltfMagic(uint8Array) { const magic = getMagic(uint8Array); return magic === "glTF"; } export default CesiumOverWriteFromGltfFun;

这样就需要导入很多的工具类,虽然完成了需求,但是除了加大了打包的js的体积外,
还增加了和cesium 源码版本的耦合性,而且在应对没有压缩格式的模型文件(gltf)时需要进行额外的处理方式,代码复用性较差。(不过可以考虑将gltf的json bin等文件压缩为glb文件,这样仍然需要额外的性能开销)
额外的工具类

第二种方案

将模型导入后通过 createObjectURL 函数制造一个内存的url来规避掉安全策略,也能使用model.fromgltf函数。
此时 glb 文件是可以直接createObjectURL后使用model.fromgltf函数
但是gltf仍然需要对gltf文件进行操作 需要将文件中的buffers属性和images属性的uri更换为createObjectURL生成的uri
特别重要的是

URL.createObjectURL(new Blob([JSON.stringify(changedGltf)]))

PS: 必须需要将json格式的gltf文件(changedGltf)进行JSON.stringify字符串化,否则导入后依然不显示。

结果

项目重构,采用第二种方案

参考


__EOF__

本文作者damarkday知识库
本文链接https://www.cnblogs.com/GoodMemoryBlog/p/16598675.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   DAmarkday  阅读(1799)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示