/** What type of {@link PickResult} we have. */
export var PickResultType;
(function (PickResultType) {
    /** No pick result at all */
    PickResultType[PickResultType["Empty"] = 0] = "Empty";
    /** A BabylonJS mesh was picked */
    PickResultType[PickResultType["Mesh"] = 1] = "Mesh";
    /** A {@link Icon} was picked */
    PickResultType[PickResultType["Icon"] = 2] = "Icon";
    /** A {@link BimIfcObject} and one of its IFC mesh'es was picked */
    PickResultType[PickResultType["IfcProductMesh"] = 3] = "IfcProductMesh";
})(PickResultType || (PickResultType = {}));
/** Base class for some classes used in {@link PickResult}. */
class PickResultBase {
    id;
    /**
     * Constructor
     * @param id Unique GPU picking id for the hit object
     */
    constructor(id) {
        this.id = id;
    }
    /**
     * Compare two {@link PickResult} instances.
     * @param pickResult
     */
    equals(pickResult) {
        return pickResult.type !== PickResultType.Empty && pickResult.id === this.id;
    }
}
/** Represents a pick operation where nothing was picked. */
export class PickResultEmpty {
    /** Reusable instance for use with pick operations yielding a empty result. */
    static instance = new PickResultEmpty();
    /** Discriminant union selector */
    type = PickResultType.Empty;
    /** Always empty since its a empty pick operation. */
    hitInfo = Object.freeze([]);
    /**
     * Compare two {@link PickResult} instances.
     * @param pickResult
     */
    equals(pickResult) {
        return pickResult.type === PickResultType.Empty;
    }
}
/** Represents a pick operation where a BabylonJS mesh was picked.
 *  Used when a picking operation hit a BabylonJS mesh that does not represent
 *  a Twinfinity object such as a {@link Icon} or {@link BimIfcObject}.
 */
export class PickResultMesh extends PickResultBase {
    /** Discriminant union selector */
    type = PickResultType.Mesh;
    /** Exact intersections of {@link mesh} that the pick operation gave. */
    hitInfo = [];
    /** BabylonJS Mesh pick operation yielded. */
    mesh;
    /**
     * Constructor
     * @param o - Options
     * @param o.id - Unique GPU picking id for the hit mesh.
     * @param o.mesh - BabylonJS Mesh that was hit by a pick operation
     * @param o.gpuPickMesh - The internal mesh (clone of `o.mesh`) that was used for the GPU pick operation
     * @param o.pickOptions - The picking ray and related options.
     */
    constructor(o) {
        super(o.id);
        this.mesh = o.mesh;
        // Calculate hitInfo directly. Ideally it would have to be done lazily
        // But if we did it lazy (as we do of for other PickResults) then we
        // will refer to a gpuPickMesh that is no longer enabled, visible and might have
        // a incorrect transformatio matrix.
        if (o.gpuPickMesh.isPickable && o.pickOptions.isGeometryIntersectionEnabled) {
            const scene = o.mesh.getScene();
            const pI = scene.pickWithRay(o.pickOptions.ray, (m) => m === o.gpuPickMesh);
            const pickedNormal = pI?.getNormal(true);
            if (pI?.pickedPoint && pickedNormal) {
                this.hitInfo.push({
                    position: pI.pickedPoint,
                    distance: pI.distance,
                    normal: pickedNormal
                });
            }
        }
    }
}
/** Represents a pick operation where a {@link Icon} was picked. */
export class PickResultIcon extends PickResultBase {
    _pickOptions;
    _hitInfo;
    /** Discriminant union selector. */
    type = PickResultType.Icon;
    /** Icon yielded by pick operation. */
    object;
    /** BabylonJS Mesh pick operation yielded. {@link object} belongs to this mesh. */
    mesh;
    /**
     * Constructor
     * @param o - Options
     * @param o.id - Unique GPU picking id for the hit `o.icon`.
     * @param o.mesh - BabylonJS mesh that `o.icon` belongs to.
     * @param o.icon - The {@link Icon} that was hit.
     * @param o.pickOptions - The picking ray and related options.
     */
    constructor(o) {
        super(o.id);
        this.mesh = o.mesh;
        this.object = o.icon;
        this._pickOptions = o.pickOptions;
    }
    /** Exact intersections of {@link object} that the pick operation gave. */
    get hitInfo() {
        // Lazy evaluate icon hitinfo only if requested to avoid
        // expensive intersection operation if its not really used
        if (this._hitInfo === undefined) {
            this._hitInfo = this._pickOptions.isGeometryIntersectionEnabled
                ? this.object.intersect(this._pickOptions)
                : [];
        }
        return this._hitInfo;
    }
}
/** Represents a pick operation where a ifc product mesh  was picked. */
export class PickResultIfcProductMesh extends PickResultBase {
    _pickOptions;
    _hitInfo;
    /** Discriminant union selector */
    type = PickResultType.IfcProductMesh;
    /**
     * {@link BimProductMesh} yielded by pick operation.
     * Use {@link BimProductMesh.ifcProduct} to get IFC product ({@link BimIfcObject} the mesh belongs to
     */
    ifcProductMesh;
    /** BabylonJS Mesh pick operation yielded. {@link mesh} belongs to this mesh. */
    mesh;
    /**
     * Constructor
     * @param o - Options
     * @param o.id - Unique GPU picking id for the hit `o.icon`.
     * @param o.mesh - BabylonJS mesh that `o.ifcProductAndMesh` belongs to.
     * @param o.ifcProductAndMesh - The {@link BimProductAndMesh} that was hit.
     * @param o.pickOptions - The picking ray and related options.
     */
    constructor(o) {
        super(o.id);
        this.mesh = o.mesh;
        this.ifcProductMesh = o.ifcProductAndMesh;
        this._pickOptions = o.pickOptions;
    }
    /** Exact intersections of {@link ifcProductMesh} that the pick operation gave. */
    get hitInfo() {
        // Lazy evaluate icon hitinfo only if requested to avoid
        // expensive intersection operation if its not really used
        if (this._hitInfo === undefined) {
            if (!this._pickOptions.isGeometryIntersectionEnabled) {
                this._hitInfo = [];
            }
            else {
                const ifcMesh = this.ifcProductMesh.mesh();
                this._hitInfo = ifcMesh.intersect(this._pickOptions);
            }
        }
        return this._hitInfo;
    }
}
//# sourceMappingURL=PickResult.js.map