"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 Tiles
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.indexedEdgeParamsFromCompactEdges = indexedEdgeParamsFromCompactEdges;
const core_bentley_1 = require("@itwin/core-bentley");
const ImdlSchema_1 = require("./ImdlSchema");
const EdgeParams_1 = require("../internal/render/EdgeParams");
const VertexIndices_1 = require("../internal/render/VertexIndices");
/** Iterate over the compact edges.
 * @note The same object is returned on each iteration, mutated in place.
 */
function* compactEdgeIterator(visibilityFlags, vertexIndices, normalPairs) {
    let bitIndex = 0;
    let flagsIndex = 0;
    let normalIndex = 0;
    const output = { index0: 0, index1: 1 };
    for (let i = 0; i < vertexIndices.length; i++) {
        const visibility = (visibilityFlags[flagsIndex] >> bitIndex) & 3;
        bitIndex += 2;
        if (bitIndex === 8) {
            bitIndex = 0;
            flagsIndex++;
        }
        if (ImdlSchema_1.ImdlEdgeVisibility.Hidden === visibility)
            continue;
        output.index0 = vertexIndices.decodeIndex(i);
        output.index1 = vertexIndices.decodeIndex(i % 3 === 2 ? i - 2 : i + 1);
        if (ImdlSchema_1.ImdlEdgeVisibility.Silhouette === visibility) {
            (0, core_bentley_1.assert)(undefined !== normalPairs);
            output.normals = normalPairs[normalIndex++];
        }
        else {
            output.normals = undefined;
        }
        yield output;
    }
}
function setUint24(edgeTable, byteIndex, value) {
    edgeTable[byteIndex + 0] = value & 0x0000ff;
    edgeTable[byteIndex + 1] = (value & 0x00ff00) >>> 8;
    edgeTable[byteIndex + 2] = (value & 0xff0000) >>> 16;
}
/** Convert an [[ImdlCompactEdges]] to an [[IndexedEdgeParams]].
 * @internal
 */
function indexedEdgeParamsFromCompactEdges(compact) {
    const numSilhouettes = compact.normalPairs?.length ?? 0;
    const numTotalEdges = compact.numVisibleEdges + numSilhouettes;
    if (numTotalEdges <= 0)
        return undefined;
    // Each edge is a quad consisting of six vertices. Each vertex is an identical 24-bit index into the lookup table.
    const indices = new VertexIndices_1.VertexIndices(new Uint8Array(numTotalEdges * 6 * 3));
    for (let i = 0; i < numTotalEdges; i++)
        for (let j = 0; j < 6; j++)
            indices.setNthIndex(i * 6 + j, i);
    const { width, height, silhouettePadding, silhouetteStartByteIndex } = (0, EdgeParams_1.calculateEdgeTableParams)(compact.numVisibleEdges, numSilhouettes, compact.maxEdgeTableDimension);
    const edgeTable = new Uint8Array(width * height * 4);
    let curVisibleIndex = 0;
    let curSilhouetteIndex = 0;
    for (const edge of compactEdgeIterator(compact.visibility, compact.vertexIndices, compact.normalPairs)) {
        if (undefined === edge.normals) {
            const index = curVisibleIndex++;
            const byteIndex = index * 6;
            setUint24(edgeTable, byteIndex, edge.index0);
            setUint24(edgeTable, byteIndex + 3, edge.index1);
        }
        else {
            const index = curSilhouetteIndex++;
            const byteIndex = silhouetteStartByteIndex + silhouettePadding + index * 10;
            setUint24(edgeTable, byteIndex, edge.index0);
            setUint24(edgeTable, byteIndex + 3, edge.index1);
            edgeTable[byteIndex + 6] = edge.normals & 0xff;
            edgeTable[byteIndex + 7] = (edge.normals & 0xff00) >>> 8;
            edgeTable[byteIndex + 8] = (edge.normals & 0xff0000) >>> 16;
            edgeTable[byteIndex + 9] = (edge.normals & 0xff000000) >>> 24;
        }
    }
    return {
        indices: indices.data,
        edges: {
            data: edgeTable,
            width,
            height,
            numSegments: compact.numVisibleEdges,
            silhouettePadding,
        },
    };
}
//# sourceMappingURL=CompactEdges.js.map