| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 | 
							- import ForEach from "./ForEach.js";
 
- import forEachTextureInMaterial from "./forEachTextureInMaterial.js";
 
- import usesExtension from "./usesExtension.js";
 
- import defaultValue from "../../Core/defaultValue.js";
 
- import defined from "../../Core/defined.js";
 
- const allElementTypes = [
 
-   "mesh",
 
-   "node",
 
-   "material",
 
-   "accessor",
 
-   "bufferView",
 
-   "buffer",
 
-   "texture",
 
-   "sampler",
 
-   "image",
 
- ];
 
- /**
 
-  * Removes unused elements from gltf.
 
-  *
 
-  * @param {Object} gltf A javascript object containing a glTF asset.
 
-  * @param {String[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored.
 
-  *
 
-  * @private
 
-  */
 
- function removeUnusedElements(gltf, elementTypes) {
 
-   elementTypes = defaultValue(elementTypes, allElementTypes);
 
-   allElementTypes.forEach(function (type) {
 
-     if (elementTypes.indexOf(type) > -1) {
 
-       removeUnusedElementsByType(gltf, type);
 
-     }
 
-   });
 
-   return gltf;
 
- }
 
- const TypeToGltfElementName = {
 
-   accessor: "accessors",
 
-   buffer: "buffers",
 
-   bufferView: "bufferViews",
 
-   image: "images",
 
-   node: "nodes",
 
-   material: "materials",
 
-   mesh: "meshes",
 
-   sampler: "samplers",
 
-   texture: "textures",
 
- };
 
- function removeUnusedElementsByType(gltf, type) {
 
-   const name = TypeToGltfElementName[type];
 
-   const arrayOfObjects = gltf[name];
 
-   if (defined(arrayOfObjects)) {
 
-     let removed = 0;
 
-     const usedIds = getListOfElementsIdsInUse[type](gltf);
 
-     const length = arrayOfObjects.length;
 
-     for (let i = 0; i < length; ++i) {
 
-       if (!usedIds[i]) {
 
-         Remove[type](gltf, i - removed);
 
-         removed++;
 
-       }
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Contains functions for removing elements from a glTF hierarchy.
 
-  * Since top-level glTF elements are arrays, when something is removed, referring
 
-  * indices need to be updated.
 
-  * @constructor
 
-  *
 
-  * @private
 
-  */
 
- function Remove() {}
 
- Remove.accessor = function (gltf, accessorId) {
 
-   const accessors = gltf.accessors;
 
-   accessors.splice(accessorId, 1);
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       // Update accessor ids for the primitives.
 
-       ForEach.meshPrimitiveAttribute(
 
-         primitive,
 
-         function (attributeAccessorId, semantic) {
 
-           if (attributeAccessorId > accessorId) {
 
-             primitive.attributes[semantic]--;
 
-           }
 
-         }
 
-       );
 
-       // Update accessor ids for the targets.
 
-       ForEach.meshPrimitiveTarget(primitive, function (target) {
 
-         ForEach.meshPrimitiveTargetAttribute(
 
-           target,
 
-           function (attributeAccessorId, semantic) {
 
-             if (attributeAccessorId > accessorId) {
 
-               target[semantic]--;
 
-             }
 
-           }
 
-         );
 
-       });
 
-       const indices = primitive.indices;
 
-       if (defined(indices) && indices > accessorId) {
 
-         primitive.indices--;
 
-       }
 
-     });
 
-   });
 
-   ForEach.skin(gltf, function (skin) {
 
-     if (
 
-       defined(skin.inverseBindMatrices) &&
 
-       skin.inverseBindMatrices > accessorId
 
-     ) {
 
-       skin.inverseBindMatrices--;
 
-     }
 
-   });
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationSampler(animation, function (sampler) {
 
-       if (defined(sampler.input) && sampler.input > accessorId) {
 
-         sampler.input--;
 
-       }
 
-       if (defined(sampler.output) && sampler.output > accessorId) {
 
-         sampler.output--;
 
-       }
 
-     });
 
-   });
 
- };
 
