|
@@ -131,10 +131,6 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
decodeGeometry: function ( buffer, taskConfig ) {
|
|
|
|
|
|
- var worker;
|
|
|
- var taskID = this.workerNextTaskID ++;
|
|
|
- var taskCost = buffer.byteLength;
|
|
|
-
|
|
|
// TODO: For backward-compatibility, support 'attributeTypes' objects containing
|
|
|
// references (rather than names) to typed array constructors. These must be
|
|
|
// serialized before sending them to the worker.
|
|
@@ -150,6 +146,43 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ var taskKey = JSON.stringify( taskConfig );
|
|
|
+
|
|
|
+ // Check for an existing task using this buffer. A transferred buffer cannot be transferred
|
|
|
+ // again from this thread.
|
|
|
+ if ( DRACOLoader.taskCache.has( buffer ) ) {
|
|
|
+
|
|
|
+ var cachedTask = DRACOLoader.taskCache.get( buffer );
|
|
|
+
|
|
|
+ if ( cachedTask.key === taskKey ) {
|
|
|
+
|
|
|
+ return cachedTask.promise;
|
|
|
+
|
|
|
+ } else if ( buffer.byteLength === 0 ) {
|
|
|
+
|
|
|
+ // Technically, it would be possible to wait for the previous task to complete,
|
|
|
+ // transfer the buffer back, and decode again with the second configuration. That
|
|
|
+ // is complex, and I don't know of any reason to decode a Draco buffer twice in
|
|
|
+ // different ways, so this is left unimplemented.
|
|
|
+ throw new Error(
|
|
|
+
|
|
|
+ 'THREE.DRACOLoader: Unable to re-decode a buffer with different ' +
|
|
|
+ 'settings. Buffer has already been transferred.'
|
|
|
+
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ var worker;
|
|
|
+ var taskID = this.workerNextTaskID ++;
|
|
|
+ var taskCost = buffer.byteLength;
|
|
|
+
|
|
|
// Obtain a worker and assign a task, and construct a geometry instance
|
|
|
// when the task completes.
|
|
|
var geometryPending = this._getWorker( taskID, taskCost )
|
|
@@ -184,6 +217,14 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
} );
|
|
|
|
|
|
+ // Cache the task result.
|
|
|
+ DRACOLoader.taskCache.set( buffer, {
|
|
|
+
|
|
|
+ key: taskKey,
|
|
|
+ promise: geometryPending
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
return geometryPending;
|
|
|
|
|
|
},
|
|
@@ -611,6 +652,8 @@ DRACOLoader.DRACOWorker = function () {
|
|
|
|
|
|
};
|
|
|
|
|
|
+DRACOLoader.taskCache = new WeakMap();
|
|
|
+
|
|
|
/** Deprecated static methods */
|
|
|
|
|
|
/** @deprecated */
|