| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979 | 
							- import addExtensionsUsed from "./addExtensionsUsed.js";
 
- import addToArray from "./addToArray.js";
 
- import findAccessorMinMax from "./findAccessorMinMax.js";
 
- import ForEach from "./ForEach.js";
 
- import getAccessorByteStride from "./getAccessorByteStride.js";
 
- import numberOfComponentsForType from "./numberOfComponentsForType.js";
 
- import moveTechniqueRenderStates from "./moveTechniqueRenderStates.js";
 
- import moveTechniquesToExtension from "./moveTechniquesToExtension.js";
 
- import removeUnusedElements from "./removeUnusedElements.js";
 
- import updateAccessorComponentTypes from "./updateAccessorComponentTypes.js";
 
- import Cartesian3 from "../../Core/Cartesian3.js";
 
- import Cartesian4 from "../../Core/Cartesian4.js";
 
- import clone from "../../Core/clone.js";
 
- import ComponentDatatype from "../../Core/ComponentDatatype.js";
 
- import defaultValue from "../../Core/defaultValue.js";
 
- import defined from "../../Core/defined.js";
 
- import Matrix4 from "../../Core/Matrix4.js";
 
- import Quaternion from "../../Core/Quaternion.js";
 
- import WebGLConstants from "../../Core/WebGLConstants.js";
 
- const updateFunctions = {
 
-   0.8: glTF08to10,
 
-   "1.0": glTF10to20,
 
-   "2.0": undefined,
 
- };
 
- /**
 
-  * Update the glTF version to the latest version (2.0), or targetVersion if specified.
 
-  * Applies changes made to the glTF spec between revisions so that the core library
 
-  * only has to handle the latest version.
 
-  *
 
-  * @param {Object} gltf A javascript object containing a glTF asset.
 
-  * @param {Object} [options] Options for updating the glTF.
 
-  * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version.
 
-  * @returns {Object} The updated glTF asset.
 
-  *
 
-  * @private
 
-  */
 
- function updateVersion(gltf, options) {
 
-   options = defaultValue(options, defaultValue.EMPTY_OBJECT);
 
-   const targetVersion = options.targetVersion;
 
-   let version = gltf.version;
 
-   gltf.asset = defaultValue(gltf.asset, {
 
-     version: "1.0",
 
-   });
 
-   gltf.asset.version = defaultValue(gltf.asset.version, "1.0");
 
-   version = defaultValue(version, gltf.asset.version).toString();
 
-   // Invalid version
 
-   if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) {
 
-     // Try truncating trailing version numbers, could be a number as well if it is 0.8
 
-     if (defined(version)) {
 
-       version = version.substring(0, 3);
 
-     }
 
-     // Default to 1.0 if it cannot be determined
 
-     if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) {
 
-       version = "1.0";
 
-     }
 
-   }
 
-   let updateFunction = updateFunctions[version];
 
-   while (defined(updateFunction)) {
 
-     if (version === targetVersion) {
 
-       break;
 
-     }
 
-     updateFunction(gltf, options);
 
-     version = gltf.asset.version;
 
-     updateFunction = updateFunctions[version];
 
-   }
 
-   return gltf;
 
- }
 
- function updateInstanceTechniques(gltf) {
 
-   const materials = gltf.materials;
 
-   for (const materialId in materials) {
 
-     if (Object.prototype.hasOwnProperty.call(materials, materialId)) {
 
-       const material = materials[materialId];
 
-       const instanceTechnique = material.instanceTechnique;
 
-       if (defined(instanceTechnique)) {
 
-         material.technique = instanceTechnique.technique;
 
-         material.values = instanceTechnique.values;
 
-         delete material.instanceTechnique;
 
-       }
 
-     }
 
-   }
 
- }
 
- function setPrimitiveModes(gltf) {
 
-   const meshes = gltf.meshes;
 
-   for (const meshId in meshes) {
 
-     if (Object.prototype.hasOwnProperty.call(meshes, meshId)) {
 
-       const mesh = meshes[meshId];
 
-       const primitives = mesh.primitives;
 
-       if (defined(primitives)) {
 
-         const primitivesLength = primitives.length;
 
-         for (let i = 0; i < primitivesLength; ++i) {
 
-           const primitive = primitives[i];
 
-           const defaultMode = defaultValue(
 
-             primitive.primitive,
 
-             WebGLConstants.TRIANGLES
 
-           );
 
-           primitive.mode = defaultValue(primitive.mode, defaultMode);
 
-           delete primitive.primitive;
 
-         }
 
-       }
 
-     }
 
-   }
 
- }
 
