@babylonjs/loaders 7.37.0 → 7.37.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.
@@ -24,11 +24,11 @@ export class KHR_materials_variants {
24
24
  }
25
25
  /**
26
26
  * Gets the list of available variant names for this asset.
27
- * @param rootMesh The glTF root mesh
27
+ * @param rootNode The glTF root node
28
28
  * @returns the list of all the variant names for this model
29
29
  */
30
- static GetAvailableVariants(rootMesh) {
31
- const extensionMetadata = this._GetExtensionMetadata(rootMesh);
30
+ static GetAvailableVariants(rootNode) {
31
+ const extensionMetadata = this._GetExtensionMetadata(rootNode);
32
32
  if (!extensionMetadata) {
33
33
  return [];
34
34
  }
@@ -36,19 +36,19 @@ export class KHR_materials_variants {
36
36
  }
37
37
  /**
38
38
  * Gets the list of available variant names for this asset.
39
- * @param rootMesh The glTF root mesh
39
+ * @param rootNode The glTF root node
40
40
  * @returns the list of all the variant names for this model
41
41
  */
42
- getAvailableVariants(rootMesh) {
43
- return KHR_materials_variants.GetAvailableVariants(rootMesh);
42
+ getAvailableVariants(rootNode) {
43
+ return KHR_materials_variants.GetAvailableVariants(rootNode);
44
44
  }
45
45
  /**
46
46
  * Select a variant given a variant name or a list of variant names.
47
- * @param rootMesh The glTF root mesh
47
+ * @param rootNode The glTF root node
48
48
  * @param variantName The variant name(s) to select.
49
49
  */
50
- static SelectVariant(rootMesh, variantName) {
51
- const extensionMetadata = this._GetExtensionMetadata(rootMesh);
50
+ static SelectVariant(rootNode, variantName) {
51
+ const extensionMetadata = this._GetExtensionMetadata(rootNode);
52
52
  if (!extensionMetadata) {
53
53
  throw new Error(`Cannot select variant on a glTF mesh that does not have the ${NAME} extension`);
54
54
  }
@@ -72,18 +72,18 @@ export class KHR_materials_variants {
72
72
  }
73
73
  /**
74
74
  * Select a variant given a variant name or a list of variant names.
75
- * @param rootMesh The glTF root mesh
75
+ * @param rootNode The glTF root node
76
76
  * @param variantName The variant name(s) to select.
77
77
  */
78
- selectVariant(rootMesh, variantName) {
79
- KHR_materials_variants.SelectVariant(rootMesh, variantName);
78
+ selectVariant(rootNode, variantName) {
79
+ KHR_materials_variants.SelectVariant(rootNode, variantName);
80
80
  }
81
81
  /**
82
82
  * Reset back to the original before selecting a variant.
83
- * @param rootMesh The glTF root mesh
83
+ * @param rootNode The glTF root node
84
84
  */
85
- static Reset(rootMesh) {
86
- const extensionMetadata = this._GetExtensionMetadata(rootMesh);
85
+ static Reset(rootNode) {
86
+ const extensionMetadata = this._GetExtensionMetadata(rootNode);
87
87
  if (!extensionMetadata) {
88
88
  throw new Error(`Cannot reset on a glTF mesh that does not have the ${NAME} extension`);
89
89
  }
@@ -94,18 +94,18 @@ export class KHR_materials_variants {
94
94
  }
95
95
  /**
96
96
  * Reset back to the original before selecting a variant.
97
- * @param rootMesh The glTF root mesh
97
+ * @param rootNode The glTF root node
98
98
  */
99
- reset(rootMesh) {
100
- KHR_materials_variants.Reset(rootMesh);
99
+ reset(rootNode) {
100
+ KHR_materials_variants.Reset(rootNode);
101
101
  }
102
102
  /**
103
103
  * Gets the last selected variant name(s) or null if original.
104
- * @param rootMesh The glTF root mesh
104
+ * @param rootNode The glTF root node
105
105
  * @returns The selected variant name(s).
106
106
  */
107
- static GetLastSelectedVariant(rootMesh) {
108
- const extensionMetadata = this._GetExtensionMetadata(rootMesh);
107
+ static GetLastSelectedVariant(rootNode) {
108
+ const extensionMetadata = this._GetExtensionMetadata(rootNode);
109
109
  if (!extensionMetadata) {
110
110
  throw new Error(`Cannot get the last selected variant on a glTF mesh that does not have the ${NAME} extension`);
111
111
  }
@@ -113,14 +113,14 @@ export class KHR_materials_variants {
113
113
  }
114
114
  /**
115
115
  * Gets the last selected variant name(s) or null if original.
116
- * @param rootMesh The glTF root mesh
116
+ * @param rootNode The glTF root node
117
117
  * @returns The selected variant name(s).
118
118
  */
119
- getLastSelectedVariant(rootMesh) {
120
- return KHR_materials_variants.GetLastSelectedVariant(rootMesh);
119
+ getLastSelectedVariant(rootNode) {
120
+ return KHR_materials_variants.GetLastSelectedVariant(rootNode);
121
121
  }
122
- static _GetExtensionMetadata(rootMesh) {
123
- return rootMesh?._internalMetadata?.gltf?.[NAME] || null;
122
+ static _GetExtensionMetadata(rootNode) {
123
+ return rootNode?._internalMetadata?.gltf?.[NAME] || null;
124
124
  }
125
125
  /** @internal */
126
126
  onLoading() {
@@ -130,6 +130,30 @@ export class KHR_materials_variants {
130
130
  this._variants = extension.variants;
131
131
  }
132
132
  }
133
+ /** @internal */
134
+ onReady() {
135
+ const rootNode = this._loader.rootBabylonMesh;
136
+ if (rootNode) {
137
+ this._loader.parent.extensionOptions[NAME]?.onLoaded?.({
138
+ get variants() {
139
+ return KHR_materials_variants.GetAvailableVariants(rootNode);
140
+ },
141
+ get selectedVariant() {
142
+ const lastSelectedVariant = KHR_materials_variants.GetLastSelectedVariant(rootNode);
143
+ if (!lastSelectedVariant) {
144
+ return KHR_materials_variants.GetAvailableVariants(rootNode)[0];
145
+ }
146
+ if (Array.isArray(lastSelectedVariant)) {
147
+ return lastSelectedVariant[0];
148
+ }
149
+ return lastSelectedVariant;
150
+ },
151
+ set selectedVariant(variantName) {
152
+ KHR_materials_variants.SelectVariant(rootNode, variantName);
153
+ },
154
+ });
155
+ }
156
+ }
133
157
  /**
134
158
  * @internal
135
159
  */
@@ -1 +1 @@
1
- {"version":3,"file":"KHR_materials_variants.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport type { IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { GLTFLoader, ArrayItem } from \"../glTFLoader\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport type { Node } from \"core/node\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { INode, IMeshPrimitive, IMesh } from \"../glTFLoaderInterfaces\";\r\nimport type { IKHRMaterialVariants_Mapping, IKHRMaterialVariants_Variant, IKHRMaterialVariants_Variants } from \"babylonjs-gltf2interface\";\r\nimport type { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { registerGLTFExtension, unregisterGLTFExtension } from \"../glTFLoaderExtensionRegistry\";\r\n\r\nconst NAME = \"KHR_materials_variants\";\r\n\r\ndeclare module \"../../glTFFileLoader\" {\r\n // eslint-disable-next-line jsdoc/require-jsdoc\r\n export interface GLTFLoaderExtensionOptions {\r\n /**\r\n * Defines options for the KHR_materials_variants extension.\r\n */\r\n // NOTE: Don't use NAME here as it will break the UMD type declarations.\r\n [\"KHR_materials_variants\"]: {};\r\n }\r\n}\r\n\r\ninterface IVariantsMap {\r\n [key: string]: Array<{ mesh: AbstractMesh; material: Nullable<Material> }>;\r\n}\r\n\r\ninterface IExtensionMetadata {\r\n lastSelected: Nullable<string | Array<string>>;\r\n original: Array<{ mesh: AbstractMesh; material: Nullable<Material> }>;\r\n variants: IVariantsMap;\r\n}\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_variants implements IGLTFLoaderExtension {\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public enabled: boolean;\r\n\r\n private _loader: GLTFLoader;\r\n\r\n private _variants?: Array<IKHRMaterialVariants_Variant>;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n this.enabled = this._loader.isExtensionUsed(NAME);\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._loader as any) = null;\r\n }\r\n\r\n /**\r\n * Gets the list of available variant names for this asset.\r\n * @param rootMesh The glTF root mesh\r\n * @returns the list of all the variant names for this model\r\n */\r\n public static GetAvailableVariants(rootMesh: Mesh): string[] {\r\n const extensionMetadata = this._GetExtensionMetadata(rootMesh);\r\n if (!extensionMetadata) {\r\n return [];\r\n }\r\n\r\n return Object.keys(extensionMetadata.variants);\r\n }\r\n\r\n /**\r\n * Gets the list of available variant names for this asset.\r\n * @param rootMesh The glTF root mesh\r\n * @returns the list of all the variant names for this model\r\n */\r\n public getAvailableVariants(rootMesh: Mesh): string[] {\r\n return KHR_materials_variants.GetAvailableVariants(rootMesh);\r\n }\r\n\r\n /**\r\n * Select a variant given a variant name or a list of variant names.\r\n * @param rootMesh The glTF root mesh\r\n * @param variantName The variant name(s) to select.\r\n */\r\n public static SelectVariant(rootMesh: Mesh, variantName: string | string[]): void {\r\n const extensionMetadata = this._GetExtensionMetadata(rootMesh);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot select variant on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n const select = (variantName: string): void => {\r\n const entries = extensionMetadata.variants[variantName];\r\n if (entries) {\r\n for (const entry of entries) {\r\n entry.mesh.material = entry.material;\r\n }\r\n }\r\n };\r\n\r\n if (variantName instanceof Array) {\r\n for (const name of variantName) {\r\n select(name);\r\n }\r\n } else {\r\n select(variantName);\r\n }\r\n\r\n extensionMetadata.lastSelected = variantName;\r\n }\r\n\r\n /**\r\n * Select a variant given a variant name or a list of variant names.\r\n * @param rootMesh The glTF root mesh\r\n * @param variantName The variant name(s) to select.\r\n */\r\n public selectVariant(rootMesh: Mesh, variantName: string | string[]): void {\r\n KHR_materials_variants.SelectVariant(rootMesh, variantName);\r\n }\r\n\r\n /**\r\n * Reset back to the original before selecting a variant.\r\n * @param rootMesh The glTF root mesh\r\n */\r\n public static Reset(rootMesh: Mesh): void {\r\n const extensionMetadata = this._GetExtensionMetadata(rootMesh);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot reset on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n for (const entry of extensionMetadata.original) {\r\n entry.mesh.material = entry.material;\r\n }\r\n\r\n extensionMetadata.lastSelected = null;\r\n }\r\n\r\n /**\r\n * Reset back to the original before selecting a variant.\r\n * @param rootMesh The glTF root mesh\r\n */\r\n public reset(rootMesh: Mesh): void {\r\n KHR_materials_variants.Reset(rootMesh);\r\n }\r\n\r\n /**\r\n * Gets the last selected variant name(s) or null if original.\r\n * @param rootMesh The glTF root mesh\r\n * @returns The selected variant name(s).\r\n */\r\n public static GetLastSelectedVariant(rootMesh: Mesh): Nullable<string | string[]> {\r\n const extensionMetadata = this._GetExtensionMetadata(rootMesh);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot get the last selected variant on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n return extensionMetadata.lastSelected;\r\n }\r\n\r\n /**\r\n * Gets the last selected variant name(s) or null if original.\r\n * @param rootMesh The glTF root mesh\r\n * @returns The selected variant name(s).\r\n */\r\n public getLastSelectedVariant(rootMesh: Mesh): Nullable<string | string[]> {\r\n return KHR_materials_variants.GetLastSelectedVariant(rootMesh);\r\n }\r\n\r\n private static _GetExtensionMetadata(rootMesh: Nullable<TransformNode>): Nullable<IExtensionMetadata> {\r\n return rootMesh?._internalMetadata?.gltf?.[NAME] || null;\r\n }\r\n\r\n /** @internal */\r\n public onLoading(): void {\r\n const extensions = this._loader.gltf.extensions;\r\n if (extensions && extensions[this.name]) {\r\n const extension = extensions[this.name] as IKHRMaterialVariants_Variants;\r\n this._variants = extension.variants;\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _loadMeshPrimitiveAsync(\r\n context: string,\r\n name: string,\r\n node: INode,\r\n mesh: IMesh,\r\n primitive: IMeshPrimitive,\r\n assign: (babylonMesh: AbstractMesh) => void\r\n ): Nullable<Promise<AbstractMesh>> {\r\n return GLTFLoader.LoadExtensionAsync<IKHRMaterialVariants_Mapping, AbstractMesh>(context, primitive, this.name, (extensionContext, extension) => {\r\n const promises = new Array<Promise<any>>();\r\n promises.push(\r\n this._loader._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, (babylonMesh) => {\r\n assign(babylonMesh);\r\n\r\n if (babylonMesh instanceof Mesh) {\r\n const babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);\r\n\r\n const root = this._loader.rootBabylonMesh;\r\n const metadata = root ? (root._internalMetadata = root._internalMetadata || {}) : {};\r\n const gltf = (metadata.gltf = metadata.gltf || {});\r\n const extensionMetadata: IExtensionMetadata = (gltf[NAME] = gltf[NAME] || { lastSelected: null, original: [], variants: {} });\r\n\r\n // Store the original material.\r\n extensionMetadata.original.push({ mesh: babylonMesh, material: babylonMesh.material });\r\n\r\n // For each mapping, look at the variants and make a new entry for them.\r\n for (let mappingIndex = 0; mappingIndex < extension.mappings.length; ++mappingIndex) {\r\n const mapping = extension.mappings[mappingIndex];\r\n const material = ArrayItem.Get(`${extensionContext}/mappings/${mappingIndex}/material`, this._loader.gltf.materials, mapping.material);\r\n promises.push(\r\n this._loader._loadMaterialAsync(`#/materials/${mapping.material}`, material, babylonMesh, babylonDrawMode, (babylonMaterial) => {\r\n for (let mappingVariantIndex = 0; mappingVariantIndex < mapping.variants.length; ++mappingVariantIndex) {\r\n const variantIndex = mapping.variants[mappingVariantIndex];\r\n const variant = ArrayItem.Get(`/extensions/${NAME}/variants/${variantIndex}`, this._variants, variantIndex);\r\n extensionMetadata.variants[variant.name] = extensionMetadata.variants[variant.name] || [];\r\n extensionMetadata.variants[variant.name].push({\r\n mesh: babylonMesh,\r\n material: babylonMaterial,\r\n });\r\n\r\n // Replace the target when original mesh is cloned\r\n babylonMesh.onClonedObservable.add((newOne: Node) => {\r\n const newMesh = newOne as Mesh;\r\n let metadata: Nullable<IExtensionMetadata> = null;\r\n let newRoot: Nullable<Node> = newMesh;\r\n\r\n // Find root to get medata\r\n do {\r\n newRoot = newRoot!.parent;\r\n if (!newRoot) {\r\n return;\r\n }\r\n metadata = KHR_materials_variants._GetExtensionMetadata(newRoot as Mesh);\r\n } while (metadata === null);\r\n\r\n // Need to clone the metadata on the root (first time only)\r\n if (root && metadata === KHR_materials_variants._GetExtensionMetadata(root)) {\r\n // Copy main metadata\r\n newRoot._internalMetadata = {};\r\n for (const key in root._internalMetadata) {\r\n newRoot._internalMetadata[key] = root._internalMetadata[key];\r\n }\r\n\r\n // Copy the gltf metadata\r\n newRoot._internalMetadata.gltf = [];\r\n for (const key in root._internalMetadata.gltf) {\r\n newRoot._internalMetadata.gltf[key] = root._internalMetadata.gltf[key];\r\n }\r\n\r\n // Duplicate the extension specific metadata\r\n newRoot._internalMetadata.gltf[NAME] = { lastSelected: null, original: [], variants: {} };\r\n for (const original of metadata.original) {\r\n newRoot._internalMetadata.gltf[NAME].original.push({\r\n mesh: original.mesh,\r\n material: original.material,\r\n });\r\n }\r\n for (const key in metadata.variants) {\r\n if (Object.prototype.hasOwnProperty.call(metadata.variants, key)) {\r\n newRoot._internalMetadata.gltf[NAME].variants[key] = [];\r\n for (const variantEntry of metadata.variants[key]) {\r\n newRoot._internalMetadata.gltf[NAME].variants[key].push({\r\n mesh: variantEntry.mesh,\r\n material: variantEntry.material,\r\n });\r\n }\r\n }\r\n }\r\n\r\n metadata = newRoot._internalMetadata.gltf[NAME];\r\n }\r\n\r\n // Relocate\r\n for (const target of metadata!.original) {\r\n if (target.mesh === babylonMesh) {\r\n target.mesh = newMesh;\r\n }\r\n }\r\n for (const target of metadata!.variants[variant.name]) {\r\n if (target.mesh === babylonMesh) {\r\n target.mesh = newMesh;\r\n }\r\n }\r\n });\r\n }\r\n })\r\n );\r\n }\r\n }\r\n })\r\n );\r\n return Promise.all(promises).then(([babylonMesh]) => {\r\n return babylonMesh;\r\n });\r\n });\r\n }\r\n}\r\n\r\nunregisterGLTFExtension(NAME);\r\nregisterGLTFExtension(NAME, true, (loader) => new KHR_materials_variants(loader));\r\n"]}
1
+ {"version":3,"file":"KHR_materials_variants.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport type { IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { GLTFLoader, ArrayItem } from \"../glTFLoader\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport type { Node } from \"core/node\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { INode, IMeshPrimitive, IMesh } from \"../glTFLoaderInterfaces\";\r\nimport type { IKHRMaterialVariants_Mapping, IKHRMaterialVariants_Variant, IKHRMaterialVariants_Variants } from \"babylonjs-gltf2interface\";\r\nimport type { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { registerGLTFExtension, unregisterGLTFExtension } from \"../glTFLoaderExtensionRegistry\";\r\nimport type { MaterialVariantsController } from \"../../glTFFileLoader\";\r\n\r\nconst NAME = \"KHR_materials_variants\";\r\n\r\nexport { MaterialVariantsController };\r\n\r\ndeclare module \"../../glTFFileLoader\" {\r\n // Define options related types here so they can be referenced in the options,\r\n // but export the types at the module level. This ensures the types are in the\r\n // correct namespace for UMD.\r\n type MaterialVariantsController = {\r\n /**\r\n * The list of available variant names for this asset.\r\n */\r\n readonly variants: readonly string[];\r\n\r\n /**\r\n * Gets or sets the selected variant.\r\n */\r\n selectedVariant: string;\r\n };\r\n\r\n // eslint-disable-next-line jsdoc/require-jsdoc\r\n export interface GLTFLoaderExtensionOptions {\r\n /**\r\n * Defines options for the KHR_materials_variants extension.\r\n */\r\n // NOTE: Don't use NAME here as it will break the UMD type declarations.\r\n [\"KHR_materials_variants\"]: Partial<{\r\n /**\r\n * Defines a callback that will be called if material variants are loaded.\r\n * @experimental\r\n */\r\n onLoaded: (controller: MaterialVariantsController) => void;\r\n }>;\r\n }\r\n}\r\n\r\ninterface IVariantsMap {\r\n [key: string]: Array<{ mesh: AbstractMesh; material: Nullable<Material> }>;\r\n}\r\n\r\ninterface IExtensionMetadata {\r\n lastSelected: Nullable<string | Array<string>>;\r\n original: Array<{ mesh: AbstractMesh; material: Nullable<Material> }>;\r\n variants: IVariantsMap;\r\n}\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_variants implements IGLTFLoaderExtension {\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public enabled: boolean;\r\n\r\n private _loader: GLTFLoader;\r\n\r\n private _variants?: Array<IKHRMaterialVariants_Variant>;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n this.enabled = this._loader.isExtensionUsed(NAME);\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._loader as any) = null;\r\n }\r\n\r\n /**\r\n * Gets the list of available variant names for this asset.\r\n * @param rootNode The glTF root node\r\n * @returns the list of all the variant names for this model\r\n */\r\n public static GetAvailableVariants(rootNode: TransformNode): string[] {\r\n const extensionMetadata = this._GetExtensionMetadata(rootNode);\r\n if (!extensionMetadata) {\r\n return [];\r\n }\r\n\r\n return Object.keys(extensionMetadata.variants);\r\n }\r\n\r\n /**\r\n * Gets the list of available variant names for this asset.\r\n * @param rootNode The glTF root node\r\n * @returns the list of all the variant names for this model\r\n */\r\n public getAvailableVariants(rootNode: TransformNode): string[] {\r\n return KHR_materials_variants.GetAvailableVariants(rootNode);\r\n }\r\n\r\n /**\r\n * Select a variant given a variant name or a list of variant names.\r\n * @param rootNode The glTF root node\r\n * @param variantName The variant name(s) to select.\r\n */\r\n public static SelectVariant(rootNode: TransformNode, variantName: string | string[]): void {\r\n const extensionMetadata = this._GetExtensionMetadata(rootNode);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot select variant on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n const select = (variantName: string): void => {\r\n const entries = extensionMetadata.variants[variantName];\r\n if (entries) {\r\n for (const entry of entries) {\r\n entry.mesh.material = entry.material;\r\n }\r\n }\r\n };\r\n\r\n if (variantName instanceof Array) {\r\n for (const name of variantName) {\r\n select(name);\r\n }\r\n } else {\r\n select(variantName);\r\n }\r\n\r\n extensionMetadata.lastSelected = variantName;\r\n }\r\n\r\n /**\r\n * Select a variant given a variant name or a list of variant names.\r\n * @param rootNode The glTF root node\r\n * @param variantName The variant name(s) to select.\r\n */\r\n public selectVariant(rootNode: TransformNode, variantName: string | string[]): void {\r\n KHR_materials_variants.SelectVariant(rootNode, variantName);\r\n }\r\n\r\n /**\r\n * Reset back to the original before selecting a variant.\r\n * @param rootNode The glTF root node\r\n */\r\n public static Reset(rootNode: TransformNode): void {\r\n const extensionMetadata = this._GetExtensionMetadata(rootNode);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot reset on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n for (const entry of extensionMetadata.original) {\r\n entry.mesh.material = entry.material;\r\n }\r\n\r\n extensionMetadata.lastSelected = null;\r\n }\r\n\r\n /**\r\n * Reset back to the original before selecting a variant.\r\n * @param rootNode The glTF root node\r\n */\r\n public reset(rootNode: TransformNode): void {\r\n KHR_materials_variants.Reset(rootNode);\r\n }\r\n\r\n /**\r\n * Gets the last selected variant name(s) or null if original.\r\n * @param rootNode The glTF root node\r\n * @returns The selected variant name(s).\r\n */\r\n public static GetLastSelectedVariant(rootNode: TransformNode): Nullable<string | string[]> {\r\n const extensionMetadata = this._GetExtensionMetadata(rootNode);\r\n if (!extensionMetadata) {\r\n throw new Error(`Cannot get the last selected variant on a glTF mesh that does not have the ${NAME} extension`);\r\n }\r\n\r\n return extensionMetadata.lastSelected;\r\n }\r\n\r\n /**\r\n * Gets the last selected variant name(s) or null if original.\r\n * @param rootNode The glTF root node\r\n * @returns The selected variant name(s).\r\n */\r\n public getLastSelectedVariant(rootNode: TransformNode): Nullable<string | string[]> {\r\n return KHR_materials_variants.GetLastSelectedVariant(rootNode);\r\n }\r\n\r\n private static _GetExtensionMetadata(rootNode: Nullable<TransformNode>): Nullable<IExtensionMetadata> {\r\n return rootNode?._internalMetadata?.gltf?.[NAME] || null;\r\n }\r\n\r\n /** @internal */\r\n public onLoading(): void {\r\n const extensions = this._loader.gltf.extensions;\r\n if (extensions && extensions[this.name]) {\r\n const extension = extensions[this.name] as IKHRMaterialVariants_Variants;\r\n this._variants = extension.variants;\r\n }\r\n }\r\n\r\n /** @internal */\r\n public onReady(): void {\r\n const rootNode = this._loader.rootBabylonMesh;\r\n if (rootNode) {\r\n this._loader.parent.extensionOptions[NAME]?.onLoaded?.({\r\n get variants() {\r\n return KHR_materials_variants.GetAvailableVariants(rootNode);\r\n },\r\n get selectedVariant(): string {\r\n const lastSelectedVariant = KHR_materials_variants.GetLastSelectedVariant(rootNode);\r\n if (!lastSelectedVariant) {\r\n return KHR_materials_variants.GetAvailableVariants(rootNode)[0];\r\n }\r\n if (Array.isArray(lastSelectedVariant)) {\r\n return lastSelectedVariant[0];\r\n }\r\n return lastSelectedVariant;\r\n },\r\n set selectedVariant(variantName) {\r\n KHR_materials_variants.SelectVariant(rootNode, variantName);\r\n },\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _loadMeshPrimitiveAsync(\r\n context: string,\r\n name: string,\r\n node: INode,\r\n mesh: IMesh,\r\n primitive: IMeshPrimitive,\r\n assign: (babylonMesh: AbstractMesh) => void\r\n ): Nullable<Promise<AbstractMesh>> {\r\n return GLTFLoader.LoadExtensionAsync<IKHRMaterialVariants_Mapping, AbstractMesh>(context, primitive, this.name, (extensionContext, extension) => {\r\n const promises = new Array<Promise<any>>();\r\n promises.push(\r\n this._loader._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, (babylonMesh) => {\r\n assign(babylonMesh);\r\n\r\n if (babylonMesh instanceof Mesh) {\r\n const babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);\r\n\r\n const root = this._loader.rootBabylonMesh;\r\n const metadata = root ? (root._internalMetadata = root._internalMetadata || {}) : {};\r\n const gltf = (metadata.gltf = metadata.gltf || {});\r\n const extensionMetadata: IExtensionMetadata = (gltf[NAME] = gltf[NAME] || { lastSelected: null, original: [], variants: {} });\r\n\r\n // Store the original material.\r\n extensionMetadata.original.push({ mesh: babylonMesh, material: babylonMesh.material });\r\n\r\n // For each mapping, look at the variants and make a new entry for them.\r\n for (let mappingIndex = 0; mappingIndex < extension.mappings.length; ++mappingIndex) {\r\n const mapping = extension.mappings[mappingIndex];\r\n const material = ArrayItem.Get(`${extensionContext}/mappings/${mappingIndex}/material`, this._loader.gltf.materials, mapping.material);\r\n promises.push(\r\n this._loader._loadMaterialAsync(`#/materials/${mapping.material}`, material, babylonMesh, babylonDrawMode, (babylonMaterial) => {\r\n for (let mappingVariantIndex = 0; mappingVariantIndex < mapping.variants.length; ++mappingVariantIndex) {\r\n const variantIndex = mapping.variants[mappingVariantIndex];\r\n const variant = ArrayItem.Get(`/extensions/${NAME}/variants/${variantIndex}`, this._variants, variantIndex);\r\n extensionMetadata.variants[variant.name] = extensionMetadata.variants[variant.name] || [];\r\n extensionMetadata.variants[variant.name].push({\r\n mesh: babylonMesh,\r\n material: babylonMaterial,\r\n });\r\n\r\n // Replace the target when original mesh is cloned\r\n babylonMesh.onClonedObservable.add((newOne: Node) => {\r\n const newMesh = newOne as Mesh;\r\n let metadata: Nullable<IExtensionMetadata> = null;\r\n let newRoot: Nullable<Node> = newMesh;\r\n\r\n // Find root to get medata\r\n do {\r\n newRoot = newRoot!.parent;\r\n if (!newRoot) {\r\n return;\r\n }\r\n metadata = KHR_materials_variants._GetExtensionMetadata(newRoot as Mesh);\r\n } while (metadata === null);\r\n\r\n // Need to clone the metadata on the root (first time only)\r\n if (root && metadata === KHR_materials_variants._GetExtensionMetadata(root)) {\r\n // Copy main metadata\r\n newRoot._internalMetadata = {};\r\n for (const key in root._internalMetadata) {\r\n newRoot._internalMetadata[key] = root._internalMetadata[key];\r\n }\r\n\r\n // Copy the gltf metadata\r\n newRoot._internalMetadata.gltf = [];\r\n for (const key in root._internalMetadata.gltf) {\r\n newRoot._internalMetadata.gltf[key] = root._internalMetadata.gltf[key];\r\n }\r\n\r\n // Duplicate the extension specific metadata\r\n newRoot._internalMetadata.gltf[NAME] = { lastSelected: null, original: [], variants: {} };\r\n for (const original of metadata.original) {\r\n newRoot._internalMetadata.gltf[NAME].original.push({\r\n mesh: original.mesh,\r\n material: original.material,\r\n });\r\n }\r\n for (const key in metadata.variants) {\r\n if (Object.prototype.hasOwnProperty.call(metadata.variants, key)) {\r\n newRoot._internalMetadata.gltf[NAME].variants[key] = [];\r\n for (const variantEntry of metadata.variants[key]) {\r\n newRoot._internalMetadata.gltf[NAME].variants[key].push({\r\n mesh: variantEntry.mesh,\r\n material: variantEntry.material,\r\n });\r\n }\r\n }\r\n }\r\n\r\n metadata = newRoot._internalMetadata.gltf[NAME];\r\n }\r\n\r\n // Relocate\r\n for (const target of metadata!.original) {\r\n if (target.mesh === babylonMesh) {\r\n target.mesh = newMesh;\r\n }\r\n }\r\n for (const target of metadata!.variants[variant.name]) {\r\n if (target.mesh === babylonMesh) {\r\n target.mesh = newMesh;\r\n }\r\n }\r\n });\r\n }\r\n })\r\n );\r\n }\r\n }\r\n })\r\n );\r\n return Promise.all(promises).then(([babylonMesh]) => {\r\n return babylonMesh;\r\n });\r\n });\r\n }\r\n}\r\n\r\nunregisterGLTFExtension(NAME);\r\nregisterGLTFExtension(NAME, true, (loader) => new KHR_materials_variants(loader));\r\n"]}
@@ -22,27 +22,8 @@ import { Logger } from "@babylonjs/core/Misc/logger.js";
22
22
  import { BoundingInfo } from "@babylonjs/core/Culling/boundingInfo.js";
23
23
  import { nodeAnimationData } from "./glTFLoaderAnimation.js";
24
24
  import { registeredGLTFExtensions, registerGLTFExtension, unregisterGLTFExtension } from "./glTFLoaderExtensionRegistry.js";
25
+ import { deepMerge } from "@babylonjs/core/Misc/deepMerger.js";
25
26
  export { GLTFFileLoader };
26
- // https://stackoverflow.com/a/48218209
27
- function mergeDeep(...objects) {
28
- const isObject = (obj) => obj && typeof obj === "object";
29
- return objects.reduce((prev, obj) => {
30
- Object.keys(obj).forEach((key) => {
31
- const pVal = prev[key];
32
- const oVal = obj[key];
33
- if (Array.isArray(pVal) && Array.isArray(oVal)) {
34
- prev[key] = pVal.concat(...oVal);
35
- }
36
- else if (isObject(pVal) && isObject(oVal)) {
37
- prev[key] = mergeDeep(pVal, oVal);
38
- }
39
- else {
40
- prev[key] = oVal;
41
- }
42
- });
43
- return prev;
44
- }, {});
45
- }
46
27
  /**
47
28
  * Helper class for working with arrays when loading the glTF asset
48
29
  */
@@ -678,7 +659,7 @@ export class GLTFLoader {
678
659
  promises.push(this._loadMeshAsync(`/meshes/${mesh.index}`, node, mesh, (babylonTransformNode) => {
679
660
  const babylonTransformNodeForSkin = node._babylonTransformNodeForSkin;
680
661
  // Merge the metadata from the skin node to the skinned mesh in case a loader extension added metadata.
681
- babylonTransformNode.metadata = mergeDeep(babylonTransformNodeForSkin.metadata, babylonTransformNode.metadata || {});
662
+ babylonTransformNode.metadata = deepMerge(babylonTransformNodeForSkin.metadata, babylonTransformNode.metadata || {});
682
663
  const skin = ArrayItem.Get(`${context}/skin`, this._gltf.skins, node.skin);
683
664
  promises.push(this._loadSkinAsync(`/skins/${skin.index}`, node, skin, (babylonSkeleton) => {
684
665
  this._forEachPrimitive(node, (babylonMesh) => {