使用webworker和IndexedDB为三个j的加载器 [英] Using webworker and IndexedDB for loader of Three js

查看:181
本文介绍了使用webworker和IndexedDB为三个j的加载器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在多线程中使用threeJS的dracoLoader,然后我选择了Webworker和IndexedDB。我在webworker中获得了正确的Geometry,但是,当我使用IndexedDB将数据传递给主线程时,几何体将更改为普通的JS对象而不是ThreeJS Geometry。几何图形失去了它的功能和一些信息。

I want to use dracoLoader of threeJS in multi-threads, then I selected Webworker and IndexedDB. I have gotten the correct Geometry in webworker, however, when I pass data to main thread using IndexedDB, the geometry will be changed to a normal JS object instead of a ThreeJS Geometry. The geometry lost its functions and some information.

webworker.js

webworker.js

self.saveDrcToIndexedDB = function (drcfinal) {

  var db;
  var request = indexedDB.open("drcDB");

  drcfinal.indexName = self.randomStr();

  request.onupgradeneeded = function(event) {

    console.log('successfully upgraded db');  

    db = event.target.result;
    var objectStore = db.createObjectStore("drcfinal", { keyPath: "indexName"});
  };

  request.onsuccess = function(event) {

    console.log('successfully opened db');

    db = event.target.result;
    var transaction = db.transaction(["drcfinal"], "readwrite");

    var objectStore = transaction.objectStore("drcfinal");
    objectStore.add(drcfinal).onsuccess = function(event) {
      self.postMessage(drcfinal.indexName);
    };
  } 
}

main.js

var worker = new Worker('webworker.js');

worker.addEventListener('message', function(e) {

  indexedDB.open("drcDB").onsuccess = function(event) {

    let db = event.target.result;   
    let objectStore = db.transaction(["drcfinal"]).objectStore("drcfinal");

    objectStore.get(e.data).onsuccess = function(event) {
      console.log(event.target.result);
    };
  }

}, false);

worker.postMessage(somedata);

我可以将正确的几何体转移到主线程吗?或者使用其他工具而不是IndexedDB?或者使用其他多线程工具而不是webworker?

Can I transfer a correct geometry to main thread? Or using other tools instead of IndexedDB? Or using other multi-threading tools instead of webworker?

推荐答案

一种名为结构化克隆。同样适用于通过 postMessage 向WebWorkers发送消息。这种方法不可能复制函数。因此,您无法传输包括其方法在内的完整对象。简单地说,这是一个更好的 JSON.stringify / parse 方法,因为结构化克隆可以例如处理循环依赖。

A mechanism called Structured Cloning is used when storing data in IndexedDB. Same applies to sending messages to and from WebWorkers via postMessage. It is not possible with this approach to duplicate functions. Thus you cannot transfer complete objects including their methods. Simply put, it is a better JSON.stringify/parse approach since Structured Cloning can e.g. handle cyclic dependencies.

AFAIK所有Web浏览器可用的多线程机制,如WebWorker,SharedWorker和ServiceWorker都使用这种基于actor的消息发送方法。

AFAIK all web-browser available multi threading mechanisms such as WebWorker, SharedWorker and ServiceWorker use this actor based message sending approach.

但是,您可以使用可转移对象使用 Worker.postMessage 。这样,您可以将 THREE.Geometry 的顶点数组作为 Transferable 发送。例如。在WebWorker中使用 THREE.BufferGeometry 时。

However, you could use a Transferable object to transfer data from a WebWorker to the main thread using Worker.postMessage. This way, you could send THREE.Geometry's vertex array as a Transferable. E.g. when using a THREE.BufferGeometry within WebWorker.

const myVertexData = bufferGeometry.getAttribute('position').array.buffer;
self.postMessage({myVertices: myVertexData}, [myVertexData]);

由于未复制数据但仅更改了所有权,因此速度非常快。

This is quite fast since the data is not copied but only its ownership is changed.

这篇关于使用webworker和IndexedDB为三个j的加载器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