- function updateNodes(gltf) {
 
-   const nodes = gltf.nodes;
 
-   const axis = new Cartesian3();
 
-   const quat = new Quaternion();
 
-   for (const nodeId in nodes) {
 
-     if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
 
-       const node = nodes[nodeId];
 
-       if (defined(node.rotation)) {
 
-         const rotation = node.rotation;
 
-         Cartesian3.fromArray(rotation, 0, axis);
 
-         Quaternion.fromAxisAngle(axis, rotation[3], quat);
 
-         node.rotation = [quat.x, quat.y, quat.z, quat.w];
 
-       }
 
-       const instanceSkin = node.instanceSkin;
 
-       if (defined(instanceSkin)) {
 
-         node.skeletons = instanceSkin.skeletons;
 
-         node.skin = instanceSkin.skin;
 
-         node.meshes = instanceSkin.meshes;
 
-         delete node.instanceSkin;
 
-       }
 
-     }
 
-   }
 
- }
 
- function updateAnimations(gltf) {
 
-   const animations = gltf.animations;
 
-   const accessors = gltf.accessors;
 
-   const bufferViews = gltf.bufferViews;
 
-   const buffers = gltf.buffers;
 
-   const updatedAccessors = {};
 
-   const axis = new Cartesian3();
 
-   const quat = new Quaternion();
 
-   for (const animationId in animations) {
 
-     if (Object.prototype.hasOwnProperty.call(animations, animationId)) {
 
-       const animation = animations[animationId];
 
-       const channels = animation.channels;
 
-       const parameters = animation.parameters;
 
-       const samplers = animation.samplers;
 
-       if (defined(channels)) {
 
-         const channelsLength = channels.length;
 
-         for (let i = 0; i < channelsLength; ++i) {
 
-           const channel = channels[i];
 
-           if (channel.target.path === "rotation") {
 
-             const accessorId = parameters[samplers[channel.sampler].output];
 
-             if (defined(updatedAccessors[accessorId])) {
 
-               continue;
 
-             }
 
-             updatedAccessors[accessorId] = true;
 
-             const accessor = accessors[accessorId];
 
-             const bufferView = bufferViews[accessor.bufferView];
 
-             const buffer = buffers[bufferView.buffer];
 
-             const source = buffer.extras._pipeline.source;
 
-             const byteOffset =
 
-               source.byteOffset + bufferView.byteOffset + accessor.byteOffset;
 
-             const componentType = accessor.componentType;
 
-             const count = accessor.count;
 
-             const componentsLength = numberOfComponentsForType(accessor.type);
 
-             const length = accessor.count * componentsLength;
 
-             const typedArray = ComponentDatatype.createArrayBufferView(
 
-               componentType,
 
-               source.buffer,
 
-               byteOffset,
 
-               length
 
-             );
 
-             for (let j = 0; j < count; j++) {
 
-               const offset = j * componentsLength;
 
-               Cartesian3.unpack(typedArray, offset, axis);
 
-               const angle = typedArray[offset + 3];
 
-               Quaternion.fromAxisAngle(axis, angle, quat);
 
-               Quaternion.pack(quat, typedArray, offset);
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
- }
 
- function removeTechniquePasses(gltf) {
 
-   const techniques = gltf.techniques;
 
-   for (const techniqueId in techniques) {
 
-     if (Object.prototype.hasOwnProperty.call(techniques, techniqueId)) {
 
-       const technique = techniques[techniqueId];
 
-       const passes = technique.passes;
 
-       if (defined(passes)) {
 
-         const passName = defaultValue(technique.pass, "defaultPass");
 
-         if (Object.prototype.hasOwnProperty.call(passes, passName)) {
 
-           const pass = passes[passName];
 
-           const instanceProgram = pass.instanceProgram;
 
-           technique.attributes = defaultValue(
 
-             technique.attributes,
 
-             instanceProgram.attributes
 
-           );
 
-           technique.program = defaultValue(
 
-             technique.program,
 
-             instanceProgram.program
 
-           );
 
-           technique.uniforms = defaultValue(
 
-             technique.uniforms,
 
-             instanceProgram.uniforms
 
-           );
 
-           technique.states = defaultValue(technique.states, pass.states);
 
-         }
 
-         delete technique.passes;
 
-         delete technique.pass;
 
-       }
 
-     }
 
-   }
 
- }
 
- function glTF08to10(gltf) {
 
-   if (!defined(gltf.asset)) {
 
-     gltf.asset = {};
 
-   }
 
-   const asset = gltf.asset;
 
-   asset.version = "1.0";
 
-   // Profile should be an object, not a string
 
-   if (typeof asset.profile === "string") {
 
-     const split = asset.profile.split(" ");
 
-     asset.profile = {
 
-       api: split[0],
 
-       version: split[1],
 
-     };
 
-   } else {
 
-     asset.profile = {};
 
-   }
 
-   // Version property should be in asset, not on the root element
 
-   if (defined(gltf.version)) {
 
-     delete gltf.version;
 
-   }
 
-   // material.instanceTechnique properties should be directly on the material
 
-   updateInstanceTechniques(gltf);
 
-   // primitive.primitive should be primitive.mode
 
-   setPrimitiveModes(gltf);
 
-   // Node rotation should be quaternion, not axis-angle
 
-   // node.instanceSkin is deprecated
 
-   updateNodes(gltf);
 
-   // Animations that target rotations should be quaternion, not axis-angle
 
-   updateAnimations(gltf);
 
-   // technique.pass and techniques.passes are deprecated
 
-   removeTechniquePasses(gltf);
 
-   // gltf.allExtensions -> extensionsUsed
 
-   if (defined(gltf.allExtensions)) {
 
-     gltf.extensionsUsed = gltf.allExtensions;
 
-     delete gltf.allExtensions;
 
-   }
 
-   // gltf.lights -> khrMaterialsCommon.lights
 
-   if (defined(gltf.lights)) {
 
-     const extensions = defaultValue(gltf.extensions, {});
 
-     gltf.extensions = extensions;
 
-     const materialsCommon = defaultValue(extensions.KHR_materials_common, {});
 
-     extensions.KHR_materials_common = materialsCommon;
 
-     materialsCommon.lights = gltf.lights;
 
-     delete gltf.lights;
 
-     addExtensionsUsed(gltf, "KHR_materials_common");
 
-   }
 
- }
 
- function removeAnimationSamplersIndirection(gltf) {
 
-   const animations = gltf.animations;
 
-   for (const animationId in animations) {
 
-     if (Object.prototype.hasOwnProperty.call(animations, animationId)) {
 
-       const animation = animations[animationId];
 
-       const parameters = animation.parameters;
 
-       if (defined(parameters)) {
 
-         const samplers = animation.samplers;
 
-         for (const samplerId in samplers) {
 
-           if (Object.prototype.hasOwnProperty.call(samplers, samplerId)) {
 
-             const sampler = samplers[samplerId];
 
-             sampler.input = parameters[sampler.input];
 
-             sampler.output = parameters[sampler.output];
 
-           }
 
-         }
 
-         delete animation.parameters;
 
-       }
 
-     }
 
-   }
 
- }
 
- function objectToArray(object, mapping) {
 
-   const array = [];
 
-   for (const id in object) {
 
-     if (Object.prototype.hasOwnProperty.call(object, id)) {
 
-       const value = object[id];
 
-       mapping[id] = array.length;
 
-       array.push(value);
 
-       if (!defined(value.name)) {
 
-         value.name = id;
 
-       }
 
-     }
 
-   }
 
-   return array;
 
- }
 
- function objectsToArrays(gltf) {
 
-   let i;
 
-   const globalMapping = {
 
-     accessors: {},
 
-     animations: {},
 
-     buffers: {},
 
-     bufferViews: {},
 
-     cameras: {},
 
-     images: {},
 
-     materials: {},
 
-     meshes: {},
 
-     nodes: {},
 
-     programs: {},
 
-     samplers: {},
 
-     scenes: {},
 
-     shaders: {},
 
-     skins: {},
 
-     textures: {},
 
-     techniques: {},
 
-   };
 
-   // Map joint names to id names
 
-   let jointName;
 
-   const jointNameToId = {};
 
-   const nodes = gltf.nodes;
 
-   for (const id in nodes) {
 
-     if (Object.prototype.hasOwnProperty.call(nodes, id)) {
 
-       jointName = nodes[id].jointName;
 
-       if (defined(jointName)) {
 
-         jointNameToId[jointName] = id;
 
-       }
 
-     }
 
-   }
 
-   // Convert top level objects to arrays
 
-   for (const topLevelId in gltf) {
 
-     if (
 
-       Object.prototype.hasOwnProperty.call(gltf, topLevelId) &&
 
-       defined(globalMapping[topLevelId])
 
-     ) {
 
-       const objectMapping = {};
 
-       const object = gltf[topLevelId];
 
-       gltf[topLevelId] = objectToArray(object, objectMapping);
 
-       globalMapping[topLevelId] = objectMapping;
 
-     }
 
-   }
 
-   // Remap joint names to array indexes
 
-   for (jointName in jointNameToId) {
 
-     if (Object.prototype.hasOwnProperty.call(jointNameToId, jointName)) {
 
-       jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]];
 
-     }
 
-   }
 
-   // Fix references
 
-   if (defined(gltf.scene)) {
 
-     gltf.scene = globalMapping.scenes[gltf.scene];
 
-   }
 
-   ForEach.bufferView(gltf, function (bufferView) {
 
-     if (defined(bufferView.buffer)) {
 
-       bufferView.buffer = globalMapping.buffers[bufferView.buffer];
 
-     }
 
-   });
 
-   ForEach.accessor(gltf, function (accessor) {
 
-     if (defined(accessor.bufferView)) {
 
-       accessor.bufferView = globalMapping.bufferViews[accessor.bufferView];
 
-     }
 
-   });
 
-   ForEach.shader(gltf, function (shader) {
 
-     const extensions = shader.extensions;
 
-     if (defined(extensions)) {
 
-       const binaryGltf = extensions.KHR_binary_glTF;
 
-       if (defined(binaryGltf)) {
 
-         shader.bufferView = globalMapping.bufferViews[binaryGltf.bufferView];
 
-         delete extensions.KHR_binary_glTF;
 
-       }
 
-       if (Object.keys(extensions).length === 0) {
 
-         delete shader.extensions;
 
-       }
 
-     }
 
-   });
 
-   ForEach.program(gltf, function (program) {
 
-     if (defined(program.vertexShader)) {
 
-       program.vertexShader = globalMapping.shaders[program.vertexShader];
 
-     }
 
-     if (defined(program.fragmentShader)) {
 
-       program.fragmentShader = globalMapping.shaders[program.fragmentShader];
 
-     }
 
-   });
 
-   ForEach.technique(gltf, function (technique) {
 
-     if (defined(technique.program)) {
 
-       technique.program = globalMapping.programs[technique.program];
 
-     }
 
-     ForEach.techniqueParameter(technique, function (parameter) {
 
-       if (defined(parameter.node)) {
 
-         parameter.node = globalMapping.nodes[parameter.node];
 
-       }
 
-       const value = parameter.value;
 
-       if (typeof value === "string") {
 
-         parameter.value = {
 
-           index: globalMapping.textures[value],
 
-         };
 
-       }
 
-     });
 
-   });
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       if (defined(primitive.indices)) {
 
-         primitive.indices = globalMapping.accessors[primitive.indices];
 
-       }
 
-       ForEach.meshPrimitiveAttribute(
 
-         primitive,
 
-         function (accessorId, semantic) {
 
-           primitive.attributes[semantic] = globalMapping.accessors[accessorId];
 
-         }
 
-       );
 
-       if (defined(primitive.material)) {
 
-         primitive.material = globalMapping.materials[primitive.material];
 
-       }
 
-     });
 
-   });
 
-   ForEach.node(gltf, function (node) {
 
-     let children = node.children;
 
-     if (defined(children)) {
 
-       const childrenLength = children.length;
 
-       for (i = 0; i < childrenLength; ++i) {
 
-         children[i] = globalMapping.nodes[children[i]];
 
-       }
 
-     }
 
-     if (defined(node.meshes)) {
 
-       // Split out meshes on nodes
 
-       const meshes = node.meshes;
 
-       const meshesLength = meshes.length;
 
-       if (meshesLength > 0) {
 
-         node.mesh = globalMapping.meshes[meshes[0]];
 
-         for (i = 1; i < meshesLength; ++i) {
 
-           const meshNode = {
 
-             mesh: globalMapping.meshes[meshes[i]],
 
-           };
 
-           const meshNodeId = addToArray(gltf.nodes, meshNode);
 
-           if (!defined(children)) {
 
-             children = [];
 
-             node.children = children;
 
-           }
 
-           children.push(meshNodeId);
 
-         }
 
-       }
 
-       delete node.meshes;
 
-     }
 
-     if (defined(node.camera)) {
 
-       node.camera = globalMapping.cameras[node.camera];
 
-     }
 
-     if (defined(node.skin)) {
 
-       node.skin = globalMapping.skins[node.skin];
 
-     }
 
-     if (defined(node.skeletons)) {
 
-       // Assign skeletons to skins
 
-       const skeletons = node.skeletons;
 
-       const skeletonsLength = skeletons.length;
 
-       if (skeletonsLength > 0 && defined(node.skin)) {
 
-         const skin = gltf.skins[node.skin];
 
-         skin.skeleton = globalMapping.nodes[skeletons[0]];
 
-       }
 
-       delete node.skeletons;
 
-     }
 
-     if (defined(node.jointName)) {
 
-       delete node.jointName;
 
-     }
 
-   });
 
-   ForEach.skin(gltf, function (skin) {
 
-     if (defined(skin.inverseBindMatrices)) {
 
-       skin.inverseBindMatrices =
 
-         globalMapping.accessors[skin.inverseBindMatrices];
 
-     }
 
-     const jointNames = skin.jointNames;
 
-     if (defined(jointNames)) {
 
-       const joints = [];
 
-       const jointNamesLength = jointNames.length;
 
-       for (i = 0; i < jointNamesLength; ++i) {
 
-         joints[i] = jointNameToId[jointNames[i]];
 
-       }
 
-       skin.joints = joints;
 
-       delete skin.jointNames;
 
-     }
 
-   });
 
-   ForEach.scene(gltf, function (scene) {
 
-     const sceneNodes = scene.nodes;
 
-     if (defined(sceneNodes)) {
 
-       const sceneNodesLength = sceneNodes.length;
 
-       for (i = 0; i < sceneNodesLength; ++i) {
 
-         sceneNodes[i] = globalMapping.nodes[sceneNodes[i]];
 
-       }
 
-     }
 
-   });
 
-   ForEach.animation(gltf, function (animation) {
 
-     const samplerMapping = {};
 
-     animation.samplers = objectToArray(animation.samplers, samplerMapping);
 
-     ForEach.animationSampler(animation, function (sampler) {
 
-       sampler.input = globalMapping.accessors[sampler.input];
 
-       sampler.output = globalMapping.accessors[sampler.output];
 
-     });
 
-     ForEach.animationChannel(animation, function (channel) {
 
-       channel.sampler = samplerMapping[channel.sampler];
 
-       const target = channel.target;
 
-       if (defined(target)) {
 
-         target.node = globalMapping.nodes[target.id];
 
-         delete target.id;
 
-       }
 
-     });
 
-   });
 
-   ForEach.material(gltf, function (material) {
 
-     if (defined(material.technique)) {
 
-       material.technique = globalMapping.techniques[material.technique];
 
-     }
 
-     ForEach.materialValue(material, function (value, name) {
 
-       if (typeof value === "string") {
 
-         material.values[name] = {
 
-           index: globalMapping.textures[value],
 
-         };
 
-       }
 
-     });
 
-     const extensions = material.extensions;
 
-     if (defined(extensions)) {
 
-       const materialsCommon = extensions.KHR_materials_common;
 
-       if (defined(materialsCommon)) {
 
-         ForEach.materialValue(materialsCommon, function (value, name) {
 
-           if (typeof value === "string") {
 
-             materialsCommon.values[name] = {
 
-               index: globalMapping.textures[value],
 
-             };
 
-           }
 
-         });
 
-       }
 
-     }
 
-   });
 
-   ForEach.image(gltf, function (image) {
 
-     const extensions = image.extensions;
 
-     if (defined(extensions)) {
 
-       const binaryGltf = extensions.KHR_binary_glTF;
 
-       if (defined(binaryGltf)) {
 
-         image.bufferView = globalMapping.bufferViews[binaryGltf.bufferView];
 
-         image.mimeType = binaryGltf.mimeType;
 
-         delete extensions.KHR_binary_glTF;
 
-       }
 
-       if (Object.keys(extensions).length === 0) {
 
-         delete image.extensions;
 
-       }
 
-     }
 
-   });
 
-   ForEach.texture(gltf, function (texture) {
 
-     if (defined(texture.sampler)) {
 
-       texture.sampler = globalMapping.samplers[texture.sampler];
 
-     }
 
-     if (defined(texture.source)) {
 
-       texture.source = globalMapping.images[texture.source];
 
-     }
 
-   });
 
- }
 
