"use strict";
/* @license
 * Copyright 2021 Google LLC. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const compatibleObject = (object) => {
  return object.material !== void 0 && // easier than (!object.isMesh && !object.isLine &&
  // !object.isPoints)
  object.userData && // just in case
  object.userData.variantMaterials && // Is this line costly?
  !!Array.from(object.userData.variantMaterials.values()).filter((m) => compatibleMaterial(m.material));
};
const compatibleMaterial = (material) => {
  return material && material.isMaterial && !Array.isArray(material);
};
class GLTFExporterMaterialsVariantsExtension {
  constructor(writer) {
    this.writer = writer;
    this.name = "KHR_materials_variants";
    this.variantNames = [];
  }
  beforeParse(objects) {
    const variantNameSet = /* @__PURE__ */ new Set();
    for (const object of objects) {
      object.traverse((o) => {
        if (!compatibleObject(o)) {
          return;
        }
        const variantMaterials = o.userData.variantMaterials;
        const variantDataMap = o.userData.variantData;
        for (const [variantName, variantData] of variantDataMap) {
          const variantMaterial = variantMaterials.get(variantData.index);
          if (variantMaterial && compatibleMaterial(variantMaterial.material)) {
            variantNameSet.add(variantName);
          }
        }
      });
    }
    variantNameSet.forEach((name) => this.variantNames.push(name));
  }
  writeMesh(mesh, meshDef) {
    if (!compatibleObject(mesh)) {
      return;
    }
    const userData = mesh.userData;
    const variantMaterials = userData.variantMaterials;
    const variantDataMap = userData.variantData;
    const mappingTable = /* @__PURE__ */ new Map();
    const reIndexedVariants = /* @__PURE__ */ new Map();
    const variants = Array.from(variantDataMap.values()).sort((a, b) => {
      return a.index - b.index;
    });
    for (const [i, variantData] of variants.entries()) {
      reIndexedVariants.set(variantData.index, i);
    }
    for (const variantData of variantDataMap.values()) {
      const variantInstance = variantMaterials.get(variantData.index);
      if (!variantInstance || !compatibleMaterial(variantInstance.material)) {
        continue;
      }
      const materialIndex = this.writer.processMaterial(variantInstance.material);
      if (!mappingTable.has(materialIndex)) {
        mappingTable.set(materialIndex, { material: materialIndex, variants: [] });
      }
      mappingTable.get(materialIndex).variants.push(reIndexedVariants.get(variantData.index));
    }
    const mappingsDef = Array.from(mappingTable.values()).map((m) => {
      return m.variants.sort((a, b) => a - b) && m;
    }).sort((a, b) => a.material - b.material);
    if (mappingsDef.length === 0) {
      return;
    }
    const originalMaterialIndex = compatibleMaterial(userData.originalMaterial) ? this.writer.processMaterial(userData.originalMaterial) : -1;
    for (const primitiveDef of meshDef.primitives) {
      if (originalMaterialIndex >= 0) {
        primitiveDef.material = originalMaterialIndex;
      }
      primitiveDef.extensions = primitiveDef.extensions || {};
      primitiveDef.extensions[this.name] = { mappings: mappingsDef };
    }
  }
  afterParse() {
    if (this.variantNames.length === 0) {
      return;
    }
    const root = this.writer.json;
    root.extensions = root.extensions || {};
    const variantsDef = this.variantNames.map((n) => {
      return { name: n };
    });
    root.extensions[this.name] = { variants: variantsDef };
    this.writer.extensionsUsed[this.name] = true;
  }
}
module.exports = GLTFExporterMaterialsVariantsExtension;
//# sourceMappingURL=VariantMaterialExporterPlugin.js.map
