@babylonjs/serializers 5.32.0 → 5.32.2
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/glTF/2.0/Extensions/KHR_texture_transform.d.ts +2 -9
- package/glTF/2.0/Extensions/KHR_texture_transform.js +5 -54
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/glTFExporter.d.ts +2 -2
- package/glTF/2.0/glTFExporter.js +3 -3
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFExporterExtension.d.ts +1 -1
- package/glTF/2.0/glTFExporterExtension.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.d.ts +6 -13
- package/glTF/2.0/glTFMaterialExporter.js +215 -262
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/package.json +3 -3
- package/glTF/2.0/shaders/textureTransform.fragment.d.ts +0 -5
- package/glTF/2.0/shaders/textureTransform.fragment.js +0 -13
- package/glTF/2.0/shaders/textureTransform.fragment.js.map +0 -1
|
@@ -6,6 +6,16 @@ import { TextureTools } from "@babylonjs/core/Misc/textureTools.js";
|
|
|
6
6
|
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
|
|
7
7
|
import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
|
|
8
8
|
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
|
9
|
+
function getFileExtensionFromMimeType(mimeType) {
|
|
10
|
+
switch (mimeType) {
|
|
11
|
+
case "image/jpeg" /* JPEG */:
|
|
12
|
+
return ".jpg";
|
|
13
|
+
case "image/png" /* PNG */:
|
|
14
|
+
return ".png";
|
|
15
|
+
case "image/webp" /* WEBP */:
|
|
16
|
+
return ".webp";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
9
19
|
/**
|
|
10
20
|
* Utility methods for working with glTF material conversion properties. This class should only be used internally
|
|
11
21
|
* @internal
|
|
@@ -16,6 +26,8 @@ export class _GLTFMaterialExporter {
|
|
|
16
26
|
* Mapping to store textures
|
|
17
27
|
*/
|
|
18
28
|
this._textureMap = {};
|
|
29
|
+
// Mapping of internal textures to images to avoid exporting duplicate images.
|
|
30
|
+
this._internalTextureToImage = {};
|
|
19
31
|
this._textureMap = {};
|
|
20
32
|
this._exporter = exporter;
|
|
21
33
|
}
|
|
@@ -199,68 +211,68 @@ export class _GLTFMaterialExporter {
|
|
|
199
211
|
const materialMap = this._exporter._materialMap;
|
|
200
212
|
const materials = this._exporter._materials;
|
|
201
213
|
const promises = [];
|
|
202
|
-
const
|
|
203
|
-
const
|
|
214
|
+
const pbrMetallicRoughness = this._convertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
|
|
215
|
+
const material = { name: babylonStandardMaterial.name };
|
|
204
216
|
if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
|
|
205
217
|
if (!babylonStandardMaterial.twoSidedLighting) {
|
|
206
218
|
Tools.Warn(babylonStandardMaterial.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.");
|
|
207
219
|
}
|
|
208
|
-
|
|
220
|
+
material.doubleSided = true;
|
|
209
221
|
}
|
|
210
222
|
if (hasTextureCoords) {
|
|
211
223
|
if (babylonStandardMaterial.diffuseTexture) {
|
|
212
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then((
|
|
213
|
-
if (
|
|
214
|
-
|
|
224
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then((textureInfo) => {
|
|
225
|
+
if (textureInfo) {
|
|
226
|
+
pbrMetallicRoughness.baseColorTexture = textureInfo;
|
|
215
227
|
}
|
|
216
228
|
}));
|
|
217
229
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
230
|
+
const bumpTexture = babylonStandardMaterial.bumpTexture;
|
|
231
|
+
if (bumpTexture) {
|
|
232
|
+
promises.push(this._exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {
|
|
233
|
+
if (textureInfo) {
|
|
234
|
+
material.normalTexture = textureInfo;
|
|
235
|
+
if (bumpTexture.level !== 1) {
|
|
236
|
+
material.normalTexture.scale = bumpTexture.level;
|
|
224
237
|
}
|
|
225
238
|
}
|
|
226
239
|
}));
|
|
227
240
|
}
|
|
228
241
|
if (babylonStandardMaterial.emissiveTexture) {
|
|
229
|
-
|
|
230
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then((
|
|
231
|
-
if (
|
|
232
|
-
|
|
242
|
+
material.emissiveFactor = [1.0, 1.0, 1.0];
|
|
243
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then((textureInfo) => {
|
|
244
|
+
if (textureInfo) {
|
|
245
|
+
material.emissiveTexture = textureInfo;
|
|
233
246
|
}
|
|
234
247
|
}));
|
|
235
248
|
}
|
|
236
249
|
if (babylonStandardMaterial.ambientTexture) {
|
|
237
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then((
|
|
238
|
-
if (
|
|
250
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then((textureInfo) => {
|
|
251
|
+
if (textureInfo) {
|
|
239
252
|
const occlusionTexture = {
|
|
240
|
-
index:
|
|
253
|
+
index: textureInfo.index,
|
|
241
254
|
};
|
|
242
|
-
|
|
243
|
-
occlusionTexture.strength = 1.0;
|
|
255
|
+
material.occlusionTexture = occlusionTexture;
|
|
244
256
|
}
|
|
245
257
|
}));
|
|
246
258
|
}
|
|
247
259
|
}
|
|
248
260
|
if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
|
|
249
261
|
if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {
|
|
250
|
-
|
|
262
|
+
material.alphaMode = "BLEND" /* BLEND */;
|
|
251
263
|
}
|
|
252
264
|
else {
|
|
253
265
|
Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
|
|
254
266
|
}
|
|
255
267
|
}
|
|
256
268
|
if (babylonStandardMaterial.emissiveColor && !_GLTFMaterialExporter._FuzzyEquals(babylonStandardMaterial.emissiveColor, Color3.Black(), _GLTFMaterialExporter._Epsilon)) {
|
|
257
|
-
|
|
269
|
+
material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
|
|
258
270
|
}
|
|
259
|
-
|
|
260
|
-
_GLTFMaterialExporter._SetAlphaMode(
|
|
261
|
-
materials.push(
|
|
271
|
+
material.pbrMetallicRoughness = pbrMetallicRoughness;
|
|
272
|
+
_GLTFMaterialExporter._SetAlphaMode(material, babylonStandardMaterial);
|
|
273
|
+
materials.push(material);
|
|
262
274
|
materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1;
|
|
263
|
-
return this._finishMaterial(promises,
|
|
275
|
+
return this._finishMaterial(promises, material, babylonStandardMaterial, mimeType);
|
|
264
276
|
}
|
|
265
277
|
_finishMaterial(promises, glTFMaterial, babylonMaterial, mimeType) {
|
|
266
278
|
return Promise.all(promises).then(() => {
|
|
@@ -292,19 +304,15 @@ export class _GLTFMaterialExporter {
|
|
|
292
304
|
* @param mimeType mimetype of the image
|
|
293
305
|
* @returns base64 image string
|
|
294
306
|
*/
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const data = await engine._readTexturePixels(tempTexture, width, height);
|
|
305
|
-
const base64 = await Tools.DumpDataAsync(width, height, data, mimeType, undefined, true, false);
|
|
306
|
-
resolve(base64);
|
|
307
|
-
});
|
|
307
|
+
async _getImageDataAsync(buffer, width, height, mimeType) {
|
|
308
|
+
const textureType = Constants.TEXTURETYPE_UNSIGNED_INT;
|
|
309
|
+
const hostingScene = this._exporter._babylonScene;
|
|
310
|
+
const engine = hostingScene.getEngine();
|
|
311
|
+
// Create a temporary texture with the texture buffer data
|
|
312
|
+
const tempTexture = engine.createRawTexture(buffer, width, height, Constants.TEXTUREFORMAT_RGBA, false, true, Texture.NEAREST_SAMPLINGMODE, null, textureType);
|
|
313
|
+
await TextureTools.ApplyPostProcess("pass", tempTexture, hostingScene, textureType, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTUREFORMAT_RGBA);
|
|
314
|
+
const data = await engine._readTexturePixels(tempTexture, width, height);
|
|
315
|
+
return (await Tools.DumpDataAsync(width, height, data, mimeType, undefined, true, true));
|
|
308
316
|
}
|
|
309
317
|
/**
|
|
310
318
|
* Generates a white texture based on the specified width and height
|
|
@@ -394,7 +402,7 @@ export class _GLTFMaterialExporter {
|
|
|
394
402
|
*/
|
|
395
403
|
async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(diffuseTexture, specularGlossinessTexture, factors, mimeType) {
|
|
396
404
|
var _a;
|
|
397
|
-
const promises =
|
|
405
|
+
const promises = new Array();
|
|
398
406
|
if (!(diffuseTexture || specularGlossinessTexture)) {
|
|
399
407
|
return Promise.reject("_ConvertSpecularGlosinessTexturesToMetallicRoughness: diffuse and specular glossiness textures are not defined!");
|
|
400
408
|
}
|
|
@@ -488,16 +496,14 @@ export class _GLTFMaterialExporter {
|
|
|
488
496
|
}
|
|
489
497
|
}
|
|
490
498
|
if (writeOutMetallicRoughnessTexture) {
|
|
491
|
-
|
|
492
|
-
metallicRoughnessFactors.
|
|
493
|
-
});
|
|
494
|
-
promises.push(promise);
|
|
499
|
+
promises.push(this._getImageDataAsync(metallicRoughnessBuffer, width, height, mimeType).then((data) => {
|
|
500
|
+
metallicRoughnessFactors.metallicRoughnessTextureData = data;
|
|
501
|
+
}));
|
|
495
502
|
}
|
|
496
503
|
if (writeOutBaseColorTexture) {
|
|
497
|
-
|
|
498
|
-
metallicRoughnessFactors.
|
|
499
|
-
});
|
|
500
|
-
promises.push(promise);
|
|
504
|
+
promises.push(this._getImageDataAsync(baseColorBuffer, width, height, mimeType).then((data) => {
|
|
505
|
+
metallicRoughnessFactors.baseColorTextureData = data;
|
|
506
|
+
}));
|
|
501
507
|
}
|
|
502
508
|
return Promise.all(promises).then(() => {
|
|
503
509
|
return metallicRoughnessFactors;
|
|
@@ -592,71 +598,79 @@ export class _GLTFMaterialExporter {
|
|
|
592
598
|
return metallicRoughness;
|
|
593
599
|
});
|
|
594
600
|
}
|
|
595
|
-
|
|
596
|
-
const sampler =
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
601
|
+
_getTextureSampler(texture) {
|
|
602
|
+
const sampler = {};
|
|
603
|
+
if (!texture || !(texture instanceof Texture)) {
|
|
604
|
+
return sampler;
|
|
605
|
+
}
|
|
606
|
+
const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);
|
|
607
|
+
if (wrapS !== 10497 /* REPEAT */) {
|
|
608
|
+
sampler.wrapS = wrapS;
|
|
609
|
+
}
|
|
610
|
+
const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);
|
|
611
|
+
if (wrapT !== 10497 /* REPEAT */) {
|
|
612
|
+
sampler.wrapT = wrapT;
|
|
613
|
+
}
|
|
614
|
+
switch (texture.samplingMode) {
|
|
615
|
+
case Texture.LINEAR_LINEAR: {
|
|
616
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
617
|
+
sampler.minFilter = 9729 /* LINEAR */;
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
case Texture.LINEAR_NEAREST: {
|
|
621
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
622
|
+
sampler.minFilter = 9728 /* NEAREST */;
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case Texture.NEAREST_LINEAR: {
|
|
626
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
627
|
+
sampler.minFilter = 9729 /* LINEAR */;
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
case Texture.NEAREST_LINEAR_MIPLINEAR: {
|
|
631
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
632
|
+
sampler.minFilter = 9987 /* LINEAR_MIPMAP_LINEAR */;
|
|
633
|
+
break;
|
|
634
|
+
}
|
|
635
|
+
case Texture.NEAREST_NEAREST: {
|
|
636
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
637
|
+
sampler.minFilter = 9728 /* NEAREST */;
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
case Texture.NEAREST_LINEAR_MIPNEAREST: {
|
|
641
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
642
|
+
sampler.minFilter = 9985 /* LINEAR_MIPMAP_NEAREST */;
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
case Texture.LINEAR_NEAREST_MIPNEAREST: {
|
|
646
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
647
|
+
sampler.minFilter = 9984 /* NEAREST_MIPMAP_NEAREST */;
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
case Texture.LINEAR_NEAREST_MIPLINEAR: {
|
|
651
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
652
|
+
sampler.minFilter = 9986 /* NEAREST_MIPMAP_LINEAR */;
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
case Texture.NEAREST_NEAREST_MIPLINEAR: {
|
|
656
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
657
|
+
sampler.minFilter = 9986 /* NEAREST_MIPMAP_LINEAR */;
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
case Texture.LINEAR_LINEAR_MIPLINEAR: {
|
|
661
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
662
|
+
sampler.minFilter = 9987 /* LINEAR_MIPMAP_LINEAR */;
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
case Texture.LINEAR_LINEAR_MIPNEAREST: {
|
|
666
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
667
|
+
sampler.minFilter = 9985 /* LINEAR_MIPMAP_NEAREST */;
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
case Texture.NEAREST_NEAREST_MIPNEAREST: {
|
|
671
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
672
|
+
sampler.minFilter = 9984 /* NEAREST_MIPMAP_NEAREST */;
|
|
673
|
+
break;
|
|
660
674
|
}
|
|
661
675
|
}
|
|
662
676
|
return sampler;
|
|
@@ -678,15 +692,6 @@ export class _GLTFMaterialExporter {
|
|
|
678
692
|
}
|
|
679
693
|
}
|
|
680
694
|
}
|
|
681
|
-
_getGLTFTextureWrapModesSampler(texture) {
|
|
682
|
-
const wrapS = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapU : Texture.WRAP_ADDRESSMODE);
|
|
683
|
-
const wrapT = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapV : Texture.WRAP_ADDRESSMODE);
|
|
684
|
-
if (wrapS === 10497 /* REPEAT */ && wrapT === 10497 /* REPEAT */) {
|
|
685
|
-
// default wrapping mode in glTF, so omitting
|
|
686
|
-
return {};
|
|
687
|
-
}
|
|
688
|
-
return { wrapS: wrapS, wrapT: wrapT };
|
|
689
|
-
}
|
|
690
695
|
/**
|
|
691
696
|
* Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors
|
|
692
697
|
* @param babylonPBRMaterial BJS PBR Metallic Roughness Material
|
|
@@ -695,45 +700,30 @@ export class _GLTFMaterialExporter {
|
|
|
695
700
|
* @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
|
696
701
|
* @returns glTF PBR Metallic Roughness factors
|
|
697
702
|
*/
|
|
698
|
-
_convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType,
|
|
703
|
+
_convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, pbrMetallicRoughness, hasTextureCoords) {
|
|
699
704
|
return Promise.resolve().then(() => {
|
|
700
|
-
const samplers = this._exporter._samplers;
|
|
701
|
-
const textures = this._exporter._textures;
|
|
702
|
-
const diffuseColor = babylonPBRMaterial._albedoColor;
|
|
703
|
-
const specularColor = babylonPBRMaterial._reflectivityColor;
|
|
704
|
-
const glossiness = babylonPBRMaterial._microSurface;
|
|
705
705
|
const specGloss = {
|
|
706
|
-
diffuseColor:
|
|
707
|
-
specularColor:
|
|
708
|
-
glossiness:
|
|
706
|
+
diffuseColor: babylonPBRMaterial._albedoColor,
|
|
707
|
+
specularColor: babylonPBRMaterial._reflectivityColor,
|
|
708
|
+
glossiness: babylonPBRMaterial._microSurface,
|
|
709
709
|
};
|
|
710
|
-
let samplerIndex = null;
|
|
711
710
|
const albedoTexture = babylonPBRMaterial._albedoTexture;
|
|
712
711
|
const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;
|
|
713
|
-
if (albedoTexture) {
|
|
714
|
-
const sampler = this._getGLTFTextureSampler(albedoTexture);
|
|
715
|
-
if (sampler.magFilter != null && sampler.minFilter != null && sampler.wrapS != null && sampler.wrapT != null) {
|
|
716
|
-
samplers.push(sampler);
|
|
717
|
-
samplerIndex = samplers.length - 1;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
712
|
const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;
|
|
721
713
|
if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {
|
|
722
714
|
return Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported");
|
|
723
715
|
}
|
|
724
716
|
if ((albedoTexture || reflectivityTexture) && hasTextureCoords) {
|
|
717
|
+
const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);
|
|
725
718
|
return this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType).then((metallicRoughnessFactors) => {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
719
|
+
const textures = this._exporter._textures;
|
|
720
|
+
if (metallicRoughnessFactors.baseColorTextureData) {
|
|
721
|
+
const imageIndex = this._exportImage(`baseColor${textures.length}`, mimeType, metallicRoughnessFactors.baseColorTextureData);
|
|
722
|
+
pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture === null || albedoTexture === void 0 ? void 0 : albedoTexture.coordinatesIndex);
|
|
731
723
|
}
|
|
732
|
-
if (metallicRoughnessFactors.
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;
|
|
736
|
-
}
|
|
724
|
+
if (metallicRoughnessFactors.metallicRoughnessTextureData) {
|
|
725
|
+
const imageIndex = this._exportImage(`metallicRoughness${textures.length}`, mimeType, metallicRoughnessFactors.metallicRoughnessTextureData);
|
|
726
|
+
pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture === null || reflectivityTexture === void 0 ? void 0 : reflectivityTexture.coordinatesIndex);
|
|
737
727
|
}
|
|
738
728
|
return metallicRoughnessFactors;
|
|
739
729
|
});
|
|
@@ -867,129 +857,92 @@ export class _GLTFMaterialExporter {
|
|
|
867
857
|
return this._exportTextureInfoAsync(texture, mimeType);
|
|
868
858
|
});
|
|
869
859
|
}
|
|
870
|
-
_exportTextureInfoAsync(babylonTexture, mimeType) {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
860
|
+
async _exportTextureInfoAsync(babylonTexture, mimeType) {
|
|
861
|
+
const textureUid = babylonTexture.uid;
|
|
862
|
+
if (textureUid in this._textureMap) {
|
|
863
|
+
return this._textureMap[textureUid];
|
|
864
|
+
}
|
|
865
|
+
else {
|
|
866
|
+
const pixels = await this._getPixelsFromTexture(babylonTexture);
|
|
867
|
+
if (!pixels) {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
const samplerIndex = this._exportTextureSampler(babylonTexture);
|
|
871
|
+
// Preserve texture mime type if defined
|
|
872
|
+
const textureMimeType = babylonTexture.mimeType;
|
|
873
|
+
if (textureMimeType) {
|
|
874
|
+
switch (textureMimeType) {
|
|
875
|
+
case "image/jpeg":
|
|
876
|
+
case "image/png":
|
|
877
|
+
case "image/webp":
|
|
878
|
+
mimeType = textureMimeType;
|
|
879
|
+
break;
|
|
880
|
+
default:
|
|
881
|
+
Tools.Warn("Unsupported media type: ${textureMimeType}");
|
|
890
882
|
break;
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
if (foundSamplerIndex == null) {
|
|
894
|
-
samplers.push(sampler);
|
|
895
|
-
samplerIndex = samplers.length - 1;
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
samplerIndex = foundSamplerIndex;
|
|
899
883
|
}
|
|
884
|
+
}
|
|
885
|
+
const internalTextureToImage = this._internalTextureToImage;
|
|
886
|
+
const internalTextureUniqueId = babylonTexture.getInternalTexture().uniqueId;
|
|
887
|
+
internalTextureToImage[internalTextureUniqueId] || (internalTextureToImage[internalTextureUniqueId] = {});
|
|
888
|
+
let imageIndex = internalTextureToImage[internalTextureUniqueId][mimeType];
|
|
889
|
+
if (imageIndex === undefined) {
|
|
900
890
|
const size = babylonTexture.getSize();
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
case "image/jpeg":
|
|
905
|
-
mimeType = "image/jpeg" /* JPEG */;
|
|
906
|
-
break;
|
|
907
|
-
case "image/png":
|
|
908
|
-
mimeType = "image/png" /* PNG */;
|
|
909
|
-
break;
|
|
910
|
-
case "image/webp":
|
|
911
|
-
mimeType = "image/webp" /* WEBP */;
|
|
912
|
-
break;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {
|
|
916
|
-
const textureInfo = this._getTextureInfoFromBase64(base64Data, babylonTexture.name.replace(/\.\/|\/|\.\\|\\/g, "_"), mimeType, babylonTexture.coordinatesIndex, samplerIndex);
|
|
917
|
-
if (textureInfo) {
|
|
918
|
-
this._textureMap[textureUid] = textureInfo;
|
|
919
|
-
this._exporter._extensionsPostExportTextures("linkTextureInfo", textureInfo, babylonTexture);
|
|
920
|
-
}
|
|
921
|
-
return textureInfo;
|
|
922
|
-
});
|
|
891
|
+
const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);
|
|
892
|
+
imageIndex = this._exportImage(babylonTexture.name, mimeType, data);
|
|
893
|
+
internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndex;
|
|
923
894
|
}
|
|
924
|
-
|
|
895
|
+
const textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, babylonTexture.coordinatesIndex);
|
|
896
|
+
this._textureMap[textureUid] = textureInfo;
|
|
897
|
+
return textureInfo;
|
|
898
|
+
}
|
|
925
899
|
}
|
|
926
|
-
|
|
927
|
-
* Builds a texture from base64 string
|
|
928
|
-
* @param base64Texture base64 texture string
|
|
929
|
-
* @param baseTextureName Name to use for the texture
|
|
930
|
-
* @param mimeType image mime type for the texture
|
|
931
|
-
* @param texCoordIndex
|
|
932
|
-
* @param samplerIndex
|
|
933
|
-
* @returns glTF texture info, or null if the texture format is not supported
|
|
934
|
-
*/
|
|
935
|
-
_getTextureInfoFromBase64(base64Texture, baseTextureName, mimeType, texCoordIndex, samplerIndex) {
|
|
936
|
-
const textures = this._exporter._textures;
|
|
937
|
-
const images = this._exporter._images;
|
|
900
|
+
_exportImage(name, mimeType, data) {
|
|
938
901
|
const imageData = this._exporter._imageData;
|
|
939
|
-
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
902
|
+
const baseName = name.replace(/\.\/|\/|\.\\|\\/g, "_");
|
|
903
|
+
const extension = getFileExtensionFromMimeType(mimeType);
|
|
904
|
+
let fileName = baseName + extension;
|
|
905
|
+
if (fileName in imageData) {
|
|
906
|
+
fileName = `${baseName}_${Tools.RandomId()}${extension}`;
|
|
907
|
+
}
|
|
908
|
+
imageData[fileName] = {
|
|
909
|
+
data: data,
|
|
910
|
+
mimeType: mimeType,
|
|
943
911
|
};
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
imageData[textureName] = imageValues;
|
|
961
|
-
if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */ || mimeType === "image/webp" /* WEBP */) {
|
|
962
|
-
const glTFImage = {
|
|
963
|
-
name: baseTextureName,
|
|
964
|
-
uri: textureName,
|
|
965
|
-
};
|
|
966
|
-
let foundIndex = null;
|
|
967
|
-
for (let i = 0; i < images.length; ++i) {
|
|
968
|
-
if (images[i].uri === originalTextureName) {
|
|
969
|
-
foundIndex = i;
|
|
970
|
-
break;
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
if (foundIndex == null) {
|
|
974
|
-
images.push(glTFImage);
|
|
975
|
-
glTFTexture.source = images.length - 1;
|
|
976
|
-
}
|
|
977
|
-
else {
|
|
978
|
-
glTFTexture.source = foundIndex;
|
|
979
|
-
}
|
|
980
|
-
textures.push(glTFTexture);
|
|
981
|
-
textureInfo = {
|
|
982
|
-
index: textures.length - 1,
|
|
983
|
-
};
|
|
984
|
-
if (texCoordIndex != null) {
|
|
985
|
-
textureInfo.texCoord = texCoordIndex;
|
|
986
|
-
}
|
|
912
|
+
const images = this._exporter._images;
|
|
913
|
+
images.push({
|
|
914
|
+
name: name,
|
|
915
|
+
uri: fileName,
|
|
916
|
+
});
|
|
917
|
+
return images.length - 1;
|
|
918
|
+
}
|
|
919
|
+
_exportTextureInfo(imageIndex, samplerIndex, coordinatesIndex) {
|
|
920
|
+
const textures = this._exporter._textures;
|
|
921
|
+
let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);
|
|
922
|
+
if (textureIndex === -1) {
|
|
923
|
+
textureIndex = textures.length;
|
|
924
|
+
textures.push({
|
|
925
|
+
source: imageIndex,
|
|
926
|
+
sampler: samplerIndex,
|
|
927
|
+
});
|
|
987
928
|
}
|
|
988
|
-
|
|
989
|
-
|
|
929
|
+
const textureInfo = { index: textureIndex };
|
|
930
|
+
if (coordinatesIndex) {
|
|
931
|
+
textureInfo.texCoord = coordinatesIndex;
|
|
990
932
|
}
|
|
991
933
|
return textureInfo;
|
|
992
934
|
}
|
|
935
|
+
_exportTextureSampler(texture) {
|
|
936
|
+
const sampler = this._getTextureSampler(texture);
|
|
937
|
+
// if a pre-existing sampler with identical parameters exists, then reuse the previous sampler
|
|
938
|
+
const samplers = this._exporter._samplers;
|
|
939
|
+
const samplerIndex = samplers.findIndex((s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT);
|
|
940
|
+
if (samplerIndex !== -1) {
|
|
941
|
+
return samplerIndex;
|
|
942
|
+
}
|
|
943
|
+
samplers.push(sampler);
|
|
944
|
+
return samplers.length - 1;
|
|
945
|
+
}
|
|
993
946
|
}
|
|
994
947
|
/**
|
|
995
948
|
* Represents the dielectric specular values for R, G and B
|