- Remove.buffer = function (gltf, bufferId) {
 
-   const buffers = gltf.buffers;
 
-   buffers.splice(bufferId, 1);
 
-   ForEach.bufferView(gltf, function (bufferView) {
 
-     if (defined(bufferView.buffer) && bufferView.buffer > bufferId) {
 
-       bufferView.buffer--;
 
-     }
 
-     if (
 
-       defined(bufferView.extensions) &&
 
-       defined(bufferView.extensions.EXT_meshopt_compression)
 
-     ) {
 
-       bufferView.extensions.EXT_meshopt_compression.buffer--;
 
-     }
 
-   });
 
- };
 
- Remove.bufferView = function (gltf, bufferViewId) {
 
-   const bufferViews = gltf.bufferViews;
 
-   bufferViews.splice(bufferViewId, 1);
 
-   ForEach.accessor(gltf, function (accessor) {
 
-     if (defined(accessor.bufferView) && accessor.bufferView > bufferViewId) {
 
-       accessor.bufferView--;
 
-     }
 
-   });
 
-   ForEach.shader(gltf, function (shader) {
 
-     if (defined(shader.bufferView) && shader.bufferView > bufferViewId) {
 
-       shader.bufferView--;
 
-     }
 
-   });
 
-   ForEach.image(gltf, function (image) {
 
-     if (defined(image.bufferView) && image.bufferView > bufferViewId) {
 
-       image.bufferView--;
 
-     }
 
-   });
 
-   if (usesExtension(gltf, "KHR_draco_mesh_compression")) {
 
-     ForEach.mesh(gltf, function (mesh) {
 
-       ForEach.meshPrimitive(mesh, function (primitive) {
 
-         if (
 
-           defined(primitive.extensions) &&
 
-           defined(primitive.extensions.KHR_draco_mesh_compression)
 
-         ) {
 
-           if (
 
-             primitive.extensions.KHR_draco_mesh_compression.bufferView >
 
-             bufferViewId
 
-           ) {
 
-             primitive.extensions.KHR_draco_mesh_compression.bufferView--;
 
-           }
 
-         }
 
-       });
 
-     });
 
-   }
 
-   if (usesExtension(gltf, "EXT_feature_metadata")) {
 
-     const extension = gltf.extensions.EXT_feature_metadata;
 
-     const featureTables = extension.featureTables;
 
-     for (const featureTableId in featureTables) {
 
-       if (featureTables.hasOwnProperty(featureTableId)) {
 
-         const featureTable = featureTables[featureTableId];
 
-         const properties = featureTable.properties;
 
-         if (defined(properties)) {
 
-           for (const propertyId in properties) {
 
-             if (properties.hasOwnProperty(propertyId)) {
 
-               const property = properties[propertyId];
 
-               if (
 
-                 defined(property.bufferView) &&
 
-                 property.bufferView > bufferViewId
 
-               ) {
 
-                 property.bufferView--;
 
-               }
 
-               if (
 
-                 defined(property.arrayOffsetBufferView) &&
 
-                 property.arrayOffsetBufferView > bufferViewId
 
-               ) {
 
-                 property.arrayOffsetBufferView--;
 
-               }
 
-               if (
 
-                 defined(property.stringOffsetBufferView) &&
 
-                 property.stringOffsetBufferView > bufferViewId
 
-               ) {
 
-                 property.stringOffsetBufferView--;
 
-               }
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
- };
 
- Remove.image = function (gltf, imageId) {
 
-   const images = gltf.images;
 
-   images.splice(imageId, 1);
 
-   ForEach.texture(gltf, function (texture) {
 
-     if (defined(texture.source)) {
 
-       if (texture.source > imageId) {
 
-         --texture.source;
 
-       }
 
-     }
 
-     const ext = texture.extensions;
 
-     if (
 
-       defined(ext) &&
 
-       defined(ext.EXT_texture_webp) &&
 
-       ext.EXT_texture_webp.source > imageId
 
-     ) {
 
-       --texture.extensions.EXT_texture_webp.source;
 
-     } else if (
 
-       defined(ext) &&
 
-       defined(ext.KHR_texture_basisu) &&
 
-       ext.KHR_texture_basisu.source > imageId
 
-     ) {
 
-       --texture.extensions.KHR_texture_basisu.source;
 
-     }
 
-   });
 
- };
 
- Remove.mesh = function (gltf, meshId) {
 
-   const meshes = gltf.meshes;
 
-   meshes.splice(meshId, 1);
 
-   ForEach.node(gltf, function (node) {
 
-     if (defined(node.mesh)) {
 
-       if (node.mesh > meshId) {
 
-         node.mesh--;
 
-       } else if (node.mesh === meshId) {
 
-         // Remove reference to deleted mesh
 
-         delete node.mesh;
 
-       }
 
-     }
 
-   });
 
- };
 
- Remove.node = function (gltf, nodeId) {
 
-   const nodes = gltf.nodes;
 
-   nodes.splice(nodeId, 1);
 
-   // Shift all node references
 
-   ForEach.skin(gltf, function (skin) {
 
-     if (defined(skin.skeleton) && skin.skeleton > nodeId) {
 
-       skin.skeleton--;
 
-     }
 
-     skin.joints = skin.joints.map(function (x) {
 
-       return x > nodeId ? x - 1 : x;
 
-     });
 
-   });
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationChannel(animation, function (channel) {
 
-       if (
 
-         defined(channel.target) &&
 
-         defined(channel.target.node) &&
 
-         channel.target.node > nodeId
 
-       ) {
 
-         channel.target.node--;
 
-       }
 
-     });
 
-   });
 
-   ForEach.technique(gltf, function (technique) {
 
-     ForEach.techniqueUniform(technique, function (uniform) {
 
-       if (defined(uniform.node) && uniform.node > nodeId) {
 
-         uniform.node--;
 
-       }
 
-     });
 
-   });
 
-   ForEach.node(gltf, function (node) {
 
-     if (!defined(node.children)) {
 
-       return;
 
-     }
 
-     node.children = node.children
 
-       .filter(function (x) {
 
-         return x !== nodeId; // Remove
 
-       })
 
-       .map(function (x) {
 
-         return x > nodeId ? x - 1 : x; // Shift indices
 
-       });
 
-   });
 
-   ForEach.scene(gltf, function (scene) {
 
-     scene.nodes = scene.nodes
 
-       .filter(function (x) {
 
-         return x !== nodeId; // Remove
 
-       })
 
-       .map(function (x) {
 
-         return x > nodeId ? x - 1 : x; // Shift indices
 
-       });
 
-   });
 
- };
 
- Remove.material = function (gltf, materialId) {
 
-   const materials = gltf.materials;
 
-   materials.splice(materialId, 1);
 
-   // Shift other material ids
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       if (defined(primitive.material) && primitive.material > materialId) {
 
-         primitive.material--;
 
-       }
 
-     });
 
-   });
 
- };
 
