@babylonjs/serializers 8.23.1 → 8.24.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.
@@ -1 +1 @@
1
- {"version":3,"file":"glTFExporterExtension.js","sourceRoot":"","sources":["../../../../../dev/serializers/src/glTF/2.0/glTFExporterExtension.ts"],"names":[],"mappings":"AAYA,gBAAgB;AAChB,wEAAwE;AACxE,MAAM,CAAC,IAAI,0BAA0B,GAAG,CAAC,CAAC,CAAC,uCAAuC","sourcesContent":["import type { ImageMimeType, IMeshPrimitive, INode, IMaterial, ITextureInfo, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { IDisposable } from \"core/scene\";\r\n\r\nimport type { IGLTFExporterExtension } from \"../glTFFileExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for a glTF exporter extension\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtensionV2 extends IGLTFExporterExtension, IDisposable {\r\n /**\r\n * Define this method to modify the default behavior before exporting a texture\r\n * @param context The context when loading the asset\r\n * @param babylonTexture The Babylon.js texture\r\n * @param mimeType The mime-type of the generated image\r\n * @returns A promise that resolves with the exported texture\r\n */\r\n preExportTextureAsync?(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Promise<Nullable<Texture>>;\r\n\r\n /**\r\n * Define this method to get notified when a texture info is created\r\n * @param context The context when loading the asset\r\n * @param textureInfo The glTF texture info\r\n * @param babylonTexture The Babylon.js texture\r\n */\r\n postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void;\r\n\r\n /**\r\n * Define this method to get notified when a primitive is created\r\n * @param primitive glTF mesh primitive\r\n * @param bufferManager Buffer manager\r\n * @param accessors List of glTF accessors\r\n */\r\n postExportMeshPrimitive?(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Current node mapping of babylon node to glTF node index. Useful for combining nodes together.\r\n * @param convertToRightHanded Flag indicating whether to convert values to right-handed\r\n * @param bufferManager Buffer manager\r\n * @returns nullable INode promise\r\n */\r\n postExportNodeAsync?(\r\n context: string,\r\n node: INode,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>>;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns nullable IMaterial promise\r\n */\r\n postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial>;\r\n\r\n /**\r\n * Define this method to return additional textures to export from a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns List of textures\r\n */\r\n postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[];\r\n\r\n /**\r\n * Define this method to modify the glTF buffer data before it is finalized and written\r\n * @param bufferManager Buffer manager\r\n */\r\n preGenerateBinaryAsync?(bufferManager: BufferManager): Promise<void>;\r\n\r\n /** Gets a boolean indicating that this extension was used */\r\n wasUsed: boolean;\r\n\r\n /** Gets a boolean indicating that this extension is required for the file to work */\r\n required: boolean;\r\n\r\n /**\r\n * Called after the exporter state changes to EXPORTING\r\n */\r\n onExporting?(): void;\r\n}\r\n"]}
1
+ {"version":3,"file":"glTFExporterExtension.js","sourceRoot":"","sources":["../../../../../dev/serializers/src/glTF/2.0/glTFExporterExtension.ts"],"names":[],"mappings":"AAWA,gBAAgB;AAChB,wEAAwE;AACxE,MAAM,CAAC,IAAI,0BAA0B,GAAG,CAAC,CAAC,CAAC,uCAAuC","sourcesContent":["import type { IMeshPrimitive, INode, IMaterial, ITextureInfo, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nimport type { IDisposable } from \"core/scene\";\r\n\r\nimport type { IGLTFExporterExtension } from \"../glTFFileExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for a glTF exporter extension\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtensionV2 extends IGLTFExporterExtension, IDisposable {\r\n /**\r\n * Define this method to get notified when a texture info is created\r\n * @param context The context when loading the asset\r\n * @param textureInfo The glTF texture info\r\n * @param babylonTexture The Babylon.js texture\r\n */\r\n postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void;\r\n\r\n /**\r\n * Define this method to get notified when a primitive is created\r\n * @param primitive glTF mesh primitive\r\n * @param bufferManager Buffer manager\r\n * @param accessors List of glTF accessors\r\n */\r\n postExportMeshPrimitive?(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Current node mapping of babylon node to glTF node index. Useful for combining nodes together.\r\n * @param convertToRightHanded Flag indicating whether to convert values to right-handed\r\n * @param bufferManager Buffer manager\r\n * @returns nullable INode promise\r\n */\r\n postExportNodeAsync?(\r\n context: string,\r\n node: INode,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>>;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns nullable IMaterial promise\r\n */\r\n postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial>;\r\n\r\n /**\r\n * Define this method to return additional textures to export from a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns List of textures\r\n */\r\n postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[];\r\n\r\n /**\r\n * Define this method to modify the glTF buffer data before it is finalized and written\r\n * @param bufferManager Buffer manager\r\n */\r\n preGenerateBinaryAsync?(bufferManager: BufferManager): Promise<void>;\r\n\r\n /** Gets a boolean indicating that this extension was used */\r\n wasUsed: boolean;\r\n\r\n /** Gets a boolean indicating that this extension is required for the file to work */\r\n required: boolean;\r\n\r\n /**\r\n * Called after the exporter state changes to EXPORTING\r\n */\r\n onExporting?(): void;\r\n}\r\n"]}
@@ -1,5 +1,4 @@
1
1
  import type { ITextureInfo, IMaterialPbrMetallicRoughness } from "babylonjs-gltf2interface";
