three-stdlib 2.16.2 → 2.17.0
Sign up to get free protection for your applications and to get access to all the features.
- 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]) {
|