"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.TriangleSet = exports.TriangleKey = exports.TriangleList = exports.Triangle = exports.ToleranceRatio = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
/** @internal */
var ToleranceRatio;
(function (ToleranceRatio) {
    ToleranceRatio.vertex = 0.1;
    ToleranceRatio.facetArea = 0.1;
})(ToleranceRatio || (exports.ToleranceRatio = ToleranceRatio = {}));
/** @internal */
class Triangle {
    constructor(singleSided = true) {
        this.indices = new Uint32Array(3);
        this.visible = [true, true, true];
        this.singleSided = singleSided;
    }
    setIndices(a, b, c) {
        this.indices[0] = a;
        this.indices[1] = b;
        this.indices[2] = c;
    }
    setEdgeVisibility(a, b, c) {
        this.visible[0] = a;
        this.visible[1] = b;
        this.visible[2] = c;
    }
    isEdgeVisible(index) {
        (0, core_bentley_1.assert)(index < 3 && index >= 0);
        return this.visible[index];
    }
    get isDegenerate() { return this.indices[0] === this.indices[1] || this.indices[0] === this.indices[2] || this.indices[1] === this.indices[2]; }
}
exports.Triangle = Triangle;
/** @internal */
class TriangleList {
    constructor() {
        this._flags = [];
        this.indices = [];
    }
    get length() { return this._flags.length; }
    get isEmpty() { return 0 === this.length; }
    addTriangle(triangle) {
        let flags = triangle.singleSided ? 1 : 0;
        for (let i = 0; i < 3; i++) {
            if (triangle.isEdgeVisible(i))
                flags |= (0x0002 << i);
            this.indices.push(triangle.indices[i]);
        }
        this._flags.push(flags);
    }
    addFromTypedArray(indices, flags = 0) {
        for (let i = 0; i < indices.length;) {
            this.indices.push(indices[i++]);
            this.indices.push(indices[i++]);
            this.indices.push(indices[i++]);
            this._flags.push(flags);
        }
    }
    getTriangle(index, out) {
        const triangle = undefined !== out ? out : new Triangle();
        if (index > this.length) {
            (0, core_bentley_1.assert)(false);
            return new Triangle();
        }
        const flags = this._flags[index];
        triangle.singleSided = 0 !== (flags & 0x0001);
        const baseIndex = index * 3;
        for (let i = 0; i < 3; i++) {
            triangle.indices[i] = this.indices[baseIndex + i];
            triangle.visible[i] = 0 !== (flags & 0x0002 << i);
        }
        return triangle;
    }
}
exports.TriangleList = TriangleList;
/** @internal */
class TriangleKey {
    constructor(triangle) {
        this._sortedIndices = new Uint32Array(3);
        const index = triangle.indices;
        const sorted = this._sortedIndices;
        if (index[0] < index[1]) {
            if (index[0] < index[2]) {
                sorted[0] = index[0];
                if (index[1] < index[2]) {
                    sorted[1] = index[1];
                    sorted[2] = index[2];
                }
                else {
                    sorted[1] = index[2];
                    sorted[2] = index[1];
                }
            }
            else {
                sorted[0] = index[2];
                sorted[1] = index[0];
                sorted[2] = index[1];
            }
        }
        else {
            if (index[1] < index[2]) {
                sorted[0] = index[1];
                if (index[0] < index[2]) {
                    sorted[1] = index[0];
                    sorted[2] = index[2];
                }
                else {
                    sorted[1] = index[2];
                    sorted[2] = index[0];
                }
            }
            else {
                sorted[0] = index[2];
                sorted[1] = index[1];
                sorted[2] = index[0];
            }
        }
        (0, core_bentley_1.assert)(sorted[0] < sorted[1]);
        (0, core_bentley_1.assert)(sorted[1] < sorted[2]);
    }
    compare(rhs) {
        let diff = 0;
        for (let i = 0; i < 3; i++) {
            diff = this._sortedIndices[i] - rhs._sortedIndices[i];
            if (0 !== diff)
                break;
        }
        return diff;
    }
}
exports.TriangleKey = TriangleKey;
/** @internal */
class TriangleSet extends core_bentley_1.SortedArray {
    constructor() {
        super((lhs, rhs) => lhs.compare(rhs));
    }
    insertKey(triangle, onInsert) {
        return this.insert(new TriangleKey(triangle), onInsert);
    }
}
exports.TriangleSet = TriangleSet;
//# sourceMappingURL=Primitives.js.map