- function removeAnimationSamplerNames(gltf) {
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationSampler(animation, function (sampler) {
 
-       delete sampler.name;
 
-     });
 
-   });
 
- }
 
- function removeEmptyArrays(gltf) {
 
-   for (const topLevelId in gltf) {
 
-     if (Object.prototype.hasOwnProperty.call(gltf, topLevelId)) {
 
-       const array = gltf[topLevelId];
 
-       if (Array.isArray(array) && array.length === 0) {
 
-         delete gltf[topLevelId];
 
-       }
 
-     }
 
-   }
 
-   ForEach.node(gltf, function (node) {
 
-     if (defined(node.children) && node.children.length === 0) {
 
-       delete node.children;
 
-     }
 
-   });
 
- }
 
- function stripAsset(gltf) {
 
-   const asset = gltf.asset;
 
-   delete asset.profile;
 
-   delete asset.premultipliedAlpha;
 
- }
 
- const knownExtensions = {
 
-   CESIUM_RTC: true,
 
-   KHR_materials_common: true,
 
-   WEB3D_quantized_attributes: true,
 
- };
 
- function requireKnownExtensions(gltf) {
 
-   const extensionsUsed = gltf.extensionsUsed;
 
-   gltf.extensionsRequired = defaultValue(gltf.extensionsRequired, []);
 
-   if (defined(extensionsUsed)) {
 
-     const extensionsUsedLength = extensionsUsed.length;
 
-     for (let i = 0; i < extensionsUsedLength; ++i) {
 
-       const extension = extensionsUsed[i];
 
-       if (defined(knownExtensions[extension])) {
 
-         gltf.extensionsRequired.push(extension);
 
-       }
 
-     }
 
-   }
 
- }
 