2
- import { ImageMimeType } from "babylonjs-gltf2interface";
3
2
  import type { Nullable } from "@babylonjs/core/types.js";
4
3
  import type { BaseTexture } from "@babylonjs/core/Materials/Textures/baseTexture.js";
5
4
  import type { GLTFExporter } from "./glTFExporter.js";
@@ -29,7 +28,7 @@ export declare class GLTFMaterialExporter {
29
28
  private _internalTextureToImage;
30
29
  constructor(_exporter: GLTFExporter);
31
30
  getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo>;
32
- exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number>;
31
+ exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, hasUVs: boolean): Promise<number>;
33
32
  private _finishMaterialAsync;
34
33
  private _getImageDataAsync;
35
34
  /**
@@ -72,7 +71,6 @@ export declare class GLTFMaterialExporter {
72
71
  /**
73
72
  * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors
74
73
  * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
75
- * @param mimeType mime type to use for the textures
76
74
  * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface
77
75
  * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
78
76
  * @returns glTF PBR Metallic Roughness factors
@@ -83,16 +81,15 @@ export declare class GLTFMaterialExporter {
83
81
  /**
84
82
  * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors
85
83
  * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
86
- * @param mimeType mime type to use for the textures
87
84
  * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface
88
85
  * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
89
86
  * @returns glTF PBR Metallic Roughness factors
90
87
  */
91
88
  private _convertSpecGlossFactorsToMetallicRoughnessAsync;
92
- exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number>;
89
+ exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, hasUVs: boolean): Promise<number>;
93
90
  private _setMetallicRoughnessPbrMaterialAsync;
94
- exportTextureAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise<Nullable<ITextureInfo>>;
95
- private _exportTextureInfoAsync;
91
+ exportTextureAsync(babylonTexture: BaseTexture): Promise<Nullable<ITextureInfo>>;
92
+ private _exportTextureImageAsync;
96
93
  private _exportImage;
97
94
  private _exportTextureInfo;
98
95
  private _exportTextureSampler;
@@ -10,6 +10,7 @@ import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
10
10
  import { Constants } from "@babylonjs/core/Engines/constants.js";
11
11
  import { DumpTools } from "@babylonjs/core/Misc/dumpTools.js";
12
12
  import { SpecularPowerToRoughness } from "@babylonjs/core/Helpers/materialConversionHelper.js";
13
+ import { GetMimeType } from "@babylonjs/core/Misc/fileTools.js";
13
14
  const Epsilon = 1e-6;
14
15
  const DielectricSpecular = new Color3(0.04, 0.04, 0.04);
15
16
  const MaxSpecularPower = 1024;
@@ -27,6 +28,49 @@ function GetFileExtensionFromMimeType(mimeType) {
27
28
  return ".avif";
28
29
  }
29
30
  }