- Remove.sampler = function (gltf, samplerId) {
 
-   const samplers = gltf.samplers;
 
-   samplers.splice(samplerId, 1);
 
-   ForEach.texture(gltf, function (texture) {
 
-     if (defined(texture.sampler)) {
 
-       if (texture.sampler > samplerId) {
 
-         --texture.sampler;
 
-       }
 
-     }
 
-   });
 
- };
 
- Remove.texture = function (gltf, textureId) {
 
-   const textures = gltf.textures;
 
-   textures.splice(textureId, 1);
 
-   ForEach.material(gltf, function (material) {
 
-     forEachTextureInMaterial(material, function (textureIndex, textureInfo) {
 
-       if (textureInfo.index > textureId) {
 
-         --textureInfo.index;
 
-       }
 
-     });
 
-   });
 
-   if (usesExtension(gltf, "EXT_feature_metadata")) {
 
-     ForEach.mesh(gltf, function (mesh) {
 
-       ForEach.meshPrimitive(mesh, function (primitive) {
 
-         const extensions = primitive.extensions;
 
-         if (defined(extensions) && defined(extensions.EXT_feature_metadata)) {
 
-           const extension = extensions.EXT_feature_metadata;
 
-           const featureIdTextures = extension.featureIdTextures;
 
-           if (defined(featureIdTextures)) {
 
-             const featureIdTexturesLength = featureIdTextures.length;
 
-             for (let i = 0; i < featureIdTexturesLength; ++i) {
 
-               const featureIdTexture = featureIdTextures[i];
 
-               const textureInfo = featureIdTexture.featureIds.texture;
 
-               if (textureInfo.index > textureId) {
 
-                 --textureInfo.index;
 
-               }
 
-             }
 
-           }
 
-         }
 
-       });
 
-     });
 
-     const extension = gltf.extensions.EXT_feature_metadata;
 
-     const featureTextures = extension.featureTextures;
 
-     for (const featureTextureId in featureTextures) {
 
-       if (featureTextures.hasOwnProperty(featureTextureId)) {
 
-         const featureTexture = featureTextures[featureTextureId];
 
-         const properties = featureTexture.properties;
 
-         if (defined(properties)) {
 
-           for (const propertyId in properties) {
 
-             if (properties.hasOwnProperty(propertyId)) {
 
-               const property = properties[propertyId];
 
-               const textureInfo = property.texture;
 
-               if (textureInfo.index > textureId) {
 
-                 --textureInfo.index;
 
-               }
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
- };
 
- /**
 
-  * Contains functions for getting a list of element ids in use by the glTF asset.
 
-  * @constructor
 
-  *
 
-  * @private
 
-  */
 
- function getListOfElementsIdsInUse() {}
 
- getListOfElementsIdsInUse.accessor = function (gltf) {
 
-   // Calculate accessor's that are currently in use.
 
-   const usedAccessorIds = {};
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       ForEach.meshPrimitiveAttribute(primitive, function (accessorId) {
 
-         usedAccessorIds[accessorId] = true;
 
-       });
 
-       ForEach.meshPrimitiveTarget(primitive, function (target) {
 
-         ForEach.meshPrimitiveTargetAttribute(target, function (accessorId) {
 
-           usedAccessorIds[accessorId] = true;
 
-         });
 
-       });
 
-       const indices = primitive.indices;
 
-       if (defined(indices)) {
 
-         usedAccessorIds[indices] = true;
 
-       }
 
-     });
 
-   });
 
-   ForEach.skin(gltf, function (skin) {
 
-     if (defined(skin.inverseBindMatrices)) {
 
-       usedAccessorIds[skin.inverseBindMatrices] = true;
 
-     }
 
-   });
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationSampler(animation, function (sampler) {
 
-       if (defined(sampler.input)) {
 
-         usedAccessorIds[sampler.input] = true;
 
-       }
 
-       if (defined(sampler.output)) {
 
-         usedAccessorIds[sampler.output] = true;
 
-       }
 
-     });
 
-   });
 
-   if (usesExtension(gltf, "EXT_mesh_gpu_instancing")) {
 
-     ForEach.node(gltf, function (node) {
 
-       if (
 
-         defined(node.extensions) &&
 
-         defined(node.extensions.EXT_mesh_gpu_instancing)
 
-       ) {
 
-         Object.keys(node.extensions.EXT_mesh_gpu_instancing.attributes).forEach(
 
-           function (key) {
 
-             const attributeAccessorId =
 
-               node.extensions.EXT_mesh_gpu_instancing.attributes[key];
 
-             usedAccessorIds[attributeAccessorId] = true;
 
-           }
 
-         );
 
-       }
 
-     });
 
-   }
 
-   return usedAccessorIds;
 
- };
 
