"use strict";
/*---------------------------------------------------------------------------------------------
* 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
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SkySpherePrimitive = exports.SkyCubePrimitive = exports.Primitive = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const RenderTarget_1 = require("../RenderTarget");
const CachedGeometry_1 = require("./CachedGeometry");
const DrawCommand_1 = require("./DrawCommand");
const Graphic_1 = require("./Graphic");
const InstancedGeometry_1 = require("./InstancedGeometry");
const System_1 = require("./System");
/** @internal */
class Primitive extends Graphic_1.Graphic {
    constructor(cachedGeom) {
        super();
        this.isPixelMode = false;
        this.cachedGeometry = cachedGeom;
    }
    static create(geom, instances) {
        if (!geom)
            return undefined;
        if (instances) {
            (0, core_bentley_1.assert)(geom instanceof CachedGeometry_1.LUTGeometry, "Invalid geometry type for instancing");
            if (instances instanceof InstancedGeometry_1.PatternBuffers) {
                geom = InstancedGeometry_1.InstancedGeometry.createPattern(geom, true, instances);
            }
            else {
                (0, core_bentley_1.assert)((0, InstancedGeometry_1.isInstancedGraphicParams)(instances));
                const range = InstancedGeometry_1.InstanceBuffers.computeRange(geom.computeRange(), instances.transforms, instances.transformCenter);
                const instanceBuffers = InstancedGeometry_1.InstanceBuffers.create(instances, range);
                if (!instanceBuffers)
                    return undefined;
                geom = InstancedGeometry_1.InstancedGeometry.create(geom, true, instanceBuffers);
            }
        }
        return new this(geom);
    }
    static createShared(geom, instances) {
        if (!geom)
            return undefined;
        if (instances) {
            (0, core_bentley_1.assert)(geom instanceof CachedGeometry_1.LUTGeometry, "Invalid geometry type for instancing");
            if (instances instanceof InstancedGeometry_1.InstanceBuffers)
                geom = InstancedGeometry_1.InstancedGeometry.create(geom, false, instances);
            else
                geom = InstancedGeometry_1.InstancedGeometry.createPattern(geom, false, instances);
        }
        return new this(geom);
    }
    get isDisposed() { return this.cachedGeometry.isDisposed; }
    get isPickable() { return false; }
    dispose() {
        (0, core_bentley_1.dispose)(this.cachedGeometry);
    }
    collectStatistics(stats) {
        this.cachedGeometry.collectStatistics(stats);
    }
    unionRange(range) {
        range.extendRange(this.cachedGeometry.computeRange());
    }
    getPass(target) {
        if (this.isPixelMode)
            return "view-overlay";
        switch (target.primitiveVisibility) {
            case RenderTarget_1.PrimitiveVisibility.Uninstanced:
                if (this.cachedGeometry.isInstanced)
                    return "none";
                break;
            case RenderTarget_1.PrimitiveVisibility.Instanced:
                if (!this.cachedGeometry.isInstanced)
                    return "none";
                break;
        }
        return this.cachedGeometry.getPass(target);
    }
    get hasFeatures() { return this.cachedGeometry.hasFeatures; }
    addCommands(commands) { commands.addPrimitive(this); }
    addHiliteCommands(commands, pass) {
        // Edges do not contribute to hilite pass.
        // Note that IsEdge() does not imply geom->ToEdge() => true...polylines can be edges too...
        if (!this.isEdge)
            commands.getCommands(pass).push(new DrawCommand_1.PrimitiveCommand(this));
    }
    get hasAnimation() { return this.cachedGeometry.hasAnimation; }
    get isInstanced() { return this.cachedGeometry.isInstanced; }
    get isLit() { return this.cachedGeometry.isLitSurface; }
    get isEdge() { return this.cachedGeometry.isEdge; }
    get renderOrder() { return this.cachedGeometry.renderOrder; }
    get hasMaterialAtlas() { return this.cachedGeometry.hasMaterialAtlas; }
    toPrimitive() { return this; }
    static freeParams() { Primitive._drawParams = undefined; }
    draw(shader) {
        // ###TODO: local to world should be pushed before we're invoked...we shouldn't need to pass (or copy) it
        if (undefined === Primitive._drawParams)
            Primitive._drawParams = new DrawCommand_1.DrawParams();
        const drawParams = Primitive._drawParams;
        drawParams.init(shader.params, this.cachedGeometry);
        shader.draw(drawParams);
    }
    get techniqueId() { return this.cachedGeometry.techniqueId; }
}
exports.Primitive = Primitive;
/** @internal */
class SkyCubePrimitive extends Primitive {
    constructor(cachedGeom) { super(cachedGeom); }
    draw(shader) {
        // Alter viewport to maintain square aspect ratio of skybox images even as viewRect resizes
        const vh = shader.target.viewRect.height;
        const vw = shader.target.viewRect.width;
        if (vw > vh)
            System_1.System.instance.context.viewport(0, -(vw - vh) / 2, vw, vw);
        else
            System_1.System.instance.context.viewport(-(vh - vw) / 2, 0, vh, vh);
        super.draw(shader); // Draw the skybox cubemap
        System_1.System.instance.context.viewport(0, 0, vw, vh); // Restore viewport
    }
}
exports.SkyCubePrimitive = SkyCubePrimitive;
/** @internal */
class SkySpherePrimitive extends Primitive {
    constructor(cachedGeom) {
        super(cachedGeom);
        (0, core_bentley_1.assert)(cachedGeom instanceof CachedGeometry_1.SkySphereViewportQuadGeometry);
    }
    draw(shader) {
        this.cachedGeometry.initWorldPos(shader.target);
        super.draw(shader); // Draw the skybox sphere
    }
}
exports.SkySpherePrimitive = SkySpherePrimitive;
//# sourceMappingURL=Primitive.js.map