|
| 1 | +diff --git a/loaders/DRACOLoader.cjs b/loaders/DRACOLoader.cjs |
| 2 | +index d957dd8319f97b82f026bc4d8a2cbcf36c9bbb5e..a5561635127e0f0141f68356724e55f03d314de0 100644 |
| 3 | +--- a/loaders/DRACOLoader.cjs |
| 4 | ++++ b/loaders/DRACOLoader.cjs |
| 5 | +@@ -1,5 +1,6 @@ |
| 6 | + "use strict"; |
| 7 | + Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); |
| 8 | ++const { createDecoderModule } = require("draco3d"); |
| 9 | + const THREE = require("three"); |
| 10 | + const _taskCache = /* @__PURE__ */ new WeakMap(); |
| 11 | + class DRACOLoader extends THREE.Loader { |
| 12 | +@@ -8,7 +9,7 @@ class DRACOLoader extends THREE.Loader { |
| 13 | + this.decoderPath = ""; |
| 14 | + this.decoderConfig = {}; |
| 15 | + this.decoderBinary = null; |
| 16 | +- this.decoderPending = null; |
| 17 | ++ this.decoderPending = new DRACODecoder(); |
| 18 | + this.workerLimit = 4; |
| 19 | + this.workerPool = []; |
| 20 | + this.workerNextTaskID = 1; |
| 21 | +@@ -88,13 +89,13 @@ class DRACOLoader extends THREE.Loader { |
| 22 | + let worker; |
| 23 | + const taskID = this.workerNextTaskID++; |
| 24 | + const taskCost = buffer.byteLength; |
| 25 | +- const geometryPending = this._getWorker(taskID, taskCost).then((_worker) => { |
| 26 | +- worker = _worker; |
| 27 | +- return new Promise((resolve, reject) => { |
| 28 | +- worker._callbacks[taskID] = { resolve, reject }; |
| 29 | +- worker.postMessage({ type: "decode", id: taskID, taskConfig, buffer }, [buffer]); |
| 30 | +- }); |
| 31 | +- }).then((message) => this._createGeometry(message.geometry)); |
| 32 | ++ const geometryPending = this.decoderPending.onmessage({ |
| 33 | ++ data: { |
| 34 | ++ type: 'decode', |
| 35 | ++ buffer, |
| 36 | ++ taskConfig, |
| 37 | ++ }, |
| 38 | ++ }).then((geometry) => this._createGeometry(geometry)); |
| 39 | + geometryPending.catch(() => true).then(() => { |
| 40 | + if (worker && taskID) { |
| 41 | + this._releaseTask(worker, taskID); |
| 42 | +@@ -130,7 +131,6 @@ class DRACOLoader extends THREE.Loader { |
| 43 | + }); |
| 44 | + } |
| 45 | + preload() { |
| 46 | +- this._initDecoder(); |
| 47 | + return this; |
| 48 | + } |
| 49 | + _initDecoder() { |
| 50 | +@@ -213,10 +213,12 @@ class DRACOLoader extends THREE.Loader { |
| 51 | + return this; |
| 52 | + } |
| 53 | + } |
| 54 | +-function DRACOWorker() { |
| 55 | +- let decoderConfig; |
| 56 | +- let decoderPending; |
| 57 | +- onmessage = function(e) { |
| 58 | ++class DRACODecoder { |
| 59 | ++ decoderModulePending; |
| 60 | ++ constructor() { |
| 61 | ++ this.decoderModulePending = createDecoderModule(); |
| 62 | ++ } |
| 63 | ++ onmessage(e) { |
| 64 | + const message = e.data; |
| 65 | + switch (message.type) { |
| 66 | + case "init": |
| 67 | +@@ -231,20 +233,12 @@ function DRACOWorker() { |
| 68 | + case "decode": |
| 69 | + const buffer = message.buffer; |
| 70 | + const taskConfig = message.taskConfig; |
| 71 | +- decoderPending.then((module2) => { |
| 72 | +- const draco = module2.draco; |
| 73 | ++ return this.decoderModulePending.then((draco) => { |
| 74 | + const decoder = new draco.Decoder(); |
| 75 | + const decoderBuffer = new draco.DecoderBuffer(); |
| 76 | + decoderBuffer.Init(new Int8Array(buffer), buffer.byteLength); |
| 77 | + try { |
| 78 | +- const geometry = decodeGeometry(draco, decoder, decoderBuffer, taskConfig); |
| 79 | +- const buffers = geometry.attributes.map((attr) => attr.array.buffer); |
| 80 | +- if (geometry.index) |
| 81 | +- buffers.push(geometry.index.array.buffer); |
| 82 | +- self.postMessage({ type: "decode", id: message.id, geometry }, buffers); |
| 83 | +- } catch (error) { |
| 84 | +- console.error(error); |
| 85 | +- self.postMessage({ type: "error", id: message.id, error: error.message }); |
| 86 | ++ return this.decodeGeometry(draco, decoder, decoderBuffer, taskConfig); |
| 87 | + } finally { |
| 88 | + draco.destroy(decoderBuffer); |
| 89 | + draco.destroy(decoder); |
| 90 | +@@ -253,7 +247,7 @@ function DRACOWorker() { |
| 91 | + break; |
| 92 | + } |
| 93 | + }; |
| 94 | +- function decodeGeometry(draco, decoder, decoderBuffer, taskConfig) { |
| 95 | ++ decodeGeometry(draco, decoder, decoderBuffer, taskConfig) { |
| 96 | + const attributeIDs = taskConfig.attributeIDs; |
| 97 | + const attributeTypes = taskConfig.attributeTypes; |
| 98 | + let dracoGeometry; |
| 99 | +@@ -273,7 +267,7 @@ function DRACOWorker() { |
| 100 | + } |
| 101 | + const geometry = { index: null, attributes: [] }; |
| 102 | + for (const attributeName in attributeIDs) { |
| 103 | +- const attributeType = self[attributeTypes[attributeName]]; |
| 104 | ++ const attributeType = global[attributeTypes[attributeName]]; |
| 105 | + let attribute; |
| 106 | + let attributeID; |
| 107 | + if (taskConfig.useUniqueIDs) { |
| 108 | +@@ -285,15 +279,15 @@ function DRACOWorker() { |
| 109 | + continue; |
| 110 | + attribute = decoder.GetAttribute(dracoGeometry, attributeID); |
| 111 | + } |
| 112 | +- geometry.attributes.push(decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute)); |
| 113 | ++ geometry.attributes.push(this.decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute)); |
| 114 | + } |
| 115 | + if (geometryType === draco.TRIANGULAR_MESH) { |
| 116 | +- geometry.index = decodeIndex(draco, decoder, dracoGeometry); |
| 117 | ++ geometry.index = this.decodeIndex(draco, decoder, dracoGeometry); |
| 118 | + } |
| 119 | + draco.destroy(dracoGeometry); |
| 120 | + return geometry; |
| 121 | + } |
| 122 | +- function decodeIndex(draco, decoder, dracoGeometry) { |
| 123 | ++ decodeIndex(draco, decoder, dracoGeometry) { |
| 124 | + const numFaces = dracoGeometry.num_faces(); |
| 125 | + const numIndices = numFaces * 3; |
| 126 | + const byteLength = numIndices * 4; |
| 127 | +@@ -303,12 +297,12 @@ function DRACOWorker() { |
| 128 | + draco._free(ptr); |
| 129 | + return { array: index, itemSize: 1 }; |
| 130 | + } |
| 131 | +- function decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) { |
| 132 | ++ decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) { |
| 133 | + const numComponents = attribute.num_components(); |
| 134 | + const numPoints = dracoGeometry.num_points(); |
| 135 | + const numValues = numPoints * numComponents; |
| 136 | + const byteLength = numValues * attributeType.BYTES_PER_ELEMENT; |
| 137 | +- const dataType = getDracoDataType(draco, attributeType); |
| 138 | ++ const dataType = this.getDracoDataType(draco, attributeType); |
| 139 | + const ptr = draco._malloc(byteLength); |
| 140 | + decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, dataType, byteLength, ptr); |
| 141 | + const array = new attributeType(draco.HEAPF32.buffer, ptr, numValues).slice(); |
| 142 | +@@ -319,7 +313,7 @@ function DRACOWorker() { |
| 143 | + itemSize: numComponents |
| 144 | + }; |
| 145 | + } |
| 146 | +- function getDracoDataType(draco, attributeType) { |
| 147 | ++ getDracoDataType(draco, attributeType) { |
| 148 | + switch (attributeType) { |
| 149 | + case Float32Array: |
| 150 | + return draco.DT_FLOAT32; |
| 151 | +diff --git a/loaders/DRACOLoader.js b/loaders/DRACOLoader.js |
| 152 | +index 43ca01558bbf0fffbfcebe85c2eabd962537a94e..b3ea813413c2fde835bd9d630b12113c35dda72a 100644 |
| 153 | +--- a/loaders/DRACOLoader.js |
| 154 | ++++ b/loaders/DRACOLoader.js |
| 155 | +@@ -1,3 +1,4 @@ |
| 156 | ++import { createDecoderModule } from "draco3d"; |
| 157 | + import { Loader, FileLoader, BufferGeometry, BufferAttribute } from "three"; |
| 158 | + const _taskCache = /* @__PURE__ */ new WeakMap(); |
| 159 | + class DRACOLoader extends Loader { |
| 160 | +@@ -6,7 +7,7 @@ class DRACOLoader extends Loader { |
| 161 | + this.decoderPath = ""; |
| 162 | + this.decoderConfig = {}; |
| 163 | + this.decoderBinary = null; |
| 164 | +- this.decoderPending = null; |
| 165 | ++ this.decoderPending = new DRACODecoder(); |
| 166 | + this.workerLimit = 4; |
| 167 | + this.workerPool = []; |
| 168 | + this.workerNextTaskID = 1; |
| 169 | +@@ -86,13 +87,13 @@ class DRACOLoader extends Loader { |
| 170 | + let worker; |
| 171 | + const taskID = this.workerNextTaskID++; |
| 172 | + const taskCost = buffer.byteLength; |
| 173 | +- const geometryPending = this._getWorker(taskID, taskCost).then((_worker) => { |
| 174 | +- worker = _worker; |
| 175 | +- return new Promise((resolve, reject) => { |
| 176 | +- worker._callbacks[taskID] = { resolve, reject }; |
| 177 | +- worker.postMessage({ type: "decode", id: taskID, taskConfig, buffer }, [buffer]); |
| 178 | +- }); |
| 179 | +- }).then((message) => this._createGeometry(message.geometry)); |
| 180 | ++ const geometryPending = this.decoderPending.onmessage({ |
| 181 | ++ data: { |
| 182 | ++ type: 'decode', |
| 183 | ++ buffer, |
| 184 | ++ taskConfig, |
| 185 | ++ }, |
| 186 | ++ }).then((geometry) => this._createGeometry(geometry)); |
| 187 | + geometryPending.catch(() => true).then(() => { |
| 188 | + if (worker && taskID) { |
| 189 | + this._releaseTask(worker, taskID); |
| 190 | +@@ -128,7 +129,6 @@ class DRACOLoader extends Loader { |
| 191 | + }); |
| 192 | + } |
| 193 | + preload() { |
| 194 | +- this._initDecoder(); |
| 195 | + return this; |
| 196 | + } |
| 197 | + _initDecoder() { |
| 198 | +@@ -211,10 +211,12 @@ class DRACOLoader extends Loader { |
| 199 | + return this; |
| 200 | + } |
| 201 | + } |
| 202 | +-function DRACOWorker() { |
| 203 | +- let decoderConfig; |
| 204 | +- let decoderPending; |
| 205 | +- onmessage = function(e) { |
| 206 | ++class DRACODecoder { |
| 207 | ++ decoderModulePending; |
| 208 | ++ constructor() { |
| 209 | ++ this.decoderModulePending = createDecoderModule(); |
| 210 | ++ } |
| 211 | ++ onmessage(e) { |
| 212 | + const message = e.data; |
| 213 | + switch (message.type) { |
| 214 | + case "init": |
| 215 | +@@ -229,20 +231,12 @@ function DRACOWorker() { |
| 216 | + case "decode": |
| 217 | + const buffer = message.buffer; |
| 218 | + const taskConfig = message.taskConfig; |
| 219 | +- decoderPending.then((module) => { |
| 220 | +- const draco = module.draco; |
| 221 | ++ return this.decoderModulePending.then((draco) => { |
| 222 | + const decoder = new draco.Decoder(); |
| 223 | + const decoderBuffer = new draco.DecoderBuffer(); |
| 224 | + decoderBuffer.Init(new Int8Array(buffer), buffer.byteLength); |
| 225 | + try { |
| 226 | +- const geometry = decodeGeometry(draco, decoder, decoderBuffer, taskConfig); |
| 227 | +- const buffers = geometry.attributes.map((attr) => attr.array.buffer); |
| 228 | +- if (geometry.index) |
| 229 | +- buffers.push(geometry.index.array.buffer); |
| 230 | +- self.postMessage({ type: "decode", id: message.id, geometry }, buffers); |
| 231 | +- } catch (error) { |
| 232 | +- console.error(error); |
| 233 | +- self.postMessage({ type: "error", id: message.id, error: error.message }); |
| 234 | ++ return this.decodeGeometry(draco, decoder, decoderBuffer, taskConfig); |
| 235 | + } finally { |
| 236 | + draco.destroy(decoderBuffer); |
| 237 | + draco.destroy(decoder); |
| 238 | +@@ -251,7 +245,7 @@ function DRACOWorker() { |
| 239 | + break; |
| 240 | + } |
| 241 | + }; |
| 242 | +- function decodeGeometry(draco, decoder, decoderBuffer, taskConfig) { |
| 243 | ++ decodeGeometry(draco, decoder, decoderBuffer, taskConfig) { |
| 244 | + const attributeIDs = taskConfig.attributeIDs; |
| 245 | + const attributeTypes = taskConfig.attributeTypes; |
| 246 | + let dracoGeometry; |
| 247 | +@@ -271,7 +265,7 @@ function DRACOWorker() { |
| 248 | + } |
| 249 | + const geometry = { index: null, attributes: [] }; |
| 250 | + for (const attributeName in attributeIDs) { |
| 251 | +- const attributeType = self[attributeTypes[attributeName]]; |
| 252 | ++ const attributeType = global[attributeTypes[attributeName]]; |
| 253 | + let attribute; |
| 254 | + let attributeID; |
| 255 | + if (taskConfig.useUniqueIDs) { |
| 256 | +@@ -283,15 +277,15 @@ function DRACOWorker() { |
| 257 | + continue; |
| 258 | + attribute = decoder.GetAttribute(dracoGeometry, attributeID); |
| 259 | + } |
| 260 | +- geometry.attributes.push(decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute)); |
| 261 | ++ geometry.attributes.push(this.decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute)); |
| 262 | + } |
| 263 | + if (geometryType === draco.TRIANGULAR_MESH) { |
| 264 | +- geometry.index = decodeIndex(draco, decoder, dracoGeometry); |
| 265 | ++ geometry.index = this.decodeIndex(draco, decoder, dracoGeometry); |
| 266 | + } |
| 267 | + draco.destroy(dracoGeometry); |
| 268 | + return geometry; |
| 269 | + } |
| 270 | +- function decodeIndex(draco, decoder, dracoGeometry) { |
| 271 | ++ decodeIndex(draco, decoder, dracoGeometry) { |
| 272 | + const numFaces = dracoGeometry.num_faces(); |
| 273 | + const numIndices = numFaces * 3; |
| 274 | + const byteLength = numIndices * 4; |
| 275 | +@@ -301,12 +295,12 @@ function DRACOWorker() { |
| 276 | + draco._free(ptr); |
| 277 | + return { array: index, itemSize: 1 }; |
| 278 | + } |
| 279 | +- function decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) { |
| 280 | ++ decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) { |
| 281 | + const numComponents = attribute.num_components(); |
| 282 | + const numPoints = dracoGeometry.num_points(); |
| 283 | + const numValues = numPoints * numComponents; |
| 284 | + const byteLength = numValues * attributeType.BYTES_PER_ELEMENT; |
| 285 | +- const dataType = getDracoDataType(draco, attributeType); |
| 286 | ++ const dataType = this.getDracoDataType(draco, attributeType); |
| 287 | + const ptr = draco._malloc(byteLength); |
| 288 | + decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, dataType, byteLength, ptr); |
| 289 | + const array = new attributeType(draco.HEAPF32.buffer, ptr, numValues).slice(); |
| 290 | +@@ -317,7 +311,7 @@ function DRACOWorker() { |
| 291 | + itemSize: numComponents |
| 292 | + }; |
| 293 | + } |
| 294 | +- function getDracoDataType(draco, attributeType) { |
| 295 | ++ getDracoDataType(draco, attributeType) { |
| 296 | + switch (attributeType) { |
| 297 | + case Float32Array: |
| 298 | + return draco.DT_FLOAT32; |
| 299 | +diff --git a/loaders/GLTFLoader.cjs b/loaders/GLTFLoader.cjs |
| 300 | +index 15aba5027f97e93b048e9738b45ea8b7e2193b0d..30f8e250a35f65eb5e4789d5a27f8f40beeee56d 100644 |
| 301 | +--- a/loaders/GLTFLoader.cjs |
| 302 | ++++ b/loaders/GLTFLoader.cjs |
| 303 | +@@ -1,5 +1,7 @@ |
| 304 | + "use strict"; |
| 305 | + Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); |
| 306 | ++const { readFile } = require("node:fs/promises"); |
| 307 | ++const { join } = require("node:path"); |
| 308 | + const THREE = require("three"); |
| 309 | + const BufferGeometryUtils = require("../utils/BufferGeometryUtils.cjs"); |
| 310 | + const constants = require("../_polyfill/constants.cjs"); |
| 311 | +@@ -1632,6 +1634,7 @@ class GLTFParser { |
| 312 | + if (bufferDef.uri === void 0 && bufferIndex === 0) { |
| 313 | + return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body); |
| 314 | + } |
| 315 | ++ return readFile(join(this.options.path, bufferDef.uri)); |
| 316 | + const options = this.options; |
| 317 | + return new Promise(function(resolve, reject) { |
| 318 | + loader.load(THREE.LoaderUtils.resolveURL(bufferDef.uri, options.path), resolve, void 0, function() { |
| 319 | +@@ -1794,6 +1797,7 @@ class GLTFParser { |
| 320 | + return promise; |
| 321 | + } |
| 322 | + loadImageSource(sourceIndex, loader) { |
| 323 | ++ return Promise.resolve(null); |
| 324 | + const parser = this; |
| 325 | + const json = this.json; |
| 326 | + const options = this.options; |
| 327 | +diff --git a/loaders/GLTFLoader.js b/loaders/GLTFLoader.js |
| 328 | +index 851226bb4c491b990459cae65009113035f200cc..f1dd2991c9d88adf6ae1b6bfff5f85350d6b891e 100644 |
| 329 | +--- a/loaders/GLTFLoader.js |
| 330 | ++++ b/loaders/GLTFLoader.js |
| 331 | +@@ -1,3 +1,5 @@ |
| 332 | ++import { readFile } from "node:fs/promises"; |
| 333 | ++import { join } from "node:path"; |
| 334 | + import { Loader, LoaderUtils, FileLoader, Color, SpotLight, PointLight, DirectionalLight, MeshBasicMaterial, MeshPhysicalMaterial, Vector2, Matrix4, Vector3, Quaternion, InstancedMesh, InstancedBufferAttribute, Object3D, TextureLoader, ImageBitmapLoader, BufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, LinearFilter, LinearMipmapLinearFilter, RepeatWrapping, PointsMaterial, Material, LineBasicMaterial, MeshStandardMaterial, DoubleSide, PropertyBinding, BufferGeometry, SkinnedMesh, Mesh, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, Line, LineLoop, Points, Group, PerspectiveCamera, MathUtils, OrthographicCamera, Skeleton, AnimationClip, Bone, InterpolateLinear, NearestFilter, NearestMipmapNearestFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, ClampToEdgeWrapping, MirroredRepeatWrapping, InterpolateDiscrete, FrontSide, Texture, VectorKeyframeTrack, NumberKeyframeTrack, QuaternionKeyframeTrack, Box3, Sphere, Interpolant } from "three"; |
| 335 | + import { toTrianglesDrawMode } from "../utils/BufferGeometryUtils.js"; |
| 336 | + import { version } from "../_polyfill/constants.js"; |
| 337 | +@@ -1630,6 +1632,7 @@ class GLTFParser { |
| 338 | + if (bufferDef.uri === void 0 && bufferIndex === 0) { |
| 339 | + return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body); |
| 340 | + } |
| 341 | ++ return readFile(join(this.options.path, bufferDef.uri)); |
| 342 | + const options = this.options; |
| 343 | + return new Promise(function(resolve, reject) { |
| 344 | + loader.load(LoaderUtils.resolveURL(bufferDef.uri, options.path), resolve, void 0, function() { |
| 345 | +@@ -1792,6 +1795,7 @@ class GLTFParser { |
| 346 | + return promise; |
| 347 | + } |
| 348 | + loadImageSource(sourceIndex, loader) { |
| 349 | ++ return Promise.resolve(null); |
| 350 | + const parser = this; |
| 351 | + const json = this.json; |
| 352 | + const options = this.options; |
0 commit comments