- function removeBufferType(gltf) {
 
-   ForEach.buffer(gltf, function (buffer) {
 
-     delete buffer.type;
 
-   });
 
- }
 
- function removeTextureProperties(gltf) {
 
-   ForEach.texture(gltf, function (texture) {
 
-     delete texture.format;
 
-     delete texture.internalFormat;
 
-     delete texture.target;
 
-     delete texture.type;
 
-   });
 
- }
 
- function requireAttributeSetIndex(gltf) {
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       ForEach.meshPrimitiveAttribute(
 
-         primitive,
 
-         function (accessorId, semantic) {
 
-           if (semantic === "TEXCOORD") {
 
-             primitive.attributes.TEXCOORD_0 = accessorId;
 
-           } else if (semantic === "COLOR") {
 
-             primitive.attributes.COLOR_0 = accessorId;
 
-           }
 
-         }
 
-       );
 
-       delete primitive.attributes.TEXCOORD;
 
-       delete primitive.attributes.COLOR;
 
-     });
 
-   });
 
-   ForEach.technique(gltf, function (technique) {
 
-     ForEach.techniqueParameter(technique, function (parameter) {
 
-       const semantic = parameter.semantic;
 
-       if (defined(semantic)) {
 
-         if (semantic === "TEXCOORD") {
 
-           parameter.semantic = "TEXCOORD_0";
 
-         } else if (semantic === "COLOR") {
 
-           parameter.semantic = "COLOR_0";
 
-         }
 
-       }
 
-     });
 
-   });
 
