import ForEach from "./ForEach.js"; import Check from "../../Core/Check.js"; import defined from "../../Core/defined.js"; /** * Calls the provider handler function on each texture used by the material. * Mimics the behavior of functions in gltf-pipeline ForEach. * @param {Object} material The glTF material. * @param {forEachTextureInMaterial~handler} handler Function that is called for each texture in the material. * * @private */ function forEachTextureInMaterial(material, handler) { Check.typeOf.object("material", material); Check.defined("handler", handler); // Metallic roughness const pbrMetallicRoughness = material.pbrMetallicRoughness; if (defined(pbrMetallicRoughness)) { if (defined(pbrMetallicRoughness.baseColorTexture)) { const textureInfo = pbrMetallicRoughness.baseColorTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } if (defined(pbrMetallicRoughness.metallicRoughnessTexture)) { const textureInfo = pbrMetallicRoughness.metallicRoughnessTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } } if (defined(material.extensions)) { // Spec gloss extension const pbrSpecularGlossiness = material.extensions.KHR_materials_pbrSpecularGlossiness; if (defined(pbrSpecularGlossiness)) { if (defined(pbrSpecularGlossiness.diffuseTexture)) { const textureInfo = pbrSpecularGlossiness.diffuseTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } if (defined(pbrSpecularGlossiness.specularGlossinessTexture)) { const textureInfo = pbrSpecularGlossiness.specularGlossinessTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } } // Materials common extension (may be present in models converted from glTF 1.0) const materialsCommon = material.extensions.KHR_materials_common; if (defined(materialsCommon)) { const diffuse = materialsCommon.values.diffuse; const ambient = materialsCommon.values.ambient; const emission = materialsCommon.values.emission; const specular = materialsCommon.values.specular; if (defined(diffuse) && defined(diffuse.index)) { const value = handler(diffuse.index, diffuse); if (defined(value)) { return value; } } if (defined(ambient) && defined(ambient.index)) { const value = handler(ambient.index, ambient); if (defined(value)) { return value; } } if (defined(emission) && defined(emission.index)) { const value = handler(emission.index, emission); if (defined(value)) { return value; } } if (defined(specular) && defined(specular.index)) { const value = handler(specular.index, specular); if (defined(value)) { return value; } } } } // KHR_techniques_webgl extension const value = ForEach.materialValue(material, function (materialValue) { if (defined(materialValue.index)) { const value = handler(materialValue.index, materialValue); if (defined(value)) { return value; } } }); if (defined(value)) { return value; } // Top level textures if (defined(material.emissiveTexture)) { const textureInfo = material.emissiveTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } if (defined(material.normalTexture)) { const textureInfo = material.normalTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } if (defined(material.occlusionTexture)) { const textureInfo = material.occlusionTexture; const value = handler(textureInfo.index, textureInfo); if (defined(value)) { return value; } } } /** * Function that is called for each texture in the material. If this function returns a value the for each stops and returns that value. * @callback forEachTextureInMaterial~handler * @param {Number} The texture index. * @param {Object} The texture info object. * * @private */ export default forEachTextureInMaterial;