@babylonjs/serializers 8.34.1 → 8.35.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.
|
@@ -8,7 +8,7 @@ import { GetTextureDataAsync, TextureTools } from "@babylonjs/core/Misc/textureT
|
|
|
8
8
|
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
|
|
9
9
|
import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
|
|
10
10
|
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
|
11
|
-
import {
|
|
11
|
+
import { EncodeImageAsync } from "@babylonjs/core/Misc/dumpTools.js";
|
|
12
12
|
import { PBRBaseMaterial } from "@babylonjs/core/Materials/PBR/pbrBaseMaterial.js";
|
|
13
13
|
import { SpecularPowerToRoughness } from "@babylonjs/core/Helpers/materialConversionHelper.js";
|
|
14
14
|
import { GetMimeType } from "@babylonjs/core/Misc/fileTools.js";
|
|
@@ -33,6 +33,22 @@ function GetFileExtensionFromMimeType(mimeType) {
|
|
|
33
33
|
return ".ktx2";
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* @param mimeType the MIME type requested by the user
|
|
38
|
+
* @returns true if the given mime type is compatible with glTF
|
|
39
|
+
*/
|
|
40
|
+
function IsSupportedMimeType(mimeType) {
|
|
41
|
+
switch (mimeType) {
|
|
42
|
+
case "image/jpeg" /* ImageMimeType.JPEG */:
|
|
43
|
+
case "image/png" /* ImageMimeType.PNG */:
|
|
44
|
+
case "image/webp" /* ImageMimeType.WEBP */:
|
|
45
|
+
case "image/avif" /* ImageMimeType.AVIF */:
|
|
46
|
+
case "image/ktx2" /* ImageMimeType.KTX2 */:
|
|
47
|
+
return true;
|
|
48
|
+
default:
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
36
52
|
/**
|
|
37
53
|
* Gets cached image from a texture, if available.
|
|
38
54
|
* @param babylonTexture texture to check for cached image
|
|
@@ -71,8 +87,8 @@ async function GetCachedImageAsync(babylonTexture) {
|
|
|
71
87
|
data = await Tools.LoadFileAsync(buffer.src);
|
|
72
88
|
mimeType = GetMimeType(buffer.src) || mimeType;
|
|
73
89
|
}
|
|
74
|
-
if (data && mimeType) {
|
|
75
|
-
return
|
|
90
|
+
if (data && IsSupportedMimeType(mimeType)) {
|
|
91
|
+
return new Blob([data], { type: mimeType });
|
|
76
92
|
}
|
|
77
93
|
return null;
|
|
78
94
|
}
|
|
@@ -245,9 +261,6 @@ export class GLTFMaterialExporter {
|
|
|
245
261
|
await Promise.all(promises);
|
|
246
262
|
await this._exporter._extensionsPostExportMaterialAsync("exportMaterial", glTFMaterial, babylonMaterial);
|
|
247
263
|
}
|
|
248
|
-
async _getImageDataAsync(buffer, width, height, mimeType) {
|
|
249
|
-
return await DumpTools.DumpDataAsync(width, height, buffer, mimeType, undefined, false, true);
|
|
250
|
-
}
|
|
251
264
|
/**
|
|
252
265
|
* Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null
|
|
253
266
|
* @param texture1 first texture to resize
|
|
@@ -294,10 +307,9 @@ export class GLTFMaterialExporter {
|
|
|
294
307
|
* @param diffuseTexture texture used to store diffuse information
|
|
295
308
|
* @param specularGlossinessTexture texture used to store specular and glossiness information
|
|
296
309
|
* @param factors specular glossiness material factors
|
|
297
|
-
* @param mimeType the mime type to use for the texture
|
|
298
310
|
* @returns pbr metallic roughness interface or null
|
|
299
311
|
*/
|
|
300
|
-
async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(diffuseTexture, specularGlossinessTexture, factors
|
|
312
|
+
async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(diffuseTexture, specularGlossinessTexture, factors) {
|
|
301
313
|
const promises = new Array();
|
|
302
314
|
if (!(diffuseTexture || specularGlossinessTexture)) {
|
|
303
315
|
return await Promise.reject("diffuse and specular glossiness textures are not defined!");
|
|
@@ -393,12 +405,12 @@ export class GLTFMaterialExporter {
|
|
|
393
405
|
}
|
|
394
406
|
}
|
|
395
407
|
if (writeOutMetallicRoughnessTexture) {
|
|
396
|
-
promises.push(
|
|
408
|
+
promises.push(EncodeImageAsync(metallicRoughnessBuffer, width, height).then((data) => {
|
|
397
409
|
metallicRoughnessFactors.metallicRoughnessTextureData = data;
|
|
398
410
|
}));
|
|
399
411
|
}
|
|
400
412
|
if (writeOutBaseColorTexture) {
|
|
401
|
-
promises.push(
|
|
413
|
+
promises.push(EncodeImageAsync(baseColorBuffer, width, height).then((data) => {
|
|
402
414
|
metallicRoughnessFactors.baseColorTextureData = data;
|
|
403
415
|
}));
|
|
404
416
|
}
|
|
@@ -648,7 +660,6 @@ export class GLTFMaterialExporter {
|
|
|
648
660
|
* @returns glTF PBR Metallic Roughness factors
|
|
649
661
|
*/
|
|
650
662
|
async _convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, pbrMetallicRoughness, hasUVs) {
|
|
651
|
-
const mimeType = "image/png" /* ImageMimeType.PNG */;
|
|
652
663
|
const specGloss = {
|
|
653
664
|
diffuseColor: babylonPBRMaterial._albedoColor,
|
|
654
665
|
specularColor: babylonPBRMaterial._reflectivityColor,
|
|
@@ -663,14 +674,14 @@ export class GLTFMaterialExporter {
|
|
|
663
674
|
if ((albedoTexture || reflectivityTexture) && hasUVs) {
|
|
664
675
|
this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);
|
|
665
676
|
const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);
|
|
666
|
-
const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss
|
|
677
|
+
const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss);
|
|
667
678
|
const textures = this._exporter._textures;
|
|
668
679
|
if (metallicRoughnessFactors.baseColorTextureData) {
|
|
669
|
-
const imageIndex = this.
|
|
680
|
+
const imageIndex = await this._exportImageAsync(`baseColor${textures.length}`, metallicRoughnessFactors.baseColorTextureData);
|
|
670
681
|
pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);
|
|
671
682
|
}
|
|
672
683
|
if (metallicRoughnessFactors.metallicRoughnessTextureData) {
|
|
673
|
-
const imageIndex = this.
|
|
684
|
+
const imageIndex = await this._exportImageAsync(`metallicRoughness${textures.length}`, metallicRoughnessFactors.metallicRoughnessTextureData);
|
|
674
685
|
pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);
|
|
675
686
|
}
|
|
676
687
|
return metallicRoughnessFactors;
|
|
@@ -824,48 +835,46 @@ export class GLTFMaterialExporter {
|
|
|
824
835
|
imageIndexPromise = (async () => {
|
|
825
836
|
// Try to get the image from memory first, if applicable
|
|
826
837
|
const cache = await GetCachedImageAsync(babylonTexture);
|
|
827
|
-
if (cache && (requestedMimeType === "none" || cache.
|
|
828
|
-
return this.
|
|
838
|
+
if (cache && (requestedMimeType === "none" || cache.type === requestedMimeType)) {
|
|
839
|
+
return await this._exportImageAsync(babylonTexture.name, cache);
|
|
829
840
|
}
|
|
830
841
|
// Preserve texture mime type if defined
|
|
831
842
|
let mimeType = "image/png" /* ImageMimeType.PNG */;
|
|
832
843
|
if (requestedMimeType !== "none") {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
default:
|
|
840
|
-
Tools.Warn(`Unsupported media type: ${requestedMimeType}. Exporting texture as PNG.`);
|
|
841
|
-
break;
|
|
844
|
+
if (IsSupportedMimeType(requestedMimeType)) {
|
|
845
|
+
mimeType = requestedMimeType;
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
mimeType = "image/png" /* ImageMimeType.PNG */;
|
|
849
|
+
Tools.Warn(`Unsupported media type: ${requestedMimeType}. Exporting texture as PNG.`);
|
|
842
850
|
}
|
|
843
851
|
}
|
|
844
852
|
const size = babylonTexture.getSize();
|
|
845
853
|
const pixels = await GetTextureDataAsync(babylonTexture);
|
|
846
|
-
const
|
|
847
|
-
return this.
|
|
854
|
+
const imageData = await EncodeImageAsync(pixels, size.width, size.height, mimeType);
|
|
855
|
+
return await this._exportImageAsync(babylonTexture.name, imageData);
|
|
848
856
|
})();
|
|
849
857
|
internalTextureToImage[internalTextureUniqueId][requestedMimeType] = imageIndexPromise;
|
|
850
858
|
}
|
|
851
859
|
return await imageIndexPromise;
|
|
852
860
|
}
|
|
853
|
-
|
|
861
|
+
async _exportImageAsync(name, imageData) {
|
|
854
862
|
const images = this._exporter._images;
|
|
855
863
|
let image;
|
|
856
864
|
if (this._exporter._shouldUseGlb) {
|
|
857
865
|
image = {
|
|
858
866
|
name: name,
|
|
859
|
-
mimeType:
|
|
867
|
+
mimeType: imageData.type,
|
|
860
868
|
bufferView: undefined, // Will be updated later by BufferManager
|
|
861
869
|
};
|
|
870
|
+
const data = await imageData.arrayBuffer();
|
|
862
871
|
const bufferView = this._exporter._bufferManager.createBufferView(new Uint8Array(data));
|
|
863
872
|
this._exporter._bufferManager.setBufferView(image, bufferView);
|
|
864
873
|
}
|
|
865
874
|
else {
|
|
866
875
|
// Build a unique URI
|
|
867
876
|
const baseName = name.replace(/\.\/|\/|\.\\|\\/g, "_");
|
|
868
|
-
const extension = GetFileExtensionFromMimeType(
|
|
877
|
+
const extension = GetFileExtensionFromMimeType(imageData.type);
|
|
869
878
|
let fileName = baseName + extension;
|
|
870
879
|
if (images.some((image) => image.uri === fileName)) {
|
|
871
880
|
fileName = `${baseName}_${Tools.RandomId()}${extension}`;
|
|
@@ -874,7 +883,7 @@ export class GLTFMaterialExporter {
|
|
|
874
883
|
name: name,
|
|
875
884
|
uri: fileName,
|
|
876
885
|
};
|
|
877
|
-
this._exporter._imageData[fileName] =
|
|
886
|
+
this._exporter._imageData[fileName] = imageData; // Save image data to be written to file later
|
|
878
887
|
}
|
|
879
888
|
images.push(image);
|
|
880
889
|
return images.length - 1;
|