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];
|
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;
|