31
+ /**
32
+ * Gets cached image from a texture, if available.
33
+ * @param babylonTexture texture to check for cached image
34
+ * @returns image data if found and directly usable; null otherwise
35
+ */
36
+ async function GetCachedImageAsync(babylonTexture) {
37
+ const internalTexture = babylonTexture.getInternalTexture();
38
+ if (!internalTexture || internalTexture.source !== 1 /* InternalTextureSource.Url */) {
39
+ return null;
40
+ }
41
+ if (internalTexture.invertY) {
42
+ return null;
43
+ }
44
+ const buffer = internalTexture._buffer;
45
+ let data;
46
+ let mimeType = babylonTexture.mimeType;
47
+ if (!buffer) {
48
+ data = await Tools.LoadFileAsync(internalTexture.url);
49
+ mimeType = GetMimeType(internalTexture.url) || mimeType;
50
+ }
51
+ else if (typeof buffer === "string") {
52
+ data = await Tools.LoadFileAsync(buffer);
53
+ mimeType = GetMimeType(buffer) || mimeType;
54
+ }
55
+ else if (buffer instanceof HTMLImageElement) {
56
+ data = await Tools.LoadFileAsync(buffer.src);
57
+ mimeType = GetMimeType(buffer.src) || mimeType;
58
+ }
59
+ else if (buffer instanceof Blob) {
60
+ data = await buffer.arrayBuffer();
61
+ mimeType = buffer.type || mimeType;
62
+ }
63
+ else if (ArrayBuffer.isView(buffer)) {
64
+ data = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
65
+ }
66
+ else if (buffer instanceof ArrayBuffer) {
67
+ data = buffer;
68
+ }
69
+ if (data && mimeType) {
70
+ return { data, mimeType };
71
+ }
72
+ return null;
73
+ }
30
74
  /**
31
75
  * Computes the metallic factor from specular glossiness values.
32
76
  * @param diffuse diffused value
@@ -115,7 +159,7 @@ export class GLTFMaterialExporter {
115
159
  getTextureInfo(babylonTexture) {
116
160
  return babylonTexture ? (this._textureMap.get(babylonTexture) ?? null) : null;
117
161
  }
118
- async exportStandardMaterialAsync(babylonStandardMaterial, mimeType, hasUVs) {
162
+ async exportStandardMaterialAsync(babylonStandardMaterial, hasUVs) {
119
163
  const pbrMetallicRoughness = _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
120
164
  const material = { name: babylonStandardMaterial.name };
121
165
  if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
@@ -128,7 +172,7 @@ export class GLTFMaterialExporter {
128
172
  const promises = [];
129
173
  const diffuseTexture = babylonStandardMaterial.diffuseTexture;
130
174
  if (diffuseTexture) {
131
- promises.push(this.exportTextureAsync(diffuseTexture, mimeType).then((textureInfo) => {
175
+ promises.push(this.exportTextureAsync(diffuseTexture).then((textureInfo) => {
132
176
  if (textureInfo) {
133
177
  pbrMetallicRoughness.baseColorTexture = textureInfo;
134
178
  }
@@ -136,7 +180,7 @@ export class GLTFMaterialExporter {
136
180
  }
137
181
  const bumpTexture = babylonStandardMaterial.bumpTexture;
138
182
  if (bumpTexture) {
139
- promises.push(this.exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {
183
+ promises.push(this.exportTextureAsync(bumpTexture).then((textureInfo) => {
140
184
  if (textureInfo) {
141
185
  material.normalTexture = textureInfo;
142
186
  if (bumpTexture.level !== 1) {
@@ -148,7 +192,7 @@ export class GLTFMaterialExporter {
148
192
  const emissiveTexture = babylonStandardMaterial.emissiveTexture;
149
193
  if (emissiveTexture) {
150
194
  material.emissiveFactor = [1.0, 1.0, 1.0];
151
- promises.push(this.exportTextureAsync(emissiveTexture, mimeType).then((textureInfo) => {
195
+ promises.push(this.exportTextureAsync(emissiveTexture).then((textureInfo) => {
152
196
  if (textureInfo) {
153
197
  material.emissiveTexture = textureInfo;
154
198
  }
@@ -156,7 +200,7 @@ export class GLTFMaterialExporter {
156
200
  }
157
201
  const ambientTexture = babylonStandardMaterial.ambientTexture;
158
202
  if (ambientTexture) {
159
- promises.push(this.exportTextureAsync(ambientTexture, mimeType).then((textureInfo) => {
203
+ promises.push(this.exportTextureAsync(ambientTexture).then((textureInfo) => {
160
204
  if (textureInfo) {
161
205
  const occlusionTexture = {
162
206
  index: textureInfo.index,
@@ -183,16 +227,16 @@ export class GLTFMaterialExporter {
183
227
  }
184
228
  material.pbrMetallicRoughness = pbrMetallicRoughness;
185
229
  SetAlphaMode(material, babylonStandardMaterial);
186
- await this._finishMaterialAsync(material, babylonStandardMaterial, mimeType);
230
+ await this._finishMaterialAsync(material, babylonStandardMaterial);
187
231
  const materials = this._exporter._materials;
188
232
  materials.push(material);
189
233
  return materials.length - 1;
190
234
  }
191
- async _finishMaterialAsync(glTFMaterial, babylonMaterial, mimeType) {
235
+ async _finishMaterialAsync(glTFMaterial, babylonMaterial) {
192
236
  const textures = this._exporter._extensionsPostExportMaterialAdditionalTextures("exportMaterial", glTFMaterial, babylonMaterial);
193
237
  const promises = [];
194
238
  for (const texture of textures) {
195
- promises.push(this.exportTextureAsync(texture, mimeType));
239
+ promises.push(this.exportTextureAsync(texture));
196
240
  }
197
241
  await Promise.all(promises);
198
242
  await this._exporter._extensionsPostExportMaterialAsync("exportMaterial", glTFMaterial, babylonMaterial);
@@ -408,12 +452,11 @@ export class GLTFMaterialExporter {
408
452
  /**
409
453
  * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors
410
454
  * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
411
- * @param mimeType mime type to use for the textures
412
455
  * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface
413
456
  * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
414
457
  * @returns glTF PBR Metallic Roughness factors
415
458
  */
