"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 Rendering
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnimationBranchStates = exports.formatAnimationBranchId = exports.GraphicBranch = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const IModelApp_1 = require("../IModelApp");
/**
 * A node in a scene graph. The branch itself is not renderable. Instead it contains a list of RenderGraphics,
 * and a transform, symbology overrides, and clip volume which are to be applied when rendering them.
 * Branches can be nested to build an arbitrarily-complex scene graph.
 * @see [[RenderSystem.createBranch]]
 * @public
 * @extensions
 */
class GraphicBranch {
    /** Constructor
     * @param ownsEntries If true, when this branch is [[dispose]]d, all of the [[RenderGraphic]]s it contains will also be disposed.
     */
    constructor(ownsEntries = false) {
        /** The child nodes of this branch */
        this.entries = [];
        /** Selectively overrides the view's [ViewFlags]($common) while drawing graphics within this branch. The default overrides nothing.
         * @see [[setViewFlagOverrides]].
         */
        this.viewFlagOverrides = {};
        this.ownsEntries = ownsEntries;
    }
    /** Add a graphic to this branch. */
    add(graphic) {
        this.entries.push(graphic);
    }
    /** Compute the view flags that result from applying this branch's [[viewFlagOverrides]] to the input flags.
     * @param flags The input view flags, e.g., from the view's [[DisplayStyleState]].
     * @returns The result of applying [[viewFlagOverrides]] to `flags`.
     */
    getViewFlags(flags) {
        return flags.override(this.viewFlagOverrides);
    }
    /** Set [[viewFlagOverrides]] to override **all** ViewFlags as specified by `flags`. */
    setViewFlags(flags) {
        this.viewFlagOverrides = { ...flags };
    }
    /** Change [[viewFlagOverrides]]. */
    setViewFlagOverrides(ovr) {
        this.viewFlagOverrides = { ...ovr };
    }
    /** Disposes of all graphics in this branch, if and only if [[ownsEntries]] is true. */
    dispose() {
        this.clear();
    }
    /** Returns true if this branch contains no graphics. */
    get isEmpty() {
        return 0 === this.entries.length;
    }
    /** Empties the list of [[RenderGraphic]]s contained in this branch, and if the [[ownsEntries]] flag is set, also disposes of them. */
    clear() {
        if (this.ownsEntries)
            (0, core_bentley_1.disposeArray)(this.entries);
        else
            this.entries.length = 0;
    }
    /** @internal */
    collectStatistics(stats) {
        for (const entry of this.entries)
            entry.collectStatistics(stats);
    }
}
exports.GraphicBranch = GraphicBranch;
/** @internal */
function formatAnimationBranchId(modelId, branchId) {
    if (branchId < 0)
        return modelId;
    return `${modelId}_Node_${branchId.toString()}`;
}
exports.formatAnimationBranchId = formatAnimationBranchId;
function addAnimationBranch(modelId, timeline, branchId, branches, time) {
    const clipVector = timeline.getClipVector(time);
    const clip = clipVector ? IModelApp_1.IModelApp.renderSystem.createClipVolume(clipVector) : undefined;
    if (clip)
        branches.set(formatAnimationBranchId(modelId, branchId), { clip });
}
/** @internal */
var AnimationBranchStates;
(function (AnimationBranchStates) {
    function fromScript(script, time) {
        if (!script.containsModelClipping && !script.requiresBatching)
            return undefined;
        const branches = new Map();
        for (const model of script.modelTimelines) {
            addAnimationBranch(model.modelId, model, -1, branches, time);
            for (const elem of model.elementTimelines) {
                if (elem.getVisibility(time) <= 0)
                    branches.set(formatAnimationBranchId(model.modelId, elem.batchId), { omit: true });
                else
                    addAnimationBranch(model.modelId, elem, elem.batchId, branches, time);
            }
        }
        return {
            branchStates: branches,
            transformNodeIds: script.transformBatchIds,
        };
    }
    AnimationBranchStates.fromScript = fromScript;
})(AnimationBranchStates || (exports.AnimationBranchStates = AnimationBranchStates = {}));
//# sourceMappingURL=GraphicBranch.js.map