3d模型文件存入浏览器indexDB,加快模型加载速度

// 添加数据到indexdb
    addData(data) {
      let modelStorage = db
        .transaction('threeDModelFile', 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
        .objectStore('threeDModelFile') // 仓库对象
        .add(data);
      modelStorage.onsuccess = function(event) {
        console.log('数据写入成功');
      };
      modelStorage.onerror = function(event) {
        console.log('数据写入失败');
        throw new Error(event.target.error);
      };
    },
    // 根据id获取数据
    getDataByKey(key) {
      let transaction = db.transaction('threeDModelFile'); // 事务
      let objectStore = transaction.objectStore('threeDModelFile'); // 仓库对象
      let modelStorage = objectStore.get(key);
      return modelStorage;
    },
//加载3D模型
initGLTF() {
      // 创建indexDB内存数据库,存储基础路段数据
      let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
      if (!indexedDB) {
        this.loadGltf(that.threeDModelPath);
        // 使用vuex进行缓存,否则使用indexdb缓存,
      } else {
        let that = this;
        let modelId = this.$route.query.id;
        this.showLoading = true;
        indexDB = indexedDB.open('threeDModelFile');
        // 数据库首次创建版本,或者window.indexedDB.open传递的新版本(版本数值要比现在的高)
        indexDB.onupgradeneeded = function(event) {
          db = event.target.result;
          if (!db.objectStoreNames.contains('threeDModelFile')) {
            objectStore = db.createObjectStore('threeDModelFile', { keyPath: 'id' }); // 定义主键,相当于id
            objectStore.createIndex('modelFile', 'modelFile', { unique: false });
          }
        };
        // 数据库成功打开
        indexDB.onsuccess = function(event) {
          //获取db容器
          db = indexDB.result;
          //判断是否有值--objectStore数据存储仓库(表)
          objectStore = db.transaction('threeDModelFile', 'readonly').objectStore('threeDModelFile');
          //此处根据里面是否有sectionCode=0的数据来判断是否已存储路段数据
          let modelStorage = that.getDataByKey(Number(modelId));
          modelStorage.onsuccess = function(event) {
            if (modelStorage.result) {
              // 从缓存中取出
              var url = URL.createObjectURL(modelStorage.result.modelFile);
              that.loadGltf(url);
            } else {
              that.loadGltf(that.threeDModelPath, true);
            }
          };
        };
        // 错误处理
        indexDB.onerror = function(event) {
          console.log('error', event);
        };
      }
    },
loadGltf(url, flag = false) {
      let modelId = this.$route.query.id;
      // 通过gltf加载器加载url
      let that = this;
      var loader = new GLTFLoader();
      try {
        loader.load(
          url,
          gltf => {
            that.showLoading = false;
            that.hasLoaded = true;
            gltf.scene.scale.set(1, 1, 1);
            gltf.scene.position.set(0, 0, 0);
            gltf.scene.traverse(item => {
              if (item instanceof THREE.Mesh) {
                item.material = item.material.clone();
              }
            });
            scene.add(gltf.scene);
            that.animate();
          },
          function(xhr) {
            //把加载进度数据取整然后传递给Vue组件:进度条
            if (that.$refs.threeDLoading) that.$refs.threeDLoading.percentage = Math.floor((xhr.loaded / xhr.total) * 100);
            if (flag && xhr.loaded === xhr.total) {
              //数据入表
              that.addData({
                id: Number(modelId),
                modelFile: new Blob([xhr.currentTarget.response]),
              });
            }
          },
        );
      } catch (err) {
        that.showLoading = false;
        that.$message.error('3D文件未上传或出错,无法加载!');
      }
    },
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将 Three.js 中的 3D 模型存储到 IndexedDB 中可以通过以下步骤实现: 1. 创建 IndexedDB 数据库:使用 IndexedDB API 创建一个数据库,并在其中创建一个存储对象来存储 3D 模型数据。 2. 将 3D 模型转换为二进制数据:使用 Three.js 提供的 GLTFExporter 将 3D 模型转换为二进制数据。 3. 存储二进制数据:将转换后的二进制数据存储到 IndexedDB 中的存储对象中。 4. 从 IndexedDB 中获取数据:使用 IndexedDB API 获取存储对象中的数据,并使用 Three.js 提供的 GLTFLoader 将二进制数据转换为 3D 模型。 下面是一个示例代码,用于将 Three.js 中的 3D 模型存储到 IndexedDB 中并从 IndexedDB 中获取数据: ```javascript // 创建 IndexedDB 数据库 const request = window.indexedDB.open('3d-models', 1); let db; request.onerror = (event) => { console.log('Database error: ' + event.target.errorCode); }; request.onsuccess = (event) => { db = event.target.result; }; request.onupgradeneeded = (event) => { const db = event.target.result; const objectStore = db.createObjectStore('models', { keyPath: 'id' }); }; // 将 3D 模型转换为二进制数据并存储到 IndexedDB 中 const exporter = new THREE.GLTFExporter(); exporter.parse(scene, (gltf) => { const binaryData = new Blob([gltf], { type: 'application/octet-stream' }); const transaction = db.transaction(['models'], 'readwrite'); const objectStore = transaction.objectStore('models'); const request = objectStore.put({ id: 'my-3d-model', data: binaryData }); request.onerror = (event) => { console.log('Error storing 3D model: ' + event.target.error); }; request.onsuccess = (event) => { console.log('3D model stored successfully'); }; }); // 从 IndexedDB 中获取数据并将二进制数据转换为 3D 模型 const loader = new THREE.GLTFLoader(); const transaction = db.transaction(['models'], 'readonly'); const objectStore = transaction.objectStore('models'); const request = objectStore.get('my-3d-model'); request.onerror = (event) => { console.log('Error retrieving 3D model: ' + event.target.error); }; request.onsuccess = (event) => { const binaryData = event.target.result.data; const reader = new FileReader(); reader.onload = (event) => { const gltfBlob = new Blob([event.target.result], { type: 'application/octet-stream' }); const fileReader = new FileReader(); fileReader.onload = (event) => { const gltf = JSON.parse(event.target.result); loader.parse(gltf, '', (object) => { scene.add(object.scene); }); }; fileReader.readAsText(gltfBlob); }; reader.readAsArrayBuffer(binaryData); }; ``` 需要注意的是,IndexedDB 的 API 使用起来比较复杂,需要注意处理异步操作和错误处理。同时,存储和读取大型的二进制数据可能会影响性能,因此需要根据具体情况进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值