- getListOfElementsIdsInUse.buffer = function (gltf) {
 
-   // Calculate buffer's that are currently in use.
 
-   const usedBufferIds = {};
 
-   ForEach.bufferView(gltf, function (bufferView) {
 
-     if (defined(bufferView.buffer)) {
 
-       usedBufferIds[bufferView.buffer] = true;
 
-     }
 
-     if (
 
-       defined(bufferView.extensions) &&
 
-       defined(bufferView.extensions.EXT_meshopt_compression)
 
-     ) {
 
-       usedBufferIds[
 
-         bufferView.extensions.EXT_meshopt_compression.buffer
 
-       ] = true;
 
-     }
 
-   });
 
-   return usedBufferIds;
 
- };
 
- getListOfElementsIdsInUse.bufferView = function (gltf) {
 
-   // Calculate bufferView's that are currently in use.
 
-   const usedBufferViewIds = {};
 
-   ForEach.accessor(gltf, function (accessor) {
 
-     if (defined(accessor.bufferView)) {
 
-       usedBufferViewIds[accessor.bufferView] = true;
 
-     }
 
-   });
 
-   ForEach.shader(gltf, function (shader) {
 
-     if (defined(shader.bufferView)) {
 
-       usedBufferViewIds[shader.bufferView] = true;
 
-     }
 
-   });
 
-   ForEach.image(gltf, function (image) {
 
-     if (defined(image.bufferView)) {
 
-       usedBufferViewIds[image.bufferView] = true;
 
-     }
 
-   });
 
-   if (usesExtension(gltf, "KHR_draco_mesh_compression")) {
 
-     ForEach.mesh(gltf, function (mesh) {
 
-       ForEach.meshPrimitive(mesh, function (primitive) {
 
-         if (
 
-           defined(primitive.extensions) &&
 
-           defined(primitive.extensions.KHR_draco_mesh_compression)
 
-         ) {
 
-           usedBufferViewIds[
 
-             primitive.extensions.KHR_draco_mesh_compression.bufferView
 
-           ] = true;
 
-         }
 
-       });
 
-     });
 
-   }
 
-   if (usesExtension(gltf, "EXT_feature_metadata")) {
 
-     const extension = gltf.extensions.EXT_feature_metadata;
 
-     const featureTables = extension.featureTables;
 
-     for (const featureTableId in featureTables) {
 
-       if (featureTables.hasOwnProperty(featureTableId)) {
 
-         const featureTable = featureTables[featureTableId];
 
-         const properties = featureTable.properties;
 
-         if (defined(properties)) {
 
-           for (const propertyId in properties) {
 
-             if (properties.hasOwnProperty(propertyId)) {
 
-               const property = properties[propertyId];
 
-               if (defined(property.bufferView)) {
 
-                 usedBufferViewIds[property.bufferView] = true;
 
-               }
 
-               if (defined(property.arrayOffsetBufferView)) {
 
-                 usedBufferViewIds[property.arrayOffsetBufferView] = true;
 
-               }
 
-               if (defined(property.stringOffsetBufferView)) {
 
-                 usedBufferViewIds[property.stringOffsetBufferView] = true;
 
-               }
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
-   return usedBufferViewIds;
 
- };
 
- getListOfElementsIdsInUse.image = function (gltf) {
 
-   const usedImageIds = {};
 
-   ForEach.texture(gltf, function (texture) {
 
-     if (defined(texture.source)) {
 
-       usedImageIds[texture.source] = true;
 
-     }
 
-     if (
 
-       defined(texture.extensions) &&
 
-       defined(texture.extensions.EXT_texture_webp)
 
-     ) {
 
-       usedImageIds[texture.extensions.EXT_texture_webp.source] = true;
 
-     } else if (
 
-       defined(texture.extensions) &&
 
-       defined(texture.extensions.KHR_texture_basisu)
 
-     ) {
 
-       usedImageIds[texture.extensions.KHR_texture_basisu.source] = true;
 
-     }
 
-   });
 
-   return usedImageIds;
 
- };
 
- getListOfElementsIdsInUse.mesh = function (gltf) {
 
-   const usedMeshIds = {};
 
-   ForEach.node(gltf, function (node) {
 
-     if (defined(node.mesh && defined(gltf.meshes))) {
 
-       const mesh = gltf.meshes[node.mesh];
 
-       if (
 
-         defined(mesh) &&
 
-         defined(mesh.primitives) &&
 
-         mesh.primitives.length > 0
 
-       ) {
 
-         usedMeshIds[node.mesh] = true;
 
-       }
 
-     }
 
-   });
 
-   return usedMeshIds;
 
- };
 
- // Check if node is empty. It is considered empty if neither referencing
 
- // mesh, camera, extensions and has no children
 
- function nodeIsEmpty(gltf, nodeId, usedNodeIds) {
 
-   const node = gltf.nodes[nodeId];
 
-   if (
 
-     defined(node.mesh) ||
 
-     defined(node.camera) ||
 
-     defined(node.skin) ||
 
-     defined(node.weights) ||
 
-     defined(node.extras) ||
 
-     (defined(node.extensions) && Object.keys(node.extensions).length !== 0) ||
 
-     defined(usedNodeIds[nodeId])
 
-   ) {
 
-     return false;
 
-   }
 
-   // Empty if no children or children are all empty nodes
 
-   return (
 
-     !defined(node.children) ||
 
-     node.children.filter(function (n) {
 
-       return !nodeIsEmpty(gltf, n, usedNodeIds);
 
-     }).length === 0
 
-   );
 
- }
 
- getListOfElementsIdsInUse.node = function (gltf) {
 
-   const usedNodeIds = {};
 
-   ForEach.skin(gltf, function (skin) {
 
-     if (defined(skin.skeleton)) {
 
-       usedNodeIds[skin.skeleton] = true;
 
-     }
 
-     ForEach.skinJoint(skin, function (joint) {
 
-       usedNodeIds[joint] = true;
 
-     });
 
-   });
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationChannel(animation, function (channel) {
 
-       if (defined(channel.target) && defined(channel.target.node)) {
 
-         usedNodeIds[channel.target.node] = true;
 
-       }
 
-     });
 
-   });
 
-   ForEach.technique(gltf, function (technique) {
 
-     ForEach.techniqueUniform(technique, function (uniform) {
 
-       if (defined(uniform.node)) {
 
-         usedNodeIds[uniform.node] = true;
 
-       }
 
-     });
 
-   });
 
-   ForEach.node(gltf, function (node, nodeId) {
 
-     if (!nodeIsEmpty(gltf, nodeId, usedNodeIds)) {
 
-       usedNodeIds[nodeId] = true;
 
-     }
 
-   });
 
-   return usedNodeIds;
 
- };
 
- getListOfElementsIdsInUse.material = function (gltf) {
 
-   const usedMaterialIds = {};
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       if (defined(primitive.material)) {
 
-         usedMaterialIds[primitive.material] = true;
 
-       }
 
-     });
 
-   });
 
-   return usedMaterialIds;
 
- };
 
