import { DITHERING, VISIBILITY_PROPERTY_DEFINE, HIGHLIGHT_PROPERTY_DEFINE } from '../ShaderConstants';
import { packedNormalPackSize } from '../PackedNormal';
import { Engine } from '../babylonjs-import';
import { TransparencyMode } from '../twinfinity-viewer';
import { clipPlanesStrings } from './CullingMaterial';
import { DitheringMaterial } from './DitheringMaterial';
import { transparentIfcShader } from './shaders/TransparentIfcShader';
const SIZE = 'size';
const PACK_SIZE = 'packSize';
const WORLD_MATRIX = 'worldMatrix';
const DIFFUSE_SAMPLER = 'diffuseSampler';
const PROPERTIES_SAMPLER = 'propertiesSampler';
const HIGHLIGHT_COLORS = 'highlightColors';
export class TransparentIfcMaterial extends DitheringMaterial {
    diffuseTexture;
    propertiesTexture;
    constructor(name, scene, renderingInfo, diffuseTexture, propertiesTexture, ditherTexture) {
        super(name, scene, renderingInfo, {
            attributes: ['position', 'uv'],
            samplers: [DIFFUSE_SAMPLER, PROPERTIES_SAMPLER]
        }, ditherTexture, true, false);
        this.diffuseTexture = diffuseTexture;
        this.propertiesTexture = propertiesTexture;
        this.visualSettings.ifc.color.onPropertyChanged.add(() => {
            this.isDirty = true;
        });
        this.visualSettings.ifc.transparency.onPropertyChanged.add((change) => {
            if (change.property === 'mode') {
                this.isDirty = true;
                this.updateAlphaMode();
            }
        });
    }
    updateAlphaMode() {
        if (this.visualSettings.ifc.transparency.mode === TransparencyMode.Dithering) {
            this._isDitherModeEnabled = true;
            this.alpha = 1.0;
            this.alphaMode = Engine.ALPHA_DISABLE;
        }
        else {
            this._isDitherModeEnabled = false;
            this.alpha = 0.99;
            this.alphaMode = Engine.ALPHA_COMBINE;
        }
    }
    getUniformsAndDefinesAndSamplers() {
        const uniformsAndSamplers = super.getUniformsAndDefinesAndSamplers();
        const defines = [
            'DITHERING_OPACITY_COEFFICIENT 1.0',
            VISIBILITY_PROPERTY_DEFINE,
            HIGHLIGHT_PROPERTY_DEFINE
        ];
        const uniforms = ['worldViewProjection', SIZE, PACK_SIZE, WORLD_MATRIX];
        const samplers = [DIFFUSE_SAMPLER, PROPERTIES_SAMPLER];
        if (this._isDitherModeEnabled) {
            defines.push(DITHERING);
        }
        // Babylonjs need to have every index of uniform arrays addded to the list of uniforms used by the shader
        for (let i = 0; i < 3; i++) {
            uniforms.push(HIGHLIGHT_COLORS + '[' + i + ']');
        }
        const aggregatedUniformsAndSamplers = {
            uniforms: [...uniformsAndSamplers.uniforms, ...uniforms],
            defines: [...uniformsAndSamplers.defines, ...defines],
            samplers: [...uniformsAndSamplers.samplers, ...samplers]
        };
        this.visualSettings.ifc.color._insertUniformsAndDefines(aggregatedUniformsAndSamplers);
        return aggregatedUniformsAndSamplers;
    }
    bindFunction(mesh) {
        super.bindFunction(mesh);
        const effect = this.getEffect();
        effect.setTexture(PROPERTIES_SAMPLER, this.propertiesTexture.getTexture(mesh.getScene()));
        effect.setTexture(DIFFUSE_SAMPLER, this.diffuseTexture.getTexture(mesh.getScene()));
        this.setFloat(PACK_SIZE, packedNormalPackSize);
        const wm = mesh.getWorldMatrix();
        this.getEffect().setMatrix(WORLD_MATRIX, wm);
        this.visualSettings.ifc.color._setEffectValues(effect);
        this.visualSettings.ifc._setEffectValues(effect);
    }
    getFragmentSource() {
        return transparentIfcShader.fragment({
            clipPlaneUniforms: () => {
                return clipPlanesStrings.CLIP_PLANE_UNIFORMS;
            },
            clipPlaneDiscarding: () => {
                return clipPlanesStrings.CLIP_PLANE_DISCARDING;
            },
            clipPlaneColorBlending: () => {
                return clipPlanesStrings.CLIP_PLANE_COLOR_BLENDING;
            }
        });
    }
    getVertexSource() {
        return transparentIfcShader.vertex();
    }
}
//# sourceMappingURL=TransparentIfcMaterial.js.map