@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
146 lines (122 loc) • 4.47 kB
JavaScript
import addExtensionsUsed from "./addExtensionsUsed.js";
import addExtensionsRequired from "./addExtensionsRequired.js";
import addToArray from "./addToArray.js";
import ForEach from "./ForEach.js";
import defined from "../../Core/defined.js";
/**
* Move glTF 1.0 material techniques to glTF 2.0 KHR_techniques_webgl extension.
*
* @param {object} gltf A javascript object containing a glTF asset.
* @returns {object} The updated glTF asset.
*
* @private
*/
function moveTechniquesToExtension(gltf) {
const techniquesLegacy = gltf.techniques;
const mappedUniforms = {};
const updatedTechniqueIndices = {};
const seenPrograms = {};
if (defined(techniquesLegacy)) {
const extension = {
programs: [],
shaders: [],
techniques: [],
};
// Some 1.1 models have a glExtensionsUsed property that can be transferred to program.glExtensions
const glExtensions = gltf.glExtensionsUsed;
delete gltf.glExtensionsUsed;
ForEach.technique(gltf, function (techniqueLegacy, techniqueId) {
const technique = {
name: techniqueLegacy.name,
program: undefined,
attributes: {},
uniforms: {},
};
let parameterLegacy;
ForEach.techniqueAttribute(
techniqueLegacy,
function (parameterName, attributeName) {
parameterLegacy = techniqueLegacy.parameters[parameterName];
technique.attributes[attributeName] = {
semantic: parameterLegacy.semantic,
};
},
);
ForEach.techniqueUniform(
techniqueLegacy,
function (parameterName, uniformName) {
parameterLegacy = techniqueLegacy.parameters[parameterName];
technique.uniforms[uniformName] = {
count: parameterLegacy.count,
node: parameterLegacy.node,
type: parameterLegacy.type,
semantic: parameterLegacy.semantic,
value: parameterLegacy.value,
};
// Store the name of the uniform to update material values.
if (!defined(mappedUniforms[techniqueId])) {
mappedUniforms[techniqueId] = {};
}
mappedUniforms[techniqueId][parameterName] = uniformName;
},
);
if (!defined(seenPrograms[techniqueLegacy.program])) {
const programLegacy = gltf.programs[techniqueLegacy.program];
const program = {
name: programLegacy.name,
fragmentShader: undefined,
vertexShader: undefined,
glExtensions: glExtensions,
};
const fs = gltf.shaders[programLegacy.fragmentShader];
program.fragmentShader = addToArray(extension.shaders, fs, true);
const vs = gltf.shaders[programLegacy.vertexShader];
program.vertexShader = addToArray(extension.shaders, vs, true);
technique.program = addToArray(extension.programs, program);
seenPrograms[techniqueLegacy.program] = technique.program;
} else {
technique.program = seenPrograms[techniqueLegacy.program];
}
// Store the index of the new technique to reference instead.
updatedTechniqueIndices[techniqueId] = addToArray(
extension.techniques,
technique,
);
});
if (extension.techniques.length > 0) {
if (!defined(gltf.extensions)) {
gltf.extensions = {};
}
gltf.extensions.KHR_techniques_webgl = extension;
addExtensionsUsed(gltf, "KHR_techniques_webgl");
addExtensionsRequired(gltf, "KHR_techniques_webgl");
}
}
ForEach.material(gltf, function (material) {
if (defined(material.technique)) {
const materialExtension = {
technique: updatedTechniqueIndices[material.technique],
};
ForEach.objectLegacy(material.values, function (value, parameterName) {
if (!defined(materialExtension.values)) {
materialExtension.values = {};
}
const uniformName = mappedUniforms[material.technique][parameterName];
if (defined(uniformName)) {
materialExtension.values[uniformName] = value;
}
});
if (!defined(material.extensions)) {
material.extensions = {};
}
material.extensions.KHR_techniques_webgl = materialExtension;
}
delete material.technique;
delete material.values;
});
delete gltf.techniques;
delete gltf.programs;
delete gltf.shaders;
return gltf;
}
export default moveTechniquesToExtension;