- getListOfElementsIdsInUse.texture = function (gltf) {
 
-   const usedTextureIds = {};
 
-   ForEach.material(gltf, function (material) {
 
-     forEachTextureInMaterial(material, function (textureId) {
 
-       usedTextureIds[textureId] = true;
 
-     });
 
-   });
 
-   if (usesExtension(gltf, "EXT_feature_metadata")) {
 
-     ForEach.mesh(gltf, function (mesh) {
 
-       ForEach.meshPrimitive(mesh, function (primitive) {
 
-         const extensions = primitive.extensions;
 
-         if (defined(extensions) && defined(extensions.EXT_feature_metadata)) {
 
-           const extension = extensions.EXT_feature_metadata;
 
-           const featureIdTextures = extension.featureIdTextures;
 
-           if (defined(featureIdTextures)) {
 
-             const featureIdTexturesLength = featureIdTextures.length;
 
-             for (let i = 0; i < featureIdTexturesLength; ++i) {
 
-               const featureIdTexture = featureIdTextures[i];
 
-               const textureInfo = featureIdTexture.featureIds.texture;
 
-               usedTextureIds[textureInfo.index] = true;
 
-             }
 
-           }
 
-         }
 
-       });
 
-     });
 
-     const extension = gltf.extensions.EXT_feature_metadata;
 
-     const featureTextures = extension.featureTextures;
 
-     for (const featureTextureId in featureTextures) {
 
-       if (featureTextures.hasOwnProperty(featureTextureId)) {
 
-         const featureTexture = featureTextures[featureTextureId];
 
-         const properties = featureTexture.properties;
 
-         if (defined(properties)) {
 
-           for (const propertyId in properties) {
 
-             if (properties.hasOwnProperty(propertyId)) {
 
-               const property = properties[propertyId];
 
-               const textureInfo = property.texture;
 
-               usedTextureIds[textureInfo.index] = true;
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
-   return usedTextureIds;
 
- };
 
- getListOfElementsIdsInUse.sampler = function (gltf) {
 
-   const usedSamplerIds = {};
 
-   ForEach.texture(gltf, function (texture) {
 
-     if (defined(texture.sampler)) {
 
-       usedSamplerIds[texture.sampler] = true;
 
-     }
 
-   });
 
-   return usedSamplerIds;
 
- };
 
- export default removeUnusedElements;
 
 
  |