- }
 
- const knownSemantics = {
 
-   POSITION: true,
 
-   NORMAL: true,
 
-   TANGENT: true,
 
- };
 
- const indexedSemantics = {
 
-   COLOR: "COLOR",
 
-   JOINT: "JOINTS",
 
-   JOINTS: "JOINTS",
 
-   TEXCOORD: "TEXCOORD",
 
-   WEIGHT: "WEIGHTS",
 
-   WEIGHTS: "WEIGHTS",
 
- };
 
- function underscoreApplicationSpecificSemantics(gltf) {
 
-   const mappedSemantics = {};
 
-   ForEach.mesh(gltf, function (mesh) {
 
-     ForEach.meshPrimitive(mesh, function (primitive) {
 
-       /*eslint-disable no-unused-vars*/
 
-       ForEach.meshPrimitiveAttribute(
 
-         primitive,
 
-         function (accessorId, semantic) {
 
-           if (semantic.charAt(0) !== "_") {
 
-             const setIndex = semantic.search(/_[0-9]+/g);
 
-             let strippedSemantic = semantic;
 
-             let suffix = "_0";
 
-             if (setIndex >= 0) {
 
-               strippedSemantic = semantic.substring(0, setIndex);
 
-               suffix = semantic.substring(setIndex);
 
-             }
 
-             let newSemantic;
 
-             const indexedSemantic = indexedSemantics[strippedSemantic];
 
-             if (defined(indexedSemantic)) {
 
-               newSemantic = indexedSemantic + suffix;
 
-               mappedSemantics[semantic] = newSemantic;
 
-             } else if (!defined(knownSemantics[strippedSemantic])) {
 
-               newSemantic = "_" + semantic;
 
-               mappedSemantics[semantic] = newSemantic;
 
-             }
 
-           }
 
-         }
 
-       );
 
-       for (const semantic in mappedSemantics) {
 
-         if (Object.prototype.hasOwnProperty.call(mappedSemantics, semantic)) {
 
-           const mappedSemantic = mappedSemantics[semantic];
 
-           const accessorId = primitive.attributes[semantic];
 
-           if (defined(accessorId)) {
 
-             delete primitive.attributes[semantic];
 
-             primitive.attributes[mappedSemantic] = accessorId;
 
-           }
 
-         }
 
-       }
 
-     });
 
-   });
 
-   ForEach.technique(gltf, function (technique) {
 
-     ForEach.techniqueParameter(technique, function (parameter) {
 
-       const mappedSemantic = mappedSemantics[parameter.semantic];
 
-       if (defined(mappedSemantic)) {
 
-         parameter.semantic = mappedSemantic;
 
-       }
 
-     });
 
-   });
 
- }
 
