three-stdlib 2.16.2 → 2.17.0
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/index.cjs.js +1 -1
- package/loaders/GLTFLoader.cjs.js +1 -1
- package/loaders/GLTFLoader.js +240 -91
- package/package.json +1 -1
package/loaders/GLTFLoader.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Loader, LoaderUtils, FileLoader, Color, SpotLight, PointLight, DirectionalLight, MeshBasicMaterial, MeshPhysicalMaterial, Vector2,
|
1
|
+
import { Loader, LoaderUtils, FileLoader, Color, SpotLight, PointLight, DirectionalLight, MeshBasicMaterial, sRGBEncoding, MeshPhysicalMaterial, Vector2, TangentSpaceNormalMap, Quaternion, TextureLoader, ImageBitmapLoader, InterleavedBuffer, InterleavedBufferAttribute, BufferAttribute, LinearFilter, LinearMipmapLinearFilter, RepeatWrapping, PointsMaterial, Material, LineBasicMaterial, MeshStandardMaterial, DoubleSide, PropertyBinding, BufferGeometry, SkinnedMesh, Mesh, LineSegments, Line, LineLoop, Points, Group, PerspectiveCamera, MathUtils, OrthographicCamera, InterpolateLinear, AnimationClip, Bone, Object3D, Matrix4, Skeleton, TriangleFanDrawMode, NearestFilter, NearestMipmapNearestFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, ClampToEdgeWrapping, MirroredRepeatWrapping, InterpolateDiscrete, FrontSide, Texture, TriangleStripDrawMode, VectorKeyframeTrack, QuaternionKeyframeTrack, NumberKeyframeTrack, Box3, Vector3, Sphere, Interpolant } from 'three';
|
2
2
|
|
3
3
|
class GLTFLoader extends Loader {
|
4
4
|
constructor(manager) {
|
@@ -28,9 +28,15 @@ class GLTFLoader extends Loader {
|
|
28
28
|
this.register(function (parser) {
|
29
29
|
return new GLTFMaterialsIorExtension(parser);
|
30
30
|
});
|
31
|
+
this.register(function (parser) {
|
32
|
+
return new GLTFMaterialsEmissiveStrengthExtension(parser);
|
33
|
+
});
|
31
34
|
this.register(function (parser) {
|
32
35
|
return new GLTFMaterialsSpecularExtension(parser);
|
33
36
|
});
|
37
|
+
this.register(function (parser) {
|
38
|
+
return new GLTFMaterialsIridescenceExtension(parser);
|
39
|
+
});
|
34
40
|
this.register(function (parser) {
|
35
41
|
return new GLTFLightsExtension(parser);
|
36
42
|
});
|
@@ -255,11 +261,13 @@ const EXTENSIONS = {
|
|
255
261
|
KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
|
256
262
|
KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
|
257
263
|
KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
|
264
|
+
KHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',
|
258
265
|
KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
|
259
266
|
KHR_MATERIALS_VOLUME: 'KHR_materials_volume',
|
260
267
|
KHR_TEXTURE_BASISU: 'KHR_texture_basisu',
|
261
268
|
KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
|
262
269
|
KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
|
270
|
+
KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
|
263
271
|
EXT_TEXTURE_WEBP: 'EXT_texture_webp',
|
264
272
|
EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'
|
265
273
|
};
|
@@ -391,13 +399,44 @@ class GLTFMaterialsUnlitExtension {
|
|
391
399
|
}
|
392
400
|
|
393
401
|
if (metallicRoughness.baseColorTexture !== undefined) {
|
394
|
-
pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture));
|
402
|
+
pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding));
|
395
403
|
}
|
396
404
|
}
|
397
405
|
|
398
406
|
return Promise.all(pending);
|
399
407
|
}
|
400
408
|
|
409
|
+
}
|
410
|
+
/**
|
411
|
+
* Materials Emissive Strength Extension
|
412
|
+
*
|
413
|
+
* Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
|
414
|
+
*/
|
415
|
+
|
416
|
+
|
417
|
+
class GLTFMaterialsEmissiveStrengthExtension {
|
418
|
+
constructor(parser) {
|
419
|
+
this.parser = parser;
|
420
|
+
this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;
|
421
|
+
}
|
422
|
+
|
423
|
+
extendMaterialParams(materialIndex, materialParams) {
|
424
|
+
const parser = this.parser;
|
425
|
+
const materialDef = parser.json.materials[materialIndex];
|
426
|
+
|
427
|
+
if (!materialDef.extensions || !materialDef.extensions[this.name]) {
|
428
|
+
return Promise.resolve();
|
429
|
+
}
|
430
|
+
|
431
|
+
const emissiveStrength = materialDef.extensions[this.name].emissiveStrength;
|
432
|
+
|
433
|
+
if (emissiveStrength !== undefined) {
|
434
|
+
materialParams.emissiveIntensity = emissiveStrength;
|
435
|
+
}
|
436
|
+
|
437
|
+
return Promise.resolve();
|
438
|
+
}
|
439
|
+
|
401
440
|
}
|
402
441
|
/**
|
403
442
|
* Clearcoat Materials Extension
|
@@ -458,6 +497,69 @@ class GLTFMaterialsClearcoatExtension {
|
|
458
497
|
return Promise.all(pending);
|
459
498
|
}
|
460
499
|
|
500
|
+
}
|
501
|
+
/**
|
502
|
+
* Iridescence Materials Extension
|
503
|
+
*
|
504
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
|
505
|
+
*/
|
506
|
+
|
507
|
+
|
508
|
+
class GLTFMaterialsIridescenceExtension {
|
509
|
+
constructor(parser) {
|
510
|
+
this.parser = parser;
|
511
|
+
this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;
|
512
|
+
}
|
513
|
+
|
514
|
+
getMaterialType(materialIndex) {
|
515
|
+
const parser = this.parser;
|
516
|
+
const materialDef = parser.json.materials[materialIndex];
|
517
|
+
if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
|
518
|
+
return MeshPhysicalMaterial;
|
519
|
+
}
|
520
|
+
|
521
|
+
extendMaterialParams(materialIndex, materialParams) {
|
522
|
+
const parser = this.parser;
|
523
|
+
const materialDef = parser.json.materials[materialIndex];
|
524
|
+
|
525
|
+
if (!materialDef.extensions || !materialDef.extensions[this.name]) {
|
526
|
+
return Promise.resolve();
|
527
|
+
}
|
528
|
+
|
529
|
+
const pending = [];
|
530
|
+
const extension = materialDef.extensions[this.name];
|
531
|
+
|
532
|
+
if (extension.iridescenceFactor !== undefined) {
|
533
|
+
materialParams.iridescence = extension.iridescenceFactor;
|
534
|
+
}
|
535
|
+
|
536
|
+
if (extension.iridescenceTexture !== undefined) {
|
537
|
+
pending.push(parser.assignTexture(materialParams, 'iridescenceMap', extension.iridescenceTexture));
|
538
|
+
}
|
539
|
+
|
540
|
+
if (extension.iridescenceIor !== undefined) {
|
541
|
+
materialParams.iridescenceIOR = extension.iridescenceIor;
|
542
|
+
}
|
543
|
+
|
544
|
+
if (materialParams.iridescenceThicknessRange === undefined) {
|
545
|
+
materialParams.iridescenceThicknessRange = [100, 400];
|
546
|
+
}
|
547
|
+
|
548
|
+
if (extension.iridescenceThicknessMinimum !== undefined) {
|
549
|
+
materialParams.iridescenceThicknessRange[0] = extension.iridescenceThicknessMinimum;
|
550
|
+
}
|
551
|
+
|
552
|
+
if (extension.iridescenceThicknessMaximum !== undefined) {
|
553
|
+
materialParams.iridescenceThicknessRange[1] = extension.iridescenceThicknessMaximum;
|
554
|
+
}
|
555
|
+
|
556
|
+
if (extension.iridescenceThicknessTexture !== undefined) {
|
557
|
+
pending.push(parser.assignTexture(materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture));
|
558
|
+
}
|
559
|
+
|
560
|
+
return Promise.all(pending);
|
561
|
+
}
|
562
|
+
|
461
563
|
}
|
462
564
|
/**
|
463
565
|
* Sheen Materials Extension
|
@@ -502,7 +604,7 @@ class GLTFMaterialsSheenExtension {
|
|
502
604
|
}
|
503
605
|
|
504
606
|
if (extension.sheenColorTexture !== undefined) {
|
505
|
-
pending.push(parser.assignTexture(materialParams, 'sheenColorMap', extension.sheenColorTexture));
|
607
|
+
pending.push(parser.assignTexture(materialParams, 'sheenColorMap', extension.sheenColorTexture, sRGBEncoding));
|
506
608
|
}
|
507
609
|
|
508
610
|
if (extension.sheenRoughnessTexture !== undefined) {
|
@@ -674,9 +776,7 @@ class GLTFMaterialsSpecularExtension {
|
|
674
776
|
materialParams.specularColor = new Color(colorArray[0], colorArray[1], colorArray[2]);
|
675
777
|
|
676
778
|
if (extension.specularColorTexture !== undefined) {
|
677
|
-
pending.push(parser.assignTexture(materialParams, 'specularColorMap', extension.specularColorTexture
|
678
|
-
texture.encoding = sRGBEncoding;
|
679
|
-
}));
|
779
|
+
pending.push(parser.assignTexture(materialParams, 'specularColorMap', extension.specularColorTexture, sRGBEncoding));
|
680
780
|
}
|
681
781
|
|
682
782
|
return Promise.all(pending);
|
@@ -706,7 +806,6 @@ class GLTFTextureBasisUExtension {
|
|
706
806
|
}
|
707
807
|
|
708
808
|
const extension = textureDef.extensions[this.name];
|
709
|
-
const source = json.images[extension.source];
|
710
809
|
const loader = parser.options.ktx2Loader;
|
711
810
|
|
712
811
|
if (!loader) {
|
@@ -718,7 +817,7 @@ class GLTFTextureBasisUExtension {
|
|
718
817
|
}
|
719
818
|
}
|
720
819
|
|
721
|
-
return parser.loadTextureImage(textureIndex, source, loader);
|
820
|
+
return parser.loadTextureImage(textureIndex, extension.source, loader);
|
722
821
|
}
|
723
822
|
|
724
823
|
}
|
@@ -756,7 +855,7 @@ class GLTFTextureWebPExtension {
|
|
756
855
|
}
|
757
856
|
|
758
857
|
return this.detectSupport().then(function (isSupported) {
|
759
|
-
if (isSupported) return parser.loadTextureImage(textureIndex, source, loader);
|
858
|
+
if (isSupported) return parser.loadTextureImage(textureIndex, extension.source, loader);
|
760
859
|
|
761
860
|
if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
|
762
861
|
throw new Error('THREE.GLTFLoader: WebP required by asset but unsupported.');
|
@@ -816,15 +915,25 @@ class GLTFMeshoptCompression {
|
|
816
915
|
}
|
817
916
|
}
|
818
917
|
|
819
|
-
return
|
918
|
+
return buffer.then(function (res) {
|
820
919
|
const byteOffset = extensionDef.byteOffset || 0;
|
821
920
|
const byteLength = extensionDef.byteLength || 0;
|
822
921
|
const count = extensionDef.count;
|
823
922
|
const stride = extensionDef.byteStride;
|
824
|
-
const
|
825
|
-
|
826
|
-
decoder.
|
827
|
-
|
923
|
+
const source = new Uint8Array(res, byteOffset, byteLength);
|
924
|
+
|
925
|
+
if (decoder.decodeGltfBufferAsync) {
|
926
|
+
return decoder.decodeGltfBufferAsync(count, stride, source, extensionDef.mode, extensionDef.filter).then(function (res) {
|
927
|
+
return res.buffer;
|
928
|
+
});
|
929
|
+
} else {
|
930
|
+
// Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync
|
931
|
+
return decoder.ready.then(function () {
|
932
|
+
const result = new ArrayBuffer(count * stride);
|
933
|
+
decoder.decodeGltfBuffer(new Uint8Array(result), count, stride, source, extensionDef.mode, extensionDef.filter);
|
934
|
+
return result;
|
935
|
+
});
|
936
|
+
}
|
828
937
|
});
|
829
938
|
} else {
|
830
939
|
return null;
|
@@ -927,7 +1036,7 @@ class GLTFDracoMeshCompressionExtension {
|
|
927
1036
|
if (gltfAttributeMap[attributeName] !== undefined) {
|
928
1037
|
const accessorDef = json.accessors[primitive.attributes[attributeName]];
|
929
1038
|
const componentType = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
|
930
|
-
attributeTypeMap[threeAttributeName] = componentType;
|
1039
|
+
attributeTypeMap[threeAttributeName] = componentType.name;
|
931
1040
|
attributeNormalizedMap[threeAttributeName] = accessorDef.normalized === true;
|
932
1041
|
}
|
933
1042
|
}
|
@@ -1129,7 +1238,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
1129
1238
|
}
|
1130
1239
|
|
1131
1240
|
if (pbrSpecularGlossiness.diffuseTexture !== undefined) {
|
1132
|
-
pending.push(parser.assignTexture(materialParams, 'map', pbrSpecularGlossiness.diffuseTexture));
|
1241
|
+
pending.push(parser.assignTexture(materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, sRGBEncoding));
|
1133
1242
|
}
|
1134
1243
|
|
1135
1244
|
materialParams.emissive = new Color(0.0, 0.0, 0.0);
|
@@ -1143,7 +1252,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
1143
1252
|
if (pbrSpecularGlossiness.specularGlossinessTexture !== undefined) {
|
1144
1253
|
const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
|
1145
1254
|
pending.push(parser.assignTexture(materialParams, 'glossinessMap', specGlossMapDef));
|
1146
|
-
pending.push(parser.assignTexture(materialParams, 'specularMap', specGlossMapDef));
|
1255
|
+
pending.push(parser.assignTexture(materialParams, 'specularMap', specGlossMapDef, sRGBEncoding));
|
1147
1256
|
}
|
1148
1257
|
|
1149
1258
|
return Promise.all(pending);
|
@@ -1159,7 +1268,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
1159
1268
|
material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;
|
1160
1269
|
material.aoMapIntensity = 1.0;
|
1161
1270
|
material.emissive = materialParams.emissive;
|
1162
|
-
material.emissiveIntensity = 1.0;
|
1271
|
+
material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity;
|
1163
1272
|
material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;
|
1164
1273
|
material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;
|
1165
1274
|
material.bumpScale = 1;
|
@@ -1223,43 +1332,40 @@ class GLTFCubicSplineInterpolant extends Interpolant {
|
|
1223
1332
|
return result;
|
1224
1333
|
}
|
1225
1334
|
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1335
|
+
interpolate_(i1, t0, t, t1) {
|
1336
|
+
const result = this.resultBuffer;
|
1337
|
+
const values = this.sampleValues;
|
1338
|
+
const stride = this.valueSize;
|
1339
|
+
const stride2 = stride * 2;
|
1340
|
+
const stride3 = stride * 3;
|
1341
|
+
const td = t1 - t0;
|
1342
|
+
const p = (t - t0) / td;
|
1343
|
+
const pp = p * p;
|
1344
|
+
const ppp = pp * p;
|
1345
|
+
const offset1 = i1 * stride3;
|
1346
|
+
const offset0 = offset1 - stride3;
|
1347
|
+
const s2 = -2 * ppp + 3 * pp;
|
1348
|
+
const s3 = ppp - pp;
|
1349
|
+
const s0 = 1 - s2;
|
1350
|
+
const s1 = s3 - pp + p; // Layout of keyframe output values for CUBICSPLINE animations:
|
1351
|
+
// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
|
1230
1352
|
|
1231
|
-
|
1232
|
-
|
1233
|
-
const values = this.sampleValues;
|
1234
|
-
const stride = this.valueSize;
|
1235
|
-
const stride2 = stride * 2;
|
1236
|
-
const stride3 = stride * 3;
|
1237
|
-
const td = t1 - t0;
|
1238
|
-
const p = (t - t0) / td;
|
1239
|
-
const pp = p * p;
|
1240
|
-
const ppp = pp * p;
|
1241
|
-
const offset1 = i1 * stride3;
|
1242
|
-
const offset0 = offset1 - stride3;
|
1243
|
-
const s2 = -2 * ppp + 3 * pp;
|
1244
|
-
const s3 = ppp - pp;
|
1245
|
-
const s0 = 1 - s2;
|
1246
|
-
const s1 = s3 - pp + p; // Layout of keyframe output values for CUBICSPLINE animations:
|
1247
|
-
// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
|
1353
|
+
for (let i = 0; i !== stride; i++) {
|
1354
|
+
const p0 = values[offset0 + i + stride]; // splineVertex_k
|
1248
1355
|
|
1249
|
-
|
1250
|
-
const p0 = values[offset0 + i + stride]; // splineVertex_k
|
1356
|
+
const m0 = values[offset0 + i + stride2] * td; // outTangent_k * (t_k+1 - t_k)
|
1251
1357
|
|
1252
|
-
|
1358
|
+
const p1 = values[offset1 + i + stride]; // splineVertex_k+1
|
1253
1359
|
|
1254
|
-
|
1360
|
+
const m1 = values[offset1 + i] * td; // inTangent_k+1 * (t_k+1 - t_k)
|
1255
1361
|
|
1256
|
-
|
1362
|
+
result[i] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
|
1363
|
+
}
|
1257
1364
|
|
1258
|
-
result
|
1365
|
+
return result;
|
1259
1366
|
}
|
1260
1367
|
|
1261
|
-
|
1262
|
-
};
|
1368
|
+
}
|
1263
1369
|
|
1264
1370
|
const _q = new Quaternion();
|
1265
1371
|
|
@@ -1418,17 +1524,20 @@ function assignExtrasToUserData(object, gltfDef) {
|
|
1418
1524
|
function addMorphTargets(geometry, targets, parser) {
|
1419
1525
|
let hasMorphPosition = false;
|
1420
1526
|
let hasMorphNormal = false;
|
1527
|
+
let hasMorphColor = false;
|
1421
1528
|
|
1422
1529
|
for (let i = 0, il = targets.length; i < il; i++) {
|
1423
1530
|
const target = targets[i];
|
1424
1531
|
if (target.POSITION !== undefined) hasMorphPosition = true;
|
1425
1532
|
if (target.NORMAL !== undefined) hasMorphNormal = true;
|
1426
|
-
if (
|
1533
|
+
if (target.COLOR_0 !== undefined) hasMorphColor = true;
|
1534
|
+
if (hasMorphPosition && hasMorphNormal && hasMorphColor) break;
|
1427
1535
|
}
|
1428
1536
|
|
1429
|
-
if (!hasMorphPosition && !hasMorphNormal) return Promise.resolve(geometry);
|
1537
|
+
if (!hasMorphPosition && !hasMorphNormal && !hasMorphColor) return Promise.resolve(geometry);
|
1430
1538
|
const pendingPositionAccessors = [];
|
1431
1539
|
const pendingNormalAccessors = [];
|
1540
|
+
const pendingColorAccessors = [];
|
1432
1541
|
|
1433
1542
|
for (let i = 0, il = targets.length; i < il; i++) {
|
1434
1543
|
const target = targets[i];
|
@@ -1442,13 +1551,20 @@ function addMorphTargets(geometry, targets, parser) {
|
|
1442
1551
|
const pendingAccessor = target.NORMAL !== undefined ? parser.getDependency('accessor', target.NORMAL) : geometry.attributes.normal;
|
1443
1552
|
pendingNormalAccessors.push(pendingAccessor);
|
1444
1553
|
}
|
1554
|
+
|
1555
|
+
if (hasMorphColor) {
|
1556
|
+
const pendingAccessor = target.COLOR_0 !== undefined ? parser.getDependency('accessor', target.COLOR_0) : geometry.attributes.color;
|
1557
|
+
pendingColorAccessors.push(pendingAccessor);
|
1558
|
+
}
|
1445
1559
|
}
|
1446
1560
|
|
1447
|
-
return Promise.all([Promise.all(pendingPositionAccessors), Promise.all(pendingNormalAccessors)]).then(function (accessors) {
|
1561
|
+
return Promise.all([Promise.all(pendingPositionAccessors), Promise.all(pendingNormalAccessors), Promise.all(pendingColorAccessors)]).then(function (accessors) {
|
1448
1562
|
const morphPositions = accessors[0];
|
1449
1563
|
const morphNormals = accessors[1];
|
1564
|
+
const morphColors = accessors[2];
|
1450
1565
|
if (hasMorphPosition) geometry.morphAttributes.position = morphPositions;
|
1451
1566
|
if (hasMorphNormal) geometry.morphAttributes.normal = morphNormals;
|
1567
|
+
if (hasMorphColor) geometry.morphAttributes.color = morphColors;
|
1452
1568
|
geometry.morphTargetsRelative = true;
|
1453
1569
|
return geometry;
|
1454
1570
|
});
|
@@ -1528,6 +1644,12 @@ function getNormalizedComponentScale(constructor) {
|
|
1528
1644
|
throw new Error('THREE.GLTFLoader: Unsupported normalized accessor component type.');
|
1529
1645
|
}
|
1530
1646
|
}
|
1647
|
+
|
1648
|
+
function getImageURIMimeType(uri) {
|
1649
|
+
if (uri.search(/\.jpe?g($|\?)/i) > 0 || uri.search(/^data\:image\/jpeg/) === 0) return 'image/jpeg';
|
1650
|
+
if (uri.search(/\.webp($|\?)/i) > 0 || uri.search(/^data\:image\/webp/) === 0) return 'image/webp';
|
1651
|
+
return 'image/png';
|
1652
|
+
}
|
1531
1653
|
/* GLTF PARSER */
|
1532
1654
|
|
1533
1655
|
|
@@ -1556,15 +1678,20 @@ class GLTFParser {
|
|
1556
1678
|
refs: {},
|
1557
1679
|
uses: {}
|
1558
1680
|
};
|
1681
|
+
this.sourceCache = {};
|
1559
1682
|
this.textureCache = {}; // Track node names, to ensure no duplicates
|
1560
1683
|
|
1561
1684
|
this.nodeNamesUsed = {}; // Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
|
1562
1685
|
// expensive work of uploading a texture to the GPU off the main thread.
|
1563
1686
|
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1687
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) === true;
|
1688
|
+
const isFirefox = navigator.userAgent.indexOf('Firefox') > -1;
|
1689
|
+
const firefoxVersion = isFirefox ? navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1] : -1;
|
1690
|
+
|
1691
|
+
if (typeof createImageBitmap === 'undefined' || isSafari || isFirefox && firefoxVersion < 98) {
|
1567
1692
|
this.textureLoader = new TextureLoader(this.options.manager);
|
1693
|
+
} else {
|
1694
|
+
this.textureLoader = new ImageBitmapLoader(this.options.manager);
|
1568
1695
|
}
|
1569
1696
|
|
1570
1697
|
this.textureLoader.setCrossOrigin(this.options.crossOrigin);
|
@@ -1787,7 +1914,9 @@ class GLTFParser {
|
|
1787
1914
|
break;
|
1788
1915
|
|
1789
1916
|
case 'animation':
|
1790
|
-
dependency = this.
|
1917
|
+
dependency = this._invokeOne(function (ext) {
|
1918
|
+
return ext.loadAnimation && ext.loadAnimation(index);
|
1919
|
+
});
|
1791
1920
|
break;
|
1792
1921
|
|
1793
1922
|
case 'camera':
|
@@ -1973,45 +2102,76 @@ class GLTFParser {
|
|
1973
2102
|
const json = this.json;
|
1974
2103
|
const options = this.options;
|
1975
2104
|
const textureDef = json.textures[textureIndex];
|
1976
|
-
const
|
2105
|
+
const sourceIndex = textureDef.source;
|
2106
|
+
const sourceDef = json.images[sourceIndex];
|
1977
2107
|
let loader = this.textureLoader;
|
1978
2108
|
|
1979
|
-
if (
|
1980
|
-
const handler = options.manager.getHandler(
|
2109
|
+
if (sourceDef.uri) {
|
2110
|
+
const handler = options.manager.getHandler(sourceDef.uri);
|
1981
2111
|
if (handler !== null) loader = handler;
|
1982
2112
|
}
|
1983
2113
|
|
1984
|
-
return this.loadTextureImage(textureIndex,
|
2114
|
+
return this.loadTextureImage(textureIndex, sourceIndex, loader);
|
1985
2115
|
}
|
1986
2116
|
|
1987
|
-
loadTextureImage(textureIndex,
|
2117
|
+
loadTextureImage(textureIndex, sourceIndex, loader) {
|
1988
2118
|
const parser = this;
|
1989
2119
|
const json = this.json;
|
1990
|
-
const options = this.options;
|
1991
2120
|
const textureDef = json.textures[textureIndex];
|
1992
|
-
const
|
2121
|
+
const sourceDef = json.images[sourceIndex];
|
2122
|
+
const cacheKey = (sourceDef.uri || sourceDef.bufferView) + ':' + textureDef.sampler;
|
1993
2123
|
|
1994
2124
|
if (this.textureCache[cacheKey]) {
|
1995
2125
|
// See https://github.com/mrdoob/three.js/issues/21559.
|
1996
2126
|
return this.textureCache[cacheKey];
|
1997
2127
|
}
|
1998
2128
|
|
2129
|
+
const promise = this.loadImageSource(sourceIndex, loader).then(function (texture) {
|
2130
|
+
texture.flipY = false;
|
2131
|
+
if (textureDef.name) texture.name = textureDef.name;
|
2132
|
+
const samplers = json.samplers || {};
|
2133
|
+
const sampler = samplers[textureDef.sampler] || {};
|
2134
|
+
texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || LinearFilter;
|
2135
|
+
texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || LinearMipmapLinearFilter;
|
2136
|
+
texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || RepeatWrapping;
|
2137
|
+
texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || RepeatWrapping;
|
2138
|
+
parser.associations.set(texture, {
|
2139
|
+
textures: textureIndex
|
2140
|
+
});
|
2141
|
+
return texture;
|
2142
|
+
}).catch(function () {
|
2143
|
+
return null;
|
2144
|
+
});
|
2145
|
+
this.textureCache[cacheKey] = promise;
|
2146
|
+
return promise;
|
2147
|
+
}
|
2148
|
+
|
2149
|
+
loadImageSource(sourceIndex, loader) {
|
2150
|
+
const parser = this;
|
2151
|
+
const json = this.json;
|
2152
|
+
const options = this.options;
|
2153
|
+
|
2154
|
+
if (this.sourceCache[sourceIndex] !== undefined) {
|
2155
|
+
return this.sourceCache[sourceIndex].then(texture => texture.clone());
|
2156
|
+
}
|
2157
|
+
|
2158
|
+
const sourceDef = json.images[sourceIndex];
|
1999
2159
|
const URL = self.URL || self.webkitURL;
|
2000
|
-
let sourceURI =
|
2160
|
+
let sourceURI = sourceDef.uri || '';
|
2001
2161
|
let isObjectURL = false;
|
2002
2162
|
|
2003
|
-
if (
|
2163
|
+
if (sourceDef.bufferView !== undefined) {
|
2004
2164
|
// Load binary image data from bufferView, if provided.
|
2005
|
-
sourceURI = parser.getDependency('bufferView',
|
2165
|
+
sourceURI = parser.getDependency('bufferView', sourceDef.bufferView).then(function (bufferView) {
|
2006
2166
|
isObjectURL = true;
|
2007
2167
|
const blob = new Blob([bufferView], {
|
2008
|
-
type:
|
2168
|
+
type: sourceDef.mimeType
|
2009
2169
|
});
|
2010
2170
|
sourceURI = URL.createObjectURL(blob);
|
2011
2171
|
return sourceURI;
|
2012
2172
|
});
|
2013
|
-
} else if (
|
2014
|
-
throw new Error('THREE.GLTFLoader: Image ' +
|
2173
|
+
} else if (sourceDef.uri === undefined) {
|
2174
|
+
throw new Error('THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView');
|
2015
2175
|
}
|
2016
2176
|
|
2017
2177
|
const promise = Promise.resolve(sourceURI).then(function (sourceURI) {
|
@@ -2034,23 +2194,13 @@ class GLTFParser {
|
|
2034
2194
|
URL.revokeObjectURL(sourceURI);
|
2035
2195
|
}
|
2036
2196
|
|
2037
|
-
texture.
|
2038
|
-
if (textureDef.name) texture.name = textureDef.name;
|
2039
|
-
const samplers = json.samplers || {};
|
2040
|
-
const sampler = samplers[textureDef.sampler] || {};
|
2041
|
-
texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || LinearFilter;
|
2042
|
-
texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || LinearMipmapLinearFilter;
|
2043
|
-
texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || RepeatWrapping;
|
2044
|
-
texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || RepeatWrapping;
|
2045
|
-
parser.associations.set(texture, {
|
2046
|
-
textures: textureIndex
|
2047
|
-
});
|
2197
|
+
texture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType(sourceDef.uri);
|
2048
2198
|
return texture;
|
2049
|
-
}).catch(function () {
|
2199
|
+
}).catch(function (error) {
|
2050
2200
|
console.error("THREE.GLTFLoader: Couldn't load texture", sourceURI);
|
2051
|
-
|
2201
|
+
throw error;
|
2052
2202
|
});
|
2053
|
-
this.
|
2203
|
+
this.sourceCache[sourceIndex] = promise;
|
2054
2204
|
return promise;
|
2055
2205
|
}
|
2056
2206
|
/**
|
@@ -2062,7 +2212,7 @@ class GLTFParser {
|
|
2062
2212
|
*/
|
2063
2213
|
|
2064
2214
|
|
2065
|
-
assignTexture(materialParams, mapName, mapDef) {
|
2215
|
+
assignTexture(materialParams, mapName, mapDef, encoding) {
|
2066
2216
|
const parser = this;
|
2067
2217
|
return this.getDependency('texture', mapDef.index).then(function (texture) {
|
2068
2218
|
// Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
|
@@ -2081,6 +2231,10 @@ class GLTFParser {
|
|
2081
2231
|
}
|
2082
2232
|
}
|
2083
2233
|
|
2234
|
+
if (encoding !== undefined) {
|
2235
|
+
texture.encoding = encoding;
|
2236
|
+
}
|
2237
|
+
|
2084
2238
|
materialParams[mapName] = texture;
|
2085
2239
|
return texture;
|
2086
2240
|
});
|
@@ -2208,7 +2362,7 @@ class GLTFParser {
|
|
2208
2362
|
}
|
2209
2363
|
|
2210
2364
|
if (metallicRoughness.baseColorTexture !== undefined) {
|
2211
|
-
pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture));
|
2365
|
+
pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding));
|
2212
2366
|
}
|
2213
2367
|
|
2214
2368
|
materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
|
@@ -2268,7 +2422,7 @@ class GLTFParser {
|
|
2268
2422
|
}
|
2269
2423
|
|
2270
2424
|
if (materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial) {
|
2271
|
-
pending.push(parser.assignTexture(materialParams, 'emissiveMap', materialDef.emissiveTexture));
|
2425
|
+
pending.push(parser.assignTexture(materialParams, 'emissiveMap', materialDef.emissiveTexture, sRGBEncoding));
|
2272
2426
|
}
|
2273
2427
|
|
2274
2428
|
return Promise.all(pending).then(function () {
|
@@ -2280,10 +2434,7 @@ class GLTFParser {
|
|
2280
2434
|
material = new materialType(materialParams);
|
2281
2435
|
}
|
2282
2436
|
|
2283
|
-
if (materialDef.name) material.name = materialDef.name;
|
2284
|
-
|
2285
|
-
if (material.map) material.map.encoding = sRGBEncoding;
|
2286
|
-
if (material.emissiveMap) material.emissiveMap.encoding = sRGBEncoding;
|
2437
|
+
if (materialDef.name) material.name = materialDef.name;
|
2287
2438
|
assignExtrasToUserData(material, materialDef);
|
2288
2439
|
parser.associations.set(material, {
|
2289
2440
|
materials: materialIndex
|
@@ -2523,8 +2674,7 @@ class GLTFParser {
|
|
2523
2674
|
const channel = animationDef.channels[i];
|
2524
2675
|
const sampler = animationDef.samplers[channel.sampler];
|
2525
2676
|
const target = channel.target;
|
2526
|
-
const name = target.node
|
2527
|
-
|
2677
|
+
const name = target.node;
|
2528
2678
|
const input = animationDef.parameters !== undefined ? animationDef.parameters[sampler.input] : sampler.input;
|
2529
2679
|
const output = animationDef.parameters !== undefined ? animationDef.parameters[sampler.output] : sampler.output;
|
2530
2680
|
pendingNodes.push(this.getDependency('node', name));
|
@@ -2550,7 +2700,6 @@ class GLTFParser {
|
|
2550
2700
|
const target = targets[i];
|
2551
2701
|
if (node === undefined) continue;
|
2552
2702
|
node.updateMatrix();
|
2553
|
-
node.matrixAutoUpdate = true;
|
2554
2703
|
let TypedKeyframeTrack;
|
2555
2704
|
|
2556
2705
|
switch (PATH_PROPERTIES[target.path]) {
|