import { DeepImmutable, Observable } from '../loader/babylonjs-import';
import { BimCoreApi } from '../BimCoreApi';
import { Vertex3, Vertex2 } from '../math';
/** Id of a tracked 3D coordinate. */
export type CoordinateTrackerId = unknown;
/**
 * Represents the state a tracked coordinate may have.
 */
export declare enum TrackCoordinate2DState {
    /**
     * Item is not tracked
     */
    Detached = 0,
    /**
     * Item was added. Triggers one notification
     * Next notification will say that it is {@link TrackCoordinate2DState.Updated}.
     */
    Added = 1,
    /**
     * Item was updated. Will trigger notification.
     */
    Updated = 2,
    /**
     * Item was deleted. Will trigger one final notification and then no more.
     */
    Deleted = 3
}
/**
 * Minimal requirements for a tracked coordinate.
 */
export interface TrackCoordinate2DData {
    /**
     * Position in 2D of the tracked coordinate
     */
    readonly position: DeepImmutable<Vertex2>;
    /**
     * Position in 2D of the tracked coordinate relative to the canvas.
     * Canvas refers to the the HTML canvas that {@link BimApi} uses.
     * @remarks
     * This is useful when one wants to position HTML elements on top of the canvas and make those HTML elements
     * children to the canvas.
     */
    readonly canvasPosition: DeepImmutable<Vertex2>;
    /**
     * Id of tracked 3D coordinate
     */
    readonly id: CoordinateTrackerId;
    /**
     * Whether the 3D coordinate is visible on screen or not
     */
    readonly visible: boolean;
    /**
     * If active camera is a perspective camera, this is the distance from the camera to the 3D coordinate
     * For an orthographic camera, it is the height of the frustum.
     */
    readonly distance: number;
    /**
     * Current state. Tells whether item is detached, added, updated or deleted.
     */
    readonly state: TrackCoordinate2DState;
}
/**
 * Represents information on a 3D coordinate's location on screen (2D).
 */
export interface TrackCoordinate2D<Tracked3D extends Vertex3 = Vertex3> extends TrackCoordinate2DData {
    /** 3D coordinate we subscribed to. */
    readonly trackedCoordinate: Tracked3D;
}
/** Interface for tracked 3D coordinate. */
export interface TrackCoordinate3D extends Vertex3 {
    /**
     * If `false` then 2D coordinates will be suspended for this particular 3D coordinate.
     * If `undefined` or `false` then 2D coordinates will be reported as usual.
     */
    isEnabled?: boolean;
}
/**
 * CoordinateTracker contains methods for tracking a screen space coordinate from a 3D position.
 */
export declare class CoordinateTracker<Tracked3D extends TrackCoordinate3D = Vertex3> {
    private bimApi;
    private static readonly _tmp;
    private static _currentId;
    private readonly _tracked;
    private _callback?;
    private _scene;
    private _cameraState?;
    private _materialState;
    private _onEndFrameObserver;
    /**
     * Called when a tracked 3D coordinate changes its 2D position (when camera is manipulated).
     * Same as {@link onUpdate} but using a {@link Observable} instead.
     */
    readonly onUpdateObservable: Observable<TrackCoordinate2D<Tracked3D>>;
    /**
     * Constructor
     * @param bimApi BIM Core API.
     * @param recalculate2DEachFrame If `true` then it updates the 2D positions for each tracked 3D coordinate at the end of each frame.
     */
    constructor(bimApi: BimCoreApi, recalculate2DEachFrame?: boolean);
    /**
     * Number of items currently being tracked.
     */
    get size(): number;
    /**
     * Allows iteration of all entities that are tracked (and their ids)
     * @returns collection of all tracked entities and their id.
     */
    entries(): IterableIterator<[CoordinateTrackerId, Tracked3D]>;
    /**
     * Attempt to get a currently tracked object by id.
     * @param id Id of tracked object.
     * @returns Tracked object if it exists. Otherwise undefined
     */
    get(id: CoordinateTrackerId): TrackCoordinate2D<Tracked3D> | undefined;
    /**
     * This method takes a coordinate in 3D to track screen space position when the camera moves.
     * When method is called events on {@link onUpdateObservable} are immediately raised for the passed
     * coordinate. Same coordinate can be passed multiple times (with same id) but it will only be added once.
     * However events {@link onUpdateObservable} will still be immediately raised and report
     * 2D coordinates data even if coordinate is already tracked.
     * @param coordinate Coordinate to track.
     * @param id Optional. If not specified an id will be generated
     * @returns id of tracked coordinate.
     */
    track(coordinate: Tracked3D, id?: CoordinateTrackerId): CoordinateTrackerId;
    /**
     * Gets 2D coordinate of a 3D coordinate once.
     * @param coordinate 3D coordinate to get 2D coordinate from
     * @param id Identifier for 3D coordinate.
     */
    trackOnce(coordinate: Tracked3D, id: CoordinateTrackerId): TrackCoordinate2D<Tracked3D> | undefined;
    /**
     * Stops tracking of a 3D coordinate.
     * @param id Id of 3D coordinate to stop tracking
     * @returns Object that was untracked. If there is no such object then undefined.
     */
    untrack(id: CoordinateTrackerId): Tracked3D | undefined;
    /**
     * Register a callback which will be called when the active camera moves. It is called once for each coordinate registered by {@link track}.
     * @param callback Callback to trigger when an active camera moves.
     */
    onUpdate(callback: (coordinate: TrackCoordinate2D<Tracked3D>) => void): void;
    /**
     * Removes all tracked coordinates from the tracker.
     */
    clear(): void;
    /**
     * Disposes the coordinate tracker.
     * */
    dispose(): void;
    /**
     * Immediately force a recalculation of all 2D coordinates
     */
    forceRecalculation(): void;
    private cameraOrMaterialHasChanged;
    /**
     * Calculate 2D coordinates for currently registered 3D coordinates.
     * @param force Calculation is normally only done if camera has changed
     * during the frame. Setting this to `true` forces the calculation
     */
    private calculated2DCoordinates;
    private notifyObservers;
    private projectCoordinate;
}
//# sourceMappingURL=CoordinateTracker.d.ts.map