- function clampCameraParameters(gltf) {
 
-   ForEach.camera(gltf, function (camera) {
 
-     const perspective = camera.perspective;
 
-     if (defined(perspective)) {
 
-       const aspectRatio = perspective.aspectRatio;
 
-       if (defined(aspectRatio) && aspectRatio === 0.0) {
 
-         delete perspective.aspectRatio;
 
-       }
 
-       const yfov = perspective.yfov;
 
-       if (defined(yfov) && yfov === 0.0) {
 
-         perspective.yfov = 1.0;
 
-       }
 
-     }
 
-   });
 
- }
 
- function computeAccessorByteStride(gltf, accessor) {
 
-   return defined(accessor.byteStride) && accessor.byteStride !== 0
 
-     ? accessor.byteStride
 
-     : getAccessorByteStride(gltf, accessor);
 
- }
 
- function requireByteLength(gltf) {
 
-   ForEach.buffer(gltf, function (buffer) {
 
-     if (!defined(buffer.byteLength)) {
 
-       buffer.byteLength = buffer.extras._pipeline.source.length;
 
-     }
 
-   });
 
-   ForEach.accessor(gltf, function (accessor) {
 
-     const bufferViewId = accessor.bufferView;
 
-     if (defined(bufferViewId)) {
 
-       const bufferView = gltf.bufferViews[bufferViewId];
 
-       const accessorByteStride = computeAccessorByteStride(gltf, accessor);
 
-       const accessorByteEnd =
 
-         accessor.byteOffset + accessor.count * accessorByteStride;
 
-       bufferView.byteLength = Math.max(
 
-         defaultValue(bufferView.byteLength, 0),
 
-         accessorByteEnd
 
-       );
 
-     }
 
-   });
 
- }
 
