@onerjs/loaders 8.51.5 → 8.51.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SPLAT/splatFileLoader.js +11 -3
- package/SPLAT/splatFileLoader.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +4 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +3 -331
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +2 -1
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
- package/glTF/2.0/Extensions/index.d.ts +1 -0
- package/glTF/2.0/Extensions/index.js +1 -0
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/Extensions/transmissionHelper.d.ts +157 -0
- package/glTF/2.0/Extensions/transmissionHelper.js +373 -0
- package/glTF/2.0/Extensions/transmissionHelper.js.map +1 -0
- package/glTF/2.0/glTFLoader.d.ts +26 -7
- package/glTF/2.0/glTFLoader.js +107 -58
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/2.0/materialLoadingAdapter.d.ts +8 -10
- package/glTF/2.0/materialLoadingAdapter.js.map +1 -1
- package/glTF/2.0/openpbrMaterialLoadingAdapter.d.ts +3 -3
- package/glTF/2.0/openpbrMaterialLoadingAdapter.js +17 -18
- package/glTF/2.0/openpbrMaterialLoadingAdapter.js.map +1 -1
- package/glTF/2.0/pbrMaterialLoadingAdapter.d.ts +6 -0
- package/glTF/2.0/pbrMaterialLoadingAdapter.js +5 -0
- package/glTF/2.0/pbrMaterialLoadingAdapter.js.map +1 -1
- package/package.json +3 -3
package/glTF/2.0/glTFLoader.js
CHANGED
|
@@ -11,6 +11,7 @@ import { Material } from "@onerjs/core/Materials/material.js";
|
|
|
11
11
|
import { Texture } from "@onerjs/core/Materials/Textures/texture.js";
|
|
12
12
|
import { TransformNode } from "@onerjs/core/Meshes/transformNode.js";
|
|
13
13
|
import { Buffer, VertexBuffer } from "@onerjs/core/Buffers/buffer.js";
|
|
14
|
+
import { VertexBufferForEach, VertexBufferGetTypeByteLength } from "@onerjs/core/Buffers/buffer.pure.js";
|
|
14
15
|
import { Geometry } from "@onerjs/core/Meshes/geometry.js";
|
|
15
16
|
import { AbstractMesh } from "@onerjs/core/Meshes/abstractMesh.js";
|
|
16
17
|
import { Mesh } from "@onerjs/core/Meshes/mesh.js";
|
|
@@ -106,13 +107,19 @@ export function LoadBoundingInfoFromPositionAccessor(accessor) {
|
|
|
106
107
|
*/
|
|
107
108
|
export class GLTFLoader {
|
|
108
109
|
/**
|
|
109
|
-
* Test if the given material is
|
|
110
|
+
* Test if the given material is an instance of any PBR material type known to this loader.
|
|
110
111
|
* @param material The material to test
|
|
111
|
-
* @returns true if the material
|
|
112
|
+
* @returns true if the material matches one of the loaded PBR implementations
|
|
112
113
|
*/
|
|
113
114
|
isMatchingMaterialType(material) {
|
|
114
|
-
if (material
|
|
115
|
-
return
|
|
115
|
+
if (!material) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
const materialImpls = Array.from(this._pbrMaterialImpls.values());
|
|
119
|
+
for (const impl of materialImpls) {
|
|
120
|
+
if (material instanceof impl.materialClass) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
116
123
|
}
|
|
117
124
|
return false;
|
|
118
125
|
}
|
|
@@ -182,8 +189,6 @@ export class GLTFLoader {
|
|
|
182
189
|
constructor(parent) {
|
|
183
190
|
/** @internal */
|
|
184
191
|
this._completePromises = new Array();
|
|
185
|
-
/** AbortController used to cancel in-flight finalizeAsync() calls when dispose() is called. */
|
|
186
|
-
this._finalizeController = null;
|
|
187
192
|
/** @internal */
|
|
188
193
|
this._assetContainer = null;
|
|
189
194
|
/** Storage */
|
|
@@ -195,6 +200,7 @@ export class GLTFLoader {
|
|
|
195
200
|
/** @internal */
|
|
196
201
|
this._skipStartAnimationStep = false;
|
|
197
202
|
this._extensions = new Array();
|
|
203
|
+
/** @internal */
|
|
198
204
|
this._disposed = false;
|
|
199
205
|
this._rootUrl = null;
|
|
200
206
|
this._fileName = null;
|
|
@@ -205,8 +211,13 @@ export class GLTFLoader {
|
|
|
205
211
|
this._postSceneLoadActions = new Array();
|
|
206
212
|
this._materialAdapterCache = new WeakMap();
|
|
207
213
|
this._materialAdapters = new Set();
|
|
208
|
-
/**
|
|
209
|
-
|
|
214
|
+
/**
|
|
215
|
+
* Loaded PBR material implementations, keyed by their identifier (e.g. "pbr", "openpbr").
|
|
216
|
+
* Only populated after the load has started and only for the types actually needed by the asset.
|
|
217
|
+
* Empty when PBR materials are disabled (skipMaterials).
|
|
218
|
+
* @internal
|
|
219
|
+
*/
|
|
220
|
+
this._pbrMaterialImpls = new Map();
|
|
210
221
|
this._parent = parent;
|
|
211
222
|
}
|
|
212
223
|
/**
|
|
@@ -218,10 +229,14 @@ export class GLTFLoader {
|
|
|
218
229
|
_getOrCreateMaterialAdapter(material) {
|
|
219
230
|
let adapter = this._materialAdapterCache.get(material);
|
|
220
231
|
if (!adapter) {
|
|
221
|
-
|
|
222
|
-
|
|
232
|
+
const materialImpls = Array.from(this._pbrMaterialImpls.values());
|
|
233
|
+
for (const impl of materialImpls) {
|
|
234
|
+
if (material instanceof impl.materialClass) {
|
|
235
|
+
adapter = new impl.adapterClass(material);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
223
238
|
}
|
|
224
|
-
|
|
239
|
+
if (!adapter) {
|
|
225
240
|
throw new Error(`Appropriate material adapter class not found`);
|
|
226
241
|
}
|
|
227
242
|
const createdAdapter = adapter;
|
|
@@ -236,8 +251,6 @@ export class GLTFLoader {
|
|
|
236
251
|
return;
|
|
237
252
|
}
|
|
238
253
|
this._disposed = true;
|
|
239
|
-
this._finalizeController?.abort();
|
|
240
|
-
this._finalizeController = null;
|
|
241
254
|
this._completePromises.length = 0;
|
|
242
255
|
this._extensions.forEach((extension) => extension.dispose && extension.dispose());
|
|
243
256
|
this._extensions.length = 0;
|
|
@@ -307,20 +320,35 @@ export class GLTFLoader {
|
|
|
307
320
|
this._fileName = fileName;
|
|
308
321
|
this._allMaterialsDirtyRequired = false;
|
|
309
322
|
await this._loadExtensionsAsync();
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
};
|
|
323
|
+
if (!this.parent.skipMaterials) {
|
|
324
|
+
const needsOpenPBR = this.parent.useOpenPBR || this.isExtensionUsed("KHR_materials_openpbr");
|
|
325
|
+
let needsPBR = false;
|
|
326
|
+
if (!this.parent.useOpenPBR) {
|
|
327
|
+
// PBR is needed when useOpenPBR is turned off.
|
|
328
|
+
needsPBR = true;
|
|
317
329
|
}
|
|
318
|
-
else {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
330
|
+
else if (this._gltf.materials?.length && this._gltf.materials.some((m) => !m.extensions?.["KHR_materials_openpbr"])) {
|
|
331
|
+
// PBR is needed if there is at least one material that does not use the KHR_materials_openpbr extension (i.e. relies on the default PBR implementation).
|
|
332
|
+
needsPBR = true;
|
|
333
|
+
}
|
|
334
|
+
const implPromises = [];
|
|
335
|
+
if (needsOpenPBR && !this._pbrMaterialImpls.has("openpbr")) {
|
|
336
|
+
implPromises.push(Promise.all([import("@onerjs/core/Materials/PBR/openpbrMaterial.js"), import("./openpbrMaterialLoadingAdapter.js")]).then(([{ OpenPBRMaterial: openPBRMaterialClass }, { OpenPBRMaterialLoadingAdapter: openPBRAdapterClass }]) => {
|
|
337
|
+
this._pbrMaterialImpls.set("openpbr", {
|
|
338
|
+
materialClass: openPBRMaterialClass,
|
|
339
|
+
adapterClass: openPBRAdapterClass,
|
|
340
|
+
});
|
|
341
|
+
}));
|
|
323
342
|
}
|
|
343
|
+
if (needsPBR && !this._pbrMaterialImpls.has("pbr")) {
|
|
344
|
+
implPromises.push(Promise.all([import("@onerjs/core/Materials/PBR/pbrMaterial.js"), import("./pbrMaterialLoadingAdapter.js")]).then(([{ PBRMaterial: pbrMaterialClass }, { PBRMaterialLoadingAdapter: pbrAdapterClass }]) => {
|
|
345
|
+
this._pbrMaterialImpls.set("pbr", {
|
|
346
|
+
materialClass: pbrMaterialClass,
|
|
347
|
+
adapterClass: pbrAdapterClass,
|
|
348
|
+
});
|
|
349
|
+
}));
|
|
350
|
+
}
|
|
351
|
+
await Promise.all(implPromises);
|
|
324
352
|
}
|
|
325
353
|
const loadingToReadyCounterName = `${GLTFLoaderState[GLTFLoaderState.LOADING]} => ${GLTFLoaderState[GLTFLoaderState.READY]}`;
|
|
326
354
|
const loadingToCompleteCounterName = `${GLTFLoaderState[GLTFLoaderState.LOADING]} => ${GLTFLoaderState[GLTFLoaderState.COMPLETE]}`;
|
|
@@ -380,25 +408,10 @@ export class GLTFLoader {
|
|
|
380
408
|
}
|
|
381
409
|
}
|
|
382
410
|
// Finalize all material adapters. finalizeAsync() may return a Promise for async
|
|
383
|
-
// work (e.g. GPU texture processing);
|
|
384
|
-
// _completePromises so
|
|
385
|
-
// Fall back to the deprecated finalize() for third-party adapters that have not
|
|
386
|
-
// yet migrated, logging a warning so authors know to update.
|
|
387
|
-
// An AbortController is created here and aborted in dispose() so that adapters
|
|
388
|
-
// can detect mid-flight disposal and clean up intermediate resources early.
|
|
389
|
-
this._finalizeController = new AbortController();
|
|
390
|
-
const finalizeSignal = this._finalizeController.signal;
|
|
411
|
+
// work (e.g. GPU texture processing); any returned Promise is pushed into
|
|
412
|
+
// _completePromises so it is awaited before the COMPLETE state is reached.
|
|
391
413
|
for (const adapter of Array.from(this._materialAdapters)) {
|
|
392
|
-
|
|
393
|
-
const finalizePromise = adapter.finalizeAsync(finalizeSignal);
|
|
394
|
-
if (finalizePromise) {
|
|
395
|
-
this._completePromises.push(finalizePromise);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
else if (adapter.finalize) {
|
|
399
|
-
Logger.Warn("GLTFLoader: IMaterialLoadingAdapter.finalize() is deprecated. Implement finalizeAsync() instead.");
|
|
400
|
-
adapter.finalize();
|
|
401
|
-
}
|
|
414
|
+
this._completePromises.push(adapter.finalizeAsync(this));
|
|
402
415
|
}
|
|
403
416
|
this._extensionsOnReady();
|
|
404
417
|
this._parent._setState(GLTFLoaderState.READY);
|
|
@@ -907,7 +920,7 @@ export class GLTFLoader {
|
|
|
907
920
|
if (primitive.material == undefined) {
|
|
908
921
|
let babylonMaterial = this._defaultBabylonMaterialData[babylonDrawMode];
|
|
909
922
|
if (!babylonMaterial) {
|
|
910
|
-
babylonMaterial = this._createDefaultMaterial("__GLTFLoader._default", babylonDrawMode);
|
|
923
|
+
babylonMaterial = this._createDefaultMaterial("__GLTFLoader._default", babylonDrawMode, this._getDefaultImpl());
|
|
911
924
|
this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
|
|
912
925
|
this._defaultBabylonMaterialData[babylonDrawMode] = babylonMaterial;
|
|
913
926
|
}
|
|
@@ -1652,7 +1665,7 @@ export class GLTFLoader {
|
|
|
1652
1665
|
return accessor._data;
|
|
1653
1666
|
}
|
|
1654
1667
|
const numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
|
|
1655
|
-
const byteStride = numComponents *
|
|
1668
|
+
const byteStride = numComponents * VertexBufferGetTypeByteLength(accessor.componentType);
|
|
1656
1669
|
const length = numComponents * accessor.count;
|
|
1657
1670
|
if (accessor.bufferView == undefined) {
|
|
1658
1671
|
accessor._data = Promise.resolve(new constructor(length));
|
|
@@ -1665,7 +1678,7 @@ export class GLTFLoader {
|
|
|
1665
1678
|
}
|
|
1666
1679
|
else {
|
|
1667
1680
|
const typedArray = new constructor(length);
|
|
1668
|
-
|
|
1681
|
+
VertexBufferForEach(data, accessor.byteOffset || 0, bufferView.byteStride || byteStride, numComponents, accessor.componentType, typedArray.length, accessor.normalized || false, (value, index) => {
|
|
1669
1682
|
typedArray[index] = value;
|
|
1670
1683
|
});
|
|
1671
1684
|
return typedArray;
|
|
@@ -1691,7 +1704,7 @@ export class GLTFLoader {
|
|
|
1691
1704
|
else {
|
|
1692
1705
|
const sparseData = GLTFLoader._GetTypedArray(`${context}/sparse/values`, accessor.componentType, valuesData, sparse.values.byteOffset, sparseLength);
|
|
1693
1706
|
values = new constructor(sparseLength);
|
|
1694
|
-
|
|
1707
|
+
VertexBufferForEach(sparseData, 0, byteStride, numComponents, accessor.componentType, values.length, accessor.normalized || false, (value, index) => {
|
|
1695
1708
|
values[index] = value;
|
|
1696
1709
|
});
|
|
1697
1710
|
}
|
|
@@ -1850,16 +1863,52 @@ export class GLTFLoader {
|
|
|
1850
1863
|
await babylonData.promise;
|
|
1851
1864
|
return babylonData.babylonMaterial;
|
|
1852
1865
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1866
|
+
/**
|
|
1867
|
+
* Selects the appropriate PBR material implementation for a given glTF material.
|
|
1868
|
+
* Uses OpenPBR when the material carries a "KHR_materials_openpbr" extension or when
|
|
1869
|
+
* the loader-level `useOpenPBR` flag is set; falls back to standard PBR otherwise.
|
|
1870
|
+
* @param material The glTF material
|
|
1871
|
+
* @returns The matching loaded implementation
|
|
1872
|
+
*/
|
|
1873
|
+
_selectImplForGltfMaterial(material) {
|
|
1874
|
+
if (this.parent.useOpenPBR || material.extensions?.["KHR_materials_openpbr"]) {
|
|
1875
|
+
const impl = this._pbrMaterialImpls.get("openpbr");
|
|
1876
|
+
if (impl) {
|
|
1877
|
+
return impl;
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
const impl = this._pbrMaterialImpls.get("pbr");
|
|
1881
|
+
if (impl) {
|
|
1882
|
+
return impl;
|
|
1856
1883
|
}
|
|
1884
|
+
throw new Error("No PBR material implementation loaded");
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Returns the default PBR material implementation used when there is no per-material
|
|
1888
|
+
* selection context (e.g. when creating the built-in default material for primitives
|
|
1889
|
+
* that have no glTF material assigned). Prefers OpenPBR when `useOpenPBR` is set.
|
|
1890
|
+
* @returns The default loaded implementation
|
|
1891
|
+
*/
|
|
1892
|
+
_getDefaultImpl() {
|
|
1893
|
+
if (this.parent.useOpenPBR) {
|
|
1894
|
+
const impl = this._pbrMaterialImpls.get("openpbr");
|
|
1895
|
+
if (impl) {
|
|
1896
|
+
return impl;
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
const impl = this._pbrMaterialImpls.get("pbr") ?? this._pbrMaterialImpls.values().next().value;
|
|
1900
|
+
if (impl) {
|
|
1901
|
+
return impl;
|
|
1902
|
+
}
|
|
1903
|
+
throw new Error("No PBR material implementation loaded");
|
|
1904
|
+
}
|
|
1905
|
+
_createDefaultMaterial(name, babylonDrawMode, impl) {
|
|
1857
1906
|
this._babylonScene._blockEntityCollection = !!this._assetContainer;
|
|
1858
|
-
const babylonMaterial = new
|
|
1907
|
+
const babylonMaterial = new impl.materialClass(name, this._babylonScene);
|
|
1859
1908
|
babylonMaterial._parentContainer = this._assetContainer;
|
|
1860
1909
|
this._babylonScene._blockEntityCollection = false;
|
|
1861
1910
|
babylonMaterial.fillMode = babylonDrawMode;
|
|
1862
|
-
babylonMaterial.transparencyMode =
|
|
1911
|
+
babylonMaterial.transparencyMode = impl.materialClass.MATERIAL_OPAQUE;
|
|
1863
1912
|
// Create the material adapter and set some default properties.
|
|
1864
1913
|
// We don't need to wait for the promise to resolve here.
|
|
1865
1914
|
const adapter = this._getOrCreateMaterialAdapter(babylonMaterial);
|
|
@@ -1882,7 +1931,7 @@ export class GLTFLoader {
|
|
|
1882
1931
|
return extensionMaterial;
|
|
1883
1932
|
}
|
|
1884
1933
|
const name = material.name || `material${material.index}`;
|
|
1885
|
-
const babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode);
|
|
1934
|
+
const babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode, this._selectImplForGltfMaterial(material));
|
|
1886
1935
|
return babylonMaterial;
|
|
1887
1936
|
}
|
|
1888
1937
|
/**
|
|
@@ -1972,7 +2021,7 @@ export class GLTFLoader {
|
|
|
1972
2021
|
* @param babylonMaterial The Babylon material
|
|
1973
2022
|
*/
|
|
1974
2023
|
loadMaterialAlphaProperties(context, material, babylonMaterial) {
|
|
1975
|
-
if (
|
|
2024
|
+
if (this._pbrMaterialImpls.size === 0) {
|
|
1976
2025
|
throw new Error(`${context}: Material type not supported`);
|
|
1977
2026
|
}
|
|
1978
2027
|
const adapter = this._getOrCreateMaterialAdapter(babylonMaterial);
|
|
@@ -1980,12 +2029,12 @@ export class GLTFLoader {
|
|
|
1980
2029
|
const alphaMode = material.alphaMode || "OPAQUE" /* MaterialAlphaMode.OPAQUE */;
|
|
1981
2030
|
switch (alphaMode) {
|
|
1982
2031
|
case "OPAQUE" /* MaterialAlphaMode.OPAQUE */: {
|
|
1983
|
-
babylonMaterial.transparencyMode =
|
|
2032
|
+
babylonMaterial.transparencyMode = Material.MATERIAL_OPAQUE;
|
|
1984
2033
|
babylonMaterial.alpha = 1.0; // Force alpha to 1.0 for opaque mode.
|
|
1985
2034
|
break;
|
|
1986
2035
|
}
|
|
1987
2036
|
case "MASK" /* MaterialAlphaMode.MASK */: {
|
|
1988
|
-
babylonMaterial.transparencyMode =
|
|
2037
|
+
babylonMaterial.transparencyMode = Material.MATERIAL_ALPHATEST;
|
|
1989
2038
|
adapter.alphaCutOff = material.alphaCutoff == undefined ? 0.5 : material.alphaCutoff;
|
|
1990
2039
|
if (baseColorTexture) {
|
|
1991
2040
|
baseColorTexture.hasAlpha = true;
|
|
@@ -1993,7 +2042,7 @@ export class GLTFLoader {
|
|
|
1993
2042
|
break;
|
|
1994
2043
|
}
|
|
1995
2044
|
case "BLEND" /* MaterialAlphaMode.BLEND */: {
|
|
1996
|
-
babylonMaterial.transparencyMode =
|
|
2045
|
+
babylonMaterial.transparencyMode = Material.MATERIAL_ALPHABLEND;
|
|
1997
2046
|
if (baseColorTexture) {
|
|
1998
2047
|
baseColorTexture.hasAlpha = true;
|
|
1999
2048
|
adapter.useAlphaFromBaseColorTexture = true;
|
|
@@ -2249,7 +2298,7 @@ export class GLTFLoader {
|
|
|
2249
2298
|
const buffer = bufferView.buffer;
|
|
2250
2299
|
byteOffset = bufferView.byteOffset + (byteOffset || 0);
|
|
2251
2300
|
const constructor = GLTFLoader._GetTypedArrayConstructor(`${context}/componentType`, componentType);
|
|
2252
|
-
const componentTypeLength =
|
|
2301
|
+
const componentTypeLength = VertexBufferGetTypeByteLength(componentType);
|
|
2253
2302
|
if (byteOffset % componentTypeLength !== 0) {
|
|
2254
2303
|
// HACK: Copy the buffer if byte offset is not a multiple of component type byte length.
|
|
2255
2304
|
Logger.Warn(`${context}: Copying buffer as byte offset (${byteOffset}) is not a multiple of component type byte length (${componentTypeLength})`);
|