/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
import { dispose } from "@itwin/core-bentley";
import { FeatureIndexType, LinePixels } from "@itwin/core-common";
import { LineCode } from "./LineCode";
import { createMaterialInfo } from "./Material";
import { VertexLUT } from "./VertexLUT";
/** @internal */
export class MeshData {
    constructor(lut, params, viOrigin) {
        this.lut = lut;
        this.viewIndependentOrigin = viOrigin;
        this.hasFeatures = FeatureIndexType.Empty !== params.vertices.featureIndexType;
        if (FeatureIndexType.Uniform === params.vertices.featureIndexType)
            this.uniformFeatureId = params.vertices.uniformFeatureID;
        this.textureUsesConstantLod = false;
        this.normalMapUsesConstantLod = false;
        if (undefined !== params.surface.textureMapping) {
            this.texture = params.surface.textureMapping.texture;
            this._textureAlwaysDisplayed = params.surface.textureMapping.alwaysDisplayed;
            if (undefined !== params.surface.material && !params.surface.material.isAtlas) {
                const matTM = params.surface.material.material.textureMapping;
                if (undefined !== matTM) {
                    this.textureUsesConstantLod = this.texture && matTM.params.useConstantLod;
                    if (undefined !== matTM.normalMapParams) {
                        this.normalMapUsesConstantLod = matTM.normalMapParams.useConstantLod;
                        if (undefined !== matTM.normalMapParams.normalMap) {
                            this.normalMap = matTM.normalMapParams.normalMap;
                        }
                        else {
                            // If there are normal map params but the normal map is not present, use the texture as a normal map instead of a pattern map.
                            this.normalMap = this.texture;
                            this.texture = undefined;
                        }
                    }
                    if (this.normalMapUsesConstantLod || this.textureUsesConstantLod) {
                        this.constantLodVParams = new Float32Array(3);
                        this.constantLodVParams[0] = matTM.params.constantLodParams.offset.x; // x offset
                        this.constantLodVParams[1] = matTM.params.constantLodParams.offset.y; // y offset
                        this.constantLodVParams[3] = 0.0; // placeholder for orto view distance
                        this.constantLodFParams = new Float32Array(3);
                        this.constantLodFParams[0] = matTM.params.constantLodParams.minDistClamp; // Minimum texture size
                        this.constantLodFParams[1] = matTM.params.constantLodParams.maxDistClamp; // Maximum texture size
                        this.constantLodFParams[2] = matTM.params.constantLodParams.repetitions; // # repetitions of pattern (to scale it)
                    }
                }
            }
        }
        else {
            this.texture = undefined;
            this._textureAlwaysDisplayed = false;
        }
        this.materialInfo = createMaterialInfo(params.surface.material);
        this.type = params.surface.type;
        this.fillFlags = params.surface.fillFlags;
        this.isPlanar = params.isPlanar;
        this.hasBakedLighting = params.surface.hasBakedLighting;
        const edges = params.edges;
        this.edgeWidth = undefined !== edges ? edges.weight : 1;
        this.edgeLineCode = LineCode.valueFromLinePixels(undefined !== edges ? edges.linePixels : LinePixels.Solid);
    }
    static create(params, viOrigin) {
        const lut = VertexLUT.createFromVertexTable(params.vertices, params.auxChannels);
        return undefined !== lut ? new MeshData(lut, params, viOrigin) : undefined;
    }
    get isDisposed() { return undefined === this.texture && this.lut.isDisposed; }
    dispose() {
        dispose(this.lut);
        if (this._ownsTexture)
            this.texture.dispose();
    }
    get isGlyph() { return undefined !== this.texture && this.texture.isGlyph; }
    get isTextureAlwaysDisplayed() { return this.isGlyph || this._textureAlwaysDisplayed; }
    // Returns true if no one else owns this texture. Implies that the texture should be disposed when this object is disposed, and the texture's memory should be tracked as belonging to this object.
    get _ownsTexture() {
        return undefined !== this.texture && !this.texture?.hasOwner;
    }
    collectStatistics(stats) {
        stats.addVertexTable(this.lut.bytesUsed);
        if (this._ownsTexture)
            stats.addTexture(this.texture.bytesUsed);
    }
}
//# sourceMappingURL=MeshData.js.map