- function moveByteStrideToBufferView(gltf) {
 
-   let i;
 
-   let j;
 
-   let bufferView;
 
-   const bufferViews = gltf.bufferViews;
 
-   const bufferViewHasVertexAttributes = {};
 
-   ForEach.accessorContainingVertexAttributeData(gltf, function (accessorId) {
 
-     const accessor = gltf.accessors[accessorId];
 
-     if (defined(accessor.bufferView)) {
 
-       bufferViewHasVertexAttributes[accessor.bufferView] = true;
 
-     }
 
-   });
 
-   // Map buffer views to a list of accessors
 
-   const bufferViewMap = {};
 
-   ForEach.accessor(gltf, function (accessor) {
 
-     if (defined(accessor.bufferView)) {
 
-       bufferViewMap[accessor.bufferView] = defaultValue(
 
-         bufferViewMap[accessor.bufferView],
 
-         []
 
-       );
 
-       bufferViewMap[accessor.bufferView].push(accessor);
 
-     }
 
-   });
 
-   // Split accessors with different byte strides
 
-   for (const bufferViewId in bufferViewMap) {
 
-     if (Object.prototype.hasOwnProperty.call(bufferViewMap, bufferViewId)) {
 
-       bufferView = bufferViews[bufferViewId];
 
-       const accessors = bufferViewMap[bufferViewId];
 
-       accessors.sort(function (a, b) {
 
-         return a.byteOffset - b.byteOffset;
 
-       });
 
-       let currentByteOffset = 0;
 
-       let currentIndex = 0;
 
-       const accessorsLength = accessors.length;
 
-       for (i = 0; i < accessorsLength; ++i) {
 
-         let accessor = accessors[i];
 
-         const accessorByteStride = computeAccessorByteStride(gltf, accessor);
 
-         const accessorByteOffset = accessor.byteOffset;
 
-         const accessorByteLength = accessor.count * accessorByteStride;
 
-         delete accessor.byteStride;
 
-         const hasNextAccessor = i < accessorsLength - 1;
 
-         const nextAccessorByteStride = hasNextAccessor
 
-           ? computeAccessorByteStride(gltf, accessors[i + 1])
 
-           : undefined;
 
-         if (accessorByteStride !== nextAccessorByteStride) {
 
-           const newBufferView = clone(bufferView, true);
 
-           if (bufferViewHasVertexAttributes[bufferViewId]) {
 
-             newBufferView.byteStride = accessorByteStride;
 
-           }
 
-           newBufferView.byteOffset += currentByteOffset;
 
-           newBufferView.byteLength =
 
-             accessorByteOffset + accessorByteLength - currentByteOffset;
 
-           const newBufferViewId = addToArray(bufferViews, newBufferView);
 
-           for (j = currentIndex; j <= i; ++j) {
 
-             accessor = accessors[j];
 
-             accessor.bufferView = newBufferViewId;
 
-             accessor.byteOffset = accessor.byteOffset - currentByteOffset;
 
-           }
 
-           // Set current byte offset to next accessor's byte offset
 
-           currentByteOffset = hasNextAccessor
 
-             ? accessors[i + 1].byteOffset
 
-             : undefined;
 
-           currentIndex = i + 1;
 
-         }
 
-       }
 
-     }
 
-   }
 
-   // Remove unused buffer views
 
-   removeUnusedElements(gltf, ["accessor", "bufferView", "buffer"]);
 
- }
 
- function requirePositionAccessorMinMax(gltf) {
 
-   ForEach.accessorWithSemantic(gltf, "POSITION", function (accessorId) {
 
-     const accessor = gltf.accessors[accessorId];
 
-     if (!defined(accessor.min) || !defined(accessor.max)) {
 
-       const minMax = findAccessorMinMax(gltf, accessor);
 
-       accessor.min = minMax.min;
 
-       accessor.max = minMax.max;
 
-     }
 
-   });
 
- }
 
- function isNodeEmpty(node) {
 
-   return (
 
-     (!defined(node.children) || node.children.length === 0) &&
 
-     (!defined(node.meshes) || node.meshes.length === 0) &&
 
-     !defined(node.camera) &&
 
-     !defined(node.skin) &&
 
-     !defined(node.skeletons) &&
 
-     !defined(node.jointName) &&
 
-     (!defined(node.translation) ||
 
-       Cartesian3.fromArray(node.translation).equals(Cartesian3.ZERO)) &&
 
-     (!defined(node.scale) ||
 
-       Cartesian3.fromArray(node.scale).equals(new Cartesian3(1.0, 1.0, 1.0))) &&
 
-     (!defined(node.rotation) ||
 
-       Cartesian4.fromArray(node.rotation).equals(
 
-         new Cartesian4(0.0, 0.0, 0.0, 1.0)
 
-       )) &&
 
-     (!defined(node.matrix) ||
 
-       Matrix4.fromColumnMajorArray(node.matrix).equals(Matrix4.IDENTITY)) &&
 
-     !defined(node.extensions) &&
 
-     !defined(node.extras)
 
-   );
 
- }
 