416
- async _convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs) {
459
+ async _convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs) {
417
460
  const promises = [];
418
461
  const metallicRoughness = {
419
462
  baseColor: babylonPBRMaterial._albedoColor,
@@ -423,7 +466,7 @@ export class GLTFMaterialExporter {
423
466
  if (hasUVs) {
424
467
  const albedoTexture = babylonPBRMaterial._albedoTexture;
425
468
  if (albedoTexture) {
426
- promises.push(this.exportTextureAsync(babylonPBRMaterial._albedoTexture, mimeType).then((glTFTexture) => {
469
+ promises.push(this.exportTextureAsync(albedoTexture).then((glTFTexture) => {
427
470
  if (glTFTexture) {
428
471
  glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
429
472
  }
@@ -431,7 +474,7 @@ export class GLTFMaterialExporter {
431
474
  }
432
475
  const metallicTexture = babylonPBRMaterial._metallicTexture;
433
476
  if (metallicTexture) {
434
- promises.push(this.exportTextureAsync(metallicTexture, mimeType).then((glTFTexture) => {
477
+ promises.push(this.exportTextureAsync(metallicTexture).then((glTFTexture) => {
435
478
  if (glTFTexture) {
436
479
  glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
437
480
  }
@@ -541,12 +584,12 @@ export class GLTFMaterialExporter {
541
584
  /**
542
585
  * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors
543
586
  * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
544
- * @param mimeType mime type to use for the textures
545
587
  * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface
546
588
  * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
547
589
  * @returns glTF PBR Metallic Roughness factors
548
590
  */
549
- async _convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, pbrMetallicRoughness, hasUVs) {
591
+ async _convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, pbrMetallicRoughness, hasUVs) {
592
+ const mimeType = "image/png" /* ImageMimeType.PNG */;
550
593
  const specGloss = {
551
594
  diffuseColor: babylonPBRMaterial._albedoColor,
552
595
  specularColor: babylonPBRMaterial._reflectivityColor,
@@ -577,7 +620,7 @@ export class GLTFMaterialExporter {
577
620
  return this._convertSpecularGlossinessToMetallicRoughness(specGloss);
578
621
  }
579
622
  }
580
- async exportPBRMaterialAsync(babylonPBRMaterial, mimeType, hasUVs) {
623
+ async exportPBRMaterialAsync(babylonPBRMaterial, hasUVs) {
581
624
  const glTFPbrMetallicRoughness = {};
582
625
  const glTFMaterial = {
583
626
  name: babylonPBRMaterial.name,
@@ -591,15 +634,15 @@ export class GLTFMaterialExporter {
591
634
  }
592
635
  }
593
636
  const metallicRoughness = useMetallicRoughness
594
- ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs)
595
- : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs);
596
- await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs);
597
- await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial, mimeType);
637
+ ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs)
638
+ : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs);
639
+ await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);
640
+ await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial);
598
641
  const materials = this._exporter._materials;
599
642
  materials.push(glTFMaterial);
600
643
  return materials.length - 1;
601
644
  }
602
- async _setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs) {
645
+ async _setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs) {
603
646
  SetAlphaMode(glTFMaterial, babylonPBRMaterial);
604
647
  if (!metallicRoughness.baseColor.equalsWithEpsilon(White, Epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, Epsilon)) {
605
648
  glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];
@@ -620,7 +663,7 @@ export class GLTFMaterialExporter {
620
663
  const promises = [];
621
664
  const bumpTexture = babylonPBRMaterial._bumpTexture;
622
665
  if (bumpTexture) {
623
- promises.push(this.exportTextureAsync(bumpTexture, mimeType).then((glTFTexture) => {
666
+ promises.push(this.exportTextureAsync(bumpTexture).then((glTFTexture) => {
624
667
  if (glTFTexture) {
625
668
  glTFMaterial.normalTexture = glTFTexture;
626
669
  if (bumpTexture.level !== 1) {
@@ -631,7 +674,7 @@ export class GLTFMaterialExporter {
631
674
  }
632
675
  const ambientTexture = babylonPBRMaterial._ambientTexture;
633
676
  if (ambientTexture) {
634
- promises.push(this.exportTextureAsync(ambientTexture, mimeType).then((glTFTexture) => {
677
+ promises.push(this.exportTextureAsync(ambientTexture).then((glTFTexture) => {
635
678
  if (glTFTexture) {
636
679
  const occlusionTexture = {
637
680
  index: glTFTexture.index,
@@ -648,7 +691,7 @@ export class GLTFMaterialExporter {
648
691
  }
649
692
  const emissiveTexture = babylonPBRMaterial._emissiveTexture;
650
693
  if (emissiveTexture) {
651
- promises.push(this.exportTextureAsync(emissiveTexture, mimeType).then((glTFTexture) => {
694
+ promises.push(this.exportTextureAsync(emissiveTexture).then((glTFTexture) => {
652
695
  if (glTFTexture) {
653
696
  glTFMaterial.emissiveTexture = glTFTexture;
654
697
  }
@@ -665,58 +708,55 @@ export class GLTFMaterialExporter {
665
708
  }
666
709
  glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
667
710
  }
668
- async exportTextureAsync(babylonTexture, mimeType) {
669
- const extensionPromise = this._exporter._extensionsPreExportTextureAsync("exporter", babylonTexture, mimeType);
670
- if (!extensionPromise) {
671
- return await this._exportTextureInfoAsync(babylonTexture, mimeType);
672
- }
673
- return await extensionPromise.then(async (texture) => {
674
- if (!texture) {
675
- return await this._exportTextureInfoAsync(babylonTexture, mimeType);
676
- }
677
- return await this._exportTextureInfoAsync(texture, mimeType);
678
- });
679
- }
680
- async _exportTextureInfoAsync(babylonTexture, mimeType) {
711
+ async exportTextureAsync(babylonTexture) {
681
712
  let textureInfo = this._textureMap.get(babylonTexture);
682
- if (!textureInfo) {
683
- const pixels = await GetTextureDataAsync(babylonTexture).catch(() => null);
684
- if (!pixels) {
685
- return null;
686
- }
687
- const samplerIndex = this._exportTextureSampler(babylonTexture);
688
- // Preserve texture mime type if defined
689
- const textureMimeType = babylonTexture.mimeType;
690
- if (textureMimeType) {
691
- switch (textureMimeType) {
692
- case "image/jpeg":
693
- case "image/png":
694
- case "image/webp":
695
- mimeType = textureMimeType;
696
- break;
697
- default:
698
- Tools.Warn(`Unsupported media type: ${textureMimeType}. Exporting texture as PNG.`);
699
- // Will later fallback to default mime type, image/png, from Canvas API
700
- break;
713
+ if (textureInfo) {
714
+ return textureInfo;
715
+ }
716
+ const samplerIndex = this._exportTextureSampler(babylonTexture);
717
+ const imageIndex = await this._exportTextureImageAsync(babylonTexture);
718
+ textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, babylonTexture.coordinatesIndex);
719
+ this._textureMap.set(babylonTexture, textureInfo);
720
+ this._exporter._extensionsPostExportTextures("exporter", textureInfo, babylonTexture);
721
+ return textureInfo;
722
+ }
723
+ async _exportTextureImageAsync(babylonTexture) {
724
+ const requestedMimeType = babylonTexture.mimeType ?? "none";
725
+ // TODO: Add an official way for users to export using a different mime type
726
+ // than the one they loaded with (which is denoted by Texture.mimeType)
727
+ const internalTextureToImage = this._internalTextureToImage;
728
+ const internalTextureUniqueId = babylonTexture.getInternalTexture().uniqueId;
729
+ internalTextureToImage[internalTextureUniqueId] = internalTextureToImage[internalTextureUniqueId] || {};
730
+ let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][requestedMimeType];
731
+ if (imageIndexPromise === undefined) {
732
+ imageIndexPromise = (async () => {
733
+ // Try to get the image from memory first, if applicable
734
+ const cache = await GetCachedImageAsync(babylonTexture);
735
+ if (cache && (requestedMimeType === "none" || cache.mimeType === requestedMimeType)) {
736
+ return this._exportImage(babylonTexture.name, cache.mimeType, cache.data);
737
+ }
738
+ // Preserve texture mime type if defined
739
+ let mimeType = "image/png" /* ImageMimeType.PNG */;
740
+ if (requestedMimeType !== "none") {
741
+ switch (requestedMimeType) {
742
+ case "image/jpeg" /* ImageMimeType.JPEG */:
743
+ case "image/png" /* ImageMimeType.PNG */:
744
+ case "image/webp" /* ImageMimeType.WEBP */:
745
+ mimeType = requestedMimeType;
746
+ break;
747
+ default:
748
+ Tools.Warn(`Unsupported media type: ${requestedMimeType}. Exporting texture as PNG.`);
749
+ break;
750
+ }
701
751
  }
702
- }
703
- const internalTextureToImage = this._internalTextureToImage;
704
- const internalTextureUniqueId = babylonTexture.getInternalTexture().uniqueId;
705
- internalTextureToImage[internalTextureUniqueId] || (internalTextureToImage[internalTextureUniqueId] = {});
706
- let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][mimeType];
707
- if (imageIndexPromise === undefined) {
708
752
  const size = babylonTexture.getSize();
709
- imageIndexPromise = (async () => {
710
- const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);
711
- return this._exportImage(babylonTexture.name, mimeType, data);
712
- })();
713
- internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndexPromise;
714
- }
715
- textureInfo = this._exportTextureInfo(await imageIndexPromise, samplerIndex, babylonTexture.coordinatesIndex);
716
- this._textureMap.set(babylonTexture, textureInfo);
717
- this._exporter._extensionsPostExportTextures("exporter", textureInfo, babylonTexture);
753
+ const pixels = await GetTextureDataAsync(babylonTexture);
754
+ const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);
755
+ return this._exportImage(babylonTexture.name, mimeType, data);
756
+ })();
757
+ internalTextureToImage[internalTextureUniqueId][requestedMimeType] = imageIndexPromise;
718
758
  }
719
- return textureInfo;
759
+ return await imageIndexPromise;
720
760
  }
721
761
  _exportImage(name, mimeType, data) {
722
762
  const images = this._exporter._images;