import { CoordinateTracker, TrackCoordinate2D } from './CoordinateTracker';
import { BimCoreApi } from '../BimCoreApi';
import { Vertex3 } from '../math/index';
import { DynamicPolygonPoint } from './DynamicPolygonPoint';
import { DynamicPolygonPointParent, DynamicPolygonPointValidationResult } from './DynamicPolygonPointParent';
import { Matrix, Mesh, Nullable, Observable, Observer, Plane, TransformNode, Vector3 } from '../loader/babylonjs-import';
export type DragPointPositioningFunction = (points: DynamicPolygonPoint[]) => Vertex3;
/**
 * Factory signature for creating instances of {@link DynamicPolygonPoint} (or of classes which derive
 * from it.)
 */
export interface DynamicPolygonPointFactoryHandler<Point extends DynamicPolygonPoint> {
    (api: BimCoreApi, plane: Plane, isVirtual: boolean): Point;
}
/**
 * Represents a dynamic polygon. It is possible to add, insert and remove points to it and
 * have those changes reflect its 3D visualization. Useful for tools that need to
 * calculate area.
 * @param <Point> Defaults to {@link DynamicPolygonPoint}. However, a custom class can be specified
 * which derives from {@link DynamicPolygonPoint}.
 */
export declare class DynamicPolygon<Point extends DynamicPolygonPoint = DynamicPolygonPoint> implements DynamicPolygonPointParent<DynamicPolygonPoint> {
    readonly name: string;
    protected readonly _api: BimCoreApi;
    dragPointPositioningFunction?: DragPointPositioningFunction | undefined;
    private static readonly _tmp;
    /**
     * The drag point for this polygon.
     * @hidden
     * @internal
     */
    _dragPoint?: Point;
    private _dragPointPreviousPosition;
    private readonly _interiorPointTracker;
    private _polygonMesh;
    private _interiorPoint;
    private _polygonSurfaceArea;
    private _polygonBottomArea;
    private _polygonVolume;
    height: number;
    /**
     * Plane all points of the polygon must lie on.
     */
    private _plane;
    private _pointFactory;
    private _rotMat;
    private _centroidInWorld;
    private static readonly _renderingGroupOnTop;
    private _isEnabled;
    private _flatVertexData;
    private _vertexData;
    private _parent?;
    protected _onParentWorldMatrixUpdateObserver: Nullable<Observer<TransformNode>>;
    get parent(): TransformNode | undefined;
    /**
     * Sets the parent of the DynamicPolygon without keeping the position in world space.
     * @param node new parent for the DynamicPolygon.
     */
    set parent(node: TransformNode | undefined);
    /**
     * @hidden
     * @internal
     */
    readonly _dynamicPolygonPointTracker: CoordinateTracker<DynamicPolygonPoint>;
    /** Points to first point of the polygon.
     * @hidden
     * @internal
     */
    _head?: DynamicPolygonPoint;
    /**
     * @hidden
     * @internal
     */
    _minPoints: number;
    /**
     * Triggered when {@link DynamicPolygon.apply} is called or when camera moves around. By listening to this
     * event, it is possible to know when new polygon points are added, updated and removed. It is also possible
     * to see how far away the points are from the camera. And to see what position they have in 2D space (for example, to
     * add a HTML element to the DOM).
     */
    readonly onPointTrackableScreen: Observable<TrackCoordinate2D<Point>>;
    /**
     * Triggered when {@link DynamicPolygon.apply} is called or when camera moves around. By listening to this
     * event it is possible to know when the area label X,Y position is updated (This always exists on a DynamicPolygon). It is also possible
     * to see how far away the points are from the camera. What position they have in 2D space (perhaps one wants
     * to add a HTML element to the DOM there.).
     */
    readonly onAreaLabelTrackableScreen: Observable<TrackCoordinate2D<Vector3>>;
    /**
     * Polygon constructor, counter-clockwise polygon winding order.
     * @param name Name of polyline
     * @param _api {@link BimCoreApi} instance
     * @param pointFactory Factory method which is used to create the instances of generic class type `Point`.
     * @param recalculate2DEachFrame If `true` then it updates the 2D positions for each tracked 3D coordinate at the end of each frame.
     * @param parent If Babylon TransformNode is provided the dynamic polygon will attach as a child and follow its parent.
     * @param dragPointPositioningFunction Function to calculate the drag points position in the polygon.
     */
    constructor(name: string, _api: BimCoreApi, pointFactory: DynamicPolygonPointFactoryHandler<Point>, recalculate2DEachFrame?: boolean, parent?: TransformNode, dragPointPositioningFunction?: DragPointPositioningFunction | undefined);
    registerParentWorldMatrixCallback(): void;
    /**
     * Get the world matrix of this DynamicPolygon
     * @returns the world matrix for this DynamicPolygon.
     */
    worldMatrix(): Matrix;
    /**
     * Plane spanned by points. Only updated when {@link DynamicPolygon.build} or {@link DynamicPolygon.assignNewPolygonPoints} is called.
     * @return The Plane.
     */
    get plane(): Plane;
    /**
     * @returns `true` if polygon has no points. Otherwise `false`.
     */
    get isEmpty(): boolean;
    /**
     * Whether or not the mesh is disposed or not.
     * @return boolean.
     */
    get isDisposed(): boolean;
    /**
     * Polygon surface area. Only updated when {@link DynamicPolygon.apply} or {@link DynamicPolygon.build} is called.
     * @return The polygon surface area.
     */
    get surfaceArea(): number;
    /**
     * Polygon bottom area. Only updated when {@link DynamicPolygon.apply} or {@link DynamicPolygon.build} is called.
     * Calculated with polygonArea function with a height of zero.
     * @return The polygon bottom area.
     */
    get bottomArea(): number;
    /**
     * Polygon volume. Only updated when there exists a height and {@link DynamicPolygon.apply} or {@link DynamicPolygon.build} is called.
     * @return The polygon volume.
     */
    get volume(): number;
    /**
     * Interior point. Only updated when {@link DynamicPolygon.apply} or {@link DynamicPolygon.build} is called.
     * @return The interior point.
     */
    get interiorPoint(): Vertex3;
    /**
     * BabylonJS mesh.
     * @return mesh
     */
    get mesh(): Mesh;
    /**
     * If transformPointsToLocal is `true`, transforms all provided points according to this DynamicPolygon's parent. In either case, validate points and return the validation result
     * @param points The points to transform
     * @param transformPointsToLocal Whether to transform the points to the DynamicPolygon's parent local space before validating them
     * @returns The validation result
     * @internal NOTE: Internal API. Subject to change. Use of these APIs in production applications is not supported.
     */
    transformAndValidatePoints(points: Vertex3[], transformPointsToLocal: boolean): DynamicPolygonPointValidationResult;
    /**
     * Assigns points to define the polygon, this method can be used instead of build which adds virtual points
     * @param dynamicPolygonPoints
     */
    assignNewPolygonPoints(dynamicPolygonPoints: Point[]): void;
    /**
     * Attempt to build a {@link DynamicPolygon} using the `points` parameter.
     * @param points {@link Vertex3} points.
     * @param transformPointsToLocal Wheter to transform the points to the DynamicPolygon's parent local space before using them to build
     * @returns returns a {@link DynamicPolygonPointValidationResult}.
     */
    build(points: Vertex3[], transformPointsToLocal?: boolean): DynamicPolygonPointValidationResult;
    /**
     * Validates the specified `points`.
     * @param points {@link Vertex3} points.
     * @returns returns a {@link DynamicPolygonPointValidationResult}.
     */
    static validatePoints(points: Vertex3[], minPoints?: number): DynamicPolygonPointValidationResult;
    /**
     * Validates the specified `points`.
     * @internal
     * @hidden
     * @param points {@link Vertex3} points.
     * @returns returns a {@link DynamicPolygonPointValidationResult}.
     */
    _validatePoints(points: Vertex3[]): DynamicPolygonPointValidationResult;
    /**
     * Sets isEnabled on the dynamicpolygon and sets isEnabled on the polygon mesh if it has any points.
     * @param b state to set
     */
    set isEnabled(b: boolean);
    /**
     * @returns `true` if the dynamic polygon is enabled otherwise `false`.
     */
    get isEnabled(): boolean;
    /**
     * Applies changes to polygon which occurred when
     * calling methods on {@link DynamicPolygonPoint.move},
     * {@link DynamicPolygonPoint.virtual} and {@link DynamicPolygonPoint.delete}.
     * It will also trigger {@link DynamicPolygon.onPointTrackableScreen} events.
     */
    apply(): void;
    /**
     * Clears the polygon of all current points
     */
    clear(): void;
    /**
     * Disposes the {@link DynamicPolygon}. It is no longer useable after this call.
     */
    dispose(): void;
    /**
     * Required by {@link DynamicPolygonPointParent}.
     * @hidden
     * @internal
     */
    _virtualPointFactory(): DynamicPolygonPoint;
    /**
     * Creates a new Point instance, using the DynamicPolygon's PointFactory. Used by DynamicPolygonWithArbitraryPoints
     * @param isVirtual Determines if the created point should be virtual or not
     * @returns The new point
     * @internal
     * @hidden
     */
    createPoint(isVirtual?: boolean): Point;
    private static buildPlaneToRef;
    /**
     * @hidden
     * @internal
     * @param parent The point to constrain the other point to.
     * @param child The point that will be constrained based on the parent point.
     * @param parentPreviousPosition previous position of the parent point.
     */
    constrainChild(parent: DynamicPolygonPoint, child: DynamicPolygonPoint, parentPreviousPosition: Vertex3): void;
    private updateMeshFromPoints;
    private getInteriorPointToRef;
    private getPolygonArea;
    private getPolygonVolume;
    private transformVertex3ToRef;
    private static rotationAcordingToPointsOrientationToRef;
    private throwOnDisposed;
    private createMesh;
    points(predicate?: (p: DynamicPolygonPoint) => boolean, backwards?: boolean): Generator<DynamicPolygonPoint, void, unknown>;
}
//# sourceMappingURL=DynamicPolygon.d.ts.map