- function deleteNode(gltf, nodeId) {
 
-   // Remove from list of nodes in scene
 
-   ForEach.scene(gltf, function (scene) {
 
-     const sceneNodes = scene.nodes;
 
-     if (defined(sceneNodes)) {
 
-       const sceneNodesLength = sceneNodes.length;
 
-       for (let i = sceneNodesLength; i >= 0; --i) {
 
-         if (sceneNodes[i] === nodeId) {
 
-           sceneNodes.splice(i, 1);
 
-           return;
 
-         }
 
-       }
 
-     }
 
-   });
 
-   // Remove parent node's reference to this node, and delete the parent if also empty
 
-   ForEach.node(gltf, function (parentNode, parentNodeId) {
 
-     if (defined(parentNode.children)) {
 
-       const index = parentNode.children.indexOf(nodeId);
 
-       if (index > -1) {
 
-         parentNode.children.splice(index, 1);
 
-         if (isNodeEmpty(parentNode)) {
 
-           deleteNode(gltf, parentNodeId);
 
-         }
 
-       }
 
-     }
 
-   });
 
-   delete gltf.nodes[nodeId];
 
- }
 
- function removeEmptyNodes(gltf) {
 
-   ForEach.node(gltf, function (node, nodeId) {
 
-     if (isNodeEmpty(node)) {
 
-       deleteNode(gltf, nodeId);
 
-     }
 
-   });
 
-   return gltf;
 
- }
 
- function requireAnimationAccessorMinMax(gltf) {
 
-   ForEach.animation(gltf, function (animation) {
 
-     ForEach.animationSampler(animation, function (sampler) {
 
-       const accessor = gltf.accessors[sampler.input];
 
-       if (!defined(accessor.min) || !defined(accessor.max)) {
 
-         const minMax = findAccessorMinMax(gltf, accessor);
 
-         accessor.min = minMax.min;
 
-         accessor.max = minMax.max;
 
-       }
 
-     });
 
-   });
 
- }
 
- function glTF10to20(gltf) {
 
-   gltf.asset = defaultValue(gltf.asset, {});
 
-   gltf.asset.version = "2.0";
 
-   // material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models.
 
-   updateInstanceTechniques(gltf);
 
-   // animation.samplers now refers directly to accessors and animation.parameters should be removed
 
-   removeAnimationSamplersIndirection(gltf);
 
-   // Remove empty nodes and re-assign referencing indices
 
-   removeEmptyNodes(gltf);
 
-   // Top-level objects are now arrays referenced by index instead of id
 
-   objectsToArrays(gltf);
 
-   // Animation.sampler objects cannot have names
 
-   removeAnimationSamplerNames(gltf);
 
-   // asset.profile no longer exists
 
-   stripAsset(gltf);
 
-   // Move known extensions from extensionsUsed to extensionsRequired
 
-   requireKnownExtensions(gltf);
 
-   // bufferView.byteLength and buffer.byteLength are required
 
-   requireByteLength(gltf);
 
-   // byteStride moved from accessor to bufferView
 
-   moveByteStrideToBufferView(gltf);
 
-   // accessor.min and accessor.max must be defined for accessors containing POSITION attributes
 
-   requirePositionAccessorMinMax(gltf);
 
-   // An animation sampler's input accessor must have min and max properties defined
 
-   requireAnimationAccessorMinMax(gltf);
 
-   // buffer.type is unnecessary and should be removed
 
-   removeBufferType(gltf);
 
-   // Remove format, internalFormat, target, and type
 
-   removeTextureProperties(gltf);
 
-   // TEXCOORD and COLOR attributes must be written with a set index (TEXCOORD_#)
 
-   requireAttributeSetIndex(gltf);
 
-   // Add underscores to application-specific parameters
 
-   underscoreApplicationSpecificSemantics(gltf);
 
-   // Accessors referenced by JOINTS_0 and WEIGHTS_0 attributes must have correct component types
 
-   updateAccessorComponentTypes(gltf);
 
-   // Clamp camera parameters
 
-   clampCameraParameters(gltf);
 
-   // Move legacy technique render states to material properties and add KHR_blend extension blending functions
 
-   moveTechniqueRenderStates(gltf);
 
-   // Add material techniques to KHR_techniques_webgl extension, removing shaders, programs, and techniques
 
-   moveTechniquesToExtension(gltf);
 
-   // Remove empty arrays
 
-   removeEmptyArrays(gltf);
 
- }
 
- export default updateVersion;
 
 
  |