/** @internal NOTE: Internal APIs. Subject to change. Use of these APIs in production applications is not supported. */ /** */
import { Keyboard } from './keyboard';
import '../MapExtensions';
import { Engine, Scene, Mesh, HemisphericLight, BoundingInfo, TransformNode, Observable, Color3, PerfCounter, Ray, TargetCamera } from './babylonjs-import';
import { Geometry3dHandle, Geometry3d } from './vertex-data-merge';
import { Materials } from './materials';
import { ViewerCamera } from '../camera/ViewerCamera';
import { Selectables, CanvasPosition } from './Selectables';
import { TwinfinityCameraStateSnapshot } from '../camera/TwinfinityCameraStateSnapshot';
import { ShortFrustumDepthRenderer } from './ShortFrustumDepthRenderer';
import { ClipPlaneOptions } from './ClipPlane';
import { PickResult } from './PickResult';
import { PointerInfoWithTimings } from '../PointerInfoWithTimings';
import { DitheringTextureMode } from './CustomBabylonMaterials/DitherTexture';
import { IFCLightingEnvironment } from './IfcLightingEnvironment';
import { VisualSettings } from './VisualSettings';
import { DistanceToCamera } from './DistanceToCamera';
/** Options to control a 3D help grid */
export interface GridOptions {
    /** Whether grid shall be shown or not */
    isEnabled: boolean;
    /** Line color */
    lineColor?: Color3;
    /** color between lines */
    mainColor?: Color3;
    /** How far apart lines are supposed to be. */
    lineDistanceInMeter?: number;
    /** Offset of grid along y axis. Default is 0. */
    y?: number;
}
export declare enum TransparencyMode {
    Seethrough = 0,
    Dithering = 1
}
export interface RunRenderLoopHandler {
    (runRenderLoop: () => void): void;
}
/**
 * Options for adding or updating an environment (world) in the Twinfinity Viewer.
 * Used by {@link TwinfinityViewer.addOrUpdateEnvironment}.
 */
export interface AddOrUpdateEnvironmentOptions {
    /**
     * The bounding info of the environment (world).
     */
    boundingInfo: BoundingInfo;
    /**
     * Position the camera so it fits the bounds provided by {@link boundingInfo}. Default is `true`.
     * It ensures that the entire {@link boundingInfo} is visible and sets the maximum z-coordinate of the camera to a reasonable value that
     * allows everything with {@link boundingInfo} to be visible. However if camera is moved too far away from {@link boundingInfo} then
     * the camera will still not be able to see everything.
     */
    positionCameraToFitBounds?: boolean;
}
/**
 * Performance options for {@link TwinfinityViewer}.
 */
export interface TwinfinityViewerPerformanceOptions {
    /**
     * Set to `true` to disable rendering all together. Default is `true`.
     */
    isPaused: boolean;
    /**
     * Performance settings only applicable to IFC objects.
     */
    readonly ifc: {
        /**
         * Hides expensive models when rotating or moving the camera to increase performance.
         * A bounding sphere will be created around the pivot point when moving the camera, any mesh intersecting that sphere will not be hidden.
         */
        readonly hideExpensiveMeshesOnCameraMove: {
            isEnabled: boolean;
            /**
             * Radius of bounding sphere that will be created around the pivot point to check for meshes to keep.
             */
            pickBoundingSphereRadius: number;
            /**
             * Keeps meshes near the intersecion between the 3d model and the cameras forward vector.
             */
            keepMeshesNearPointOfInterest: boolean;
            /**
             * Keeps meshes near the intersection between the pivot point and the model.
             */
            keepMeshesNearPivotPoint: boolean;
            /**
             * Delay until culling stops after camera stops moving in miliseconds.
             */
            delayUntilCullingStops: number;
        };
    };
    /**
     * If <= 0 then frames are always rendered regardless if user is doing something or not.
     * If > 0 and also {@link forceRenderingTimeoutInMs} > 0 then rendering stops when camera has been stationary for this many milliseconds. As soon
     * as camera is moved rendering resumes in full again.
     * Default is 10000
     */
    idleRenderingTimeoutInMs: number;
    /**
     * If <= 0 then frames are always rendered regardless if user is doing something or not.
     * If > 0 and if {@link idleRenderingTimeoutInMs} > 0 then one frame is always rendered whenever this
     * interval has passed. Default is 1500
     */
    forceRenderingTimeoutInMs: number;
    /**
     * Specifies whether backface culling is enabled or not.
     * Backface culling is a technique used in 3D computer graphics to improve rendering performance by discarding polygons that are not visible to the viewer.
     * When backface culling is enabled, only the front-facing polygons are rendered, while the back-facing polygons are discarded.
     * If geometries are not rendered correctly (they have "holes"), try setting to `false`. This will make rendering slower but geometries with incorrect
     * polygon windingorder will be rendered correctly.
     * This is a global setting and affects all geometries in the scene.
     */
    isBackfaceCullingEnabled: boolean;
}
/**
 * Represents a TwinfinityViewer, which is responsible for rendering and interacting with a 3D scene.
 * There can only be one TwinfinityViewer.
 */
export declare class TwinfinityViewer {
    readonly canvas: HTMLCanvasElement;
    private readonly _runRenderLoop;
    private static _temp;
    private static _engine?;
    private _isRenderLoopStarted;
    private _ifcRootNode?;
    private _currentlyPickedItemKeys;
    private _movementRenderTimeout;
    private _lastCanvasSize;
    /** @hidden */
    static _isTouch: boolean;
    readonly scene: Scene;
    readonly keyboard: Keyboard;
    /**
     * Subscribe to get access to pointer events (mouse, touchpad etc) and to determine
     * what (if anything) a mouse click interacted with (what object was 'picked' in the 3D scene).
     */
    readonly onPointerObservable: Observable<import("@babylonjs/core").DeepImmutableObject<PointerInfoWithTimings>>;
    readonly grid: GridOptions;
    readonly statistics: {
        mesh: {
            verticeCount: PerfCounter;
            triangleCount: PerfCounter;
            count: PerfCounter;
        };
        addOrUpdateProducts: {
            totalTime: PerfCounter;
            meshCreationTime: number;
            meshMergeTime: number;
            meshAllocateMemoryTime: number;
        };
    };
    addOrUpdateProductOptions: {
        meshMerge: {
            deadline: number;
            sleepInMs: number;
        };
    };
    /**
     * Performance options.
     * @beta
     */
    performance: TwinfinityViewerPerformanceOptions;
    private readonly _environment;
    private readonly _gpuSelectables;
    private readonly _debugLayerEnabledPromise;
    private _depthRenderer?;
    private _cameraChangedThisFrame;
    private _timeSinceLastCameraMove;
    /** @hidden for internal use only.*/
    _materials: Materials;
    /**
     *  Controls the visual settings of the viewer. See {@link VisualSettings} for more information.
     *  @remarks Visual settings are things like global lightning but also how transparency is handled for IFC objects etc.
     */
    readonly visualSettings: VisualSettings;
    private _adaptiveMinZ;
    /**
     * Tracks minimum distance from currently rendered visible meshes to camera.
     * Only valid during and directly after a frame has been rendered.
     * It is updated automatically each frame and only visible meshes are considered.
     * @internal
     * @hidden
     */
    readonly _meshDistanceToCamera: DistanceToCamera;
    private constructor();
    /**
     * @deprecated Should not be used, there should exist a API method for changing lighting
     * Should this be removed? Is it used by Jaxel? Otherwise normal constructor injection should be used
     */
    get globalLight(): HemisphericLight;
    /**
     * Gets the current lighting settings, allowing you to change them on the fly.
     */
    get lightingProperties(): IFCLightingEnvironment;
    buildingMeshes(): IterableIterator<Mesh>;
    get selectables(): Selectables;
    static create(canvas: HTMLCanvasElement, materials: Materials, runRenderLoop: RunRenderLoopHandler): TwinfinityViewer;
    private reactToResize;
    get isSkyboxEnabled(): boolean;
    set isSkyboxEnabled(enabled: boolean);
    /**
     * Controls wheter to automatically adapt the near plane of the camera to preserve precision when viewing far away IFC objects when there are no close IFC objects
     */
    get adaptiveMinZ(): boolean;
    set adaptiveMinZ(enabled: boolean);
    get isTouch(): boolean;
    get engine(): Engine;
    get camera(): ViewerCamera;
    /**
     * Creates a renderer that that writes out the scenes depth to a render target texture which can be sampled for various uses like SSAO and line detection.
     * Unlike Babylonjs standard depth renderer, this renderer applies a custom depth material to the IFC meshes to be able to dicard the depth writes for fragments that are invisible
     *
     * @param storeNonLinearDepth Wheter or not the custom depth renderer material should write the depth linearly or logarithmic
     * @returns The depth renderer
     */
    enableDepthRenderer(storeNonLinearDepth: boolean): ShortFrustumDepthRenderer;
    get ifcRootNode(): TransformNode;
    /**
     * @hidden
     * @internal
     */
    get _cameraStateSnapshot(): TwinfinityCameraStateSnapshot | undefined;
    /**
     * Enables or disables the debug layer. Will only be available if the module
     * 'import "@twinfinity/core/internal/Debug' has also been added to the application. Adding it will
     * generate extra .js files during bundling (which are quite large) and will increase build times.
     * The extra files are loaded on demand though (when debug layer becomes enabled for the first time).
     * @param isEnabled `true` to enable. Otherwise `false`. If Not specified then current state of debug layer is returned.
     * @returns Promise which when resolved is `true` if layer is enabled. Otherwise `false`
     */
    isDebugLayerEnabled(isEnabled?: boolean): Promise<boolean>;
    get axes(): boolean;
    set axes(isEnabled: boolean);
    /**
     * Forces render loop to temporarily wake up if it is sleeping
     */
    wakeRenderLoop(): void;
    clear(): void;
    /**
     * @internal
     */
    dispose(): void;
    /**
     * Adds or updates the environment settings for the viewer.
     * @param boundingInfo AABB.
     * This method calculates the starting position for the camera based on the provided `boundingInfo`.
     * It ensures that the entire `boundingInfo` is visible and sets the maximum z-coordinate of the {@link camera} to a value that
     * allows everything to be visible.
     * Additionally, it creates a skybox and sets its position and scaling based on the `boundingInfo`.
     * The skybox is only visible if the {@link isSkyboxEnabled} property is set to `true`.
     */
    addOrUpdateEnvironment(boundingInfo: BoundingInfo): void;
    /**
     * Adds or updates the environment settings for the viewer.
     * @param options The options for the environment settings.
     * This method calculates the starting position for the camera based on the provided `boundingInfo`.
     * It ensures that the entire `boundingInfo` is visible and sets the maximum z-coordinate of the camera to a value that
     * allows everything to be visible.
     * Additionally, it creates a skybox and sets its position and scaling based on the `boundingInfo`.
     * The skybox is only visible if the {@link isSkyboxEnabled} property is set to `true`.
     */
    addOrUpdateEnvironment(options: AddOrUpdateEnvironmentOptions): void;
    private ensureRenderLoopRunning;
    /**
     * @deprecated Use {@link ViewerCamera.pick} instead.
     */
    getAndUpdatePickCamera(rayOrScreenCoordinate?: Ray | CanvasPosition): TargetCamera;
    /**
     * @deprecated Use {@link ViewerCamera.pick} instead.
     */
    pick(pickingCamera: TargetCamera, textureSizePow2?: number, doIntersectionTestOnGeometry?: boolean, saveRenderedGpuPickingSceneTexture?: boolean): PickResult;
    /**
     * Adds a mesh to the scene based on the provided geometry. If a mesh with the same ID already exists, it will be removed and replaced with the new one.
     *
     * @param geometry3D Mesh to add or replace
     * @returns Babylon mesh that was added
     */
    addOrReplaceMesh(geometry3D: Geometry3d): Mesh;
    removeMesh(geometry3D: Geometry3dHandle): Mesh | undefined;
    /**
     * Diagnostic method to measure actual GPU buffer memory usage.
     * Call from browser console: viewer.measureGpuBufferMemory()
     */
    measureGpuBufferMemory(): {
        totalBytes: number;
        bufferCount: number;
        meshCount: number;
    };
    private onCustomLODSelector;
    /**
     * Enables or disables a clip plane, indexed from 1 to 6. Enabling a clip plane means that all geometry inside the clip plane will not be rendered.
     * Note that this is only clipping for the IFC models, regular Babylon meshes needs to have clipping applied through the clip planes in Babylons scene
     * Like this: https://doc.babylonjs.com/features/featuresDeepDive/scene/clipPlanes, the docs says that only 4 planes are available, but there are 6
     *
     * @param clipPlaneOptions An object with the options for enabling or disabling clip planes.
     */
    setClipPlane(clipPlaneOptions: ClipPlaneOptions): void;
    /**
     * Changes how transparency is handled for transparent IFC objects
     * @param transparencyMode The type of rendering that will be used for all transparent IFC objects, dithering means that pixels are
     * rendered opaque but skipping every few pixels in a screen pattern depending on the opacity
     * Seethrough is normal alpha blending
     */
    setTransparencyMode(transparencyMode: TransparencyMode): void;
    /**
     * Gets the currently active mode of transparency
     */
    getTransparencyMode(): TransparencyMode;
    /**
     * Set the dither mode and animated frames used for dithering
     * @param ditherMode What dithering mode to use, bayer uses a bayer matrix to determine which pixels to render opaque, blue noise uses a blue noise texture
     * @param animatedFrames How many frames to use for the dithering animation when moving the camera, if 1 then no animation is used. Works best with Blue Noise
     */
    setDitheringMode(ditherMode: DitheringTextureMode, animatedFrames: number): void;
    /**
     * Set the currently used dither mode for solid objects that are dithered, never for transparent objects, even if the transparency mode is dithering
     * @param ditherDiscardDepth Wheter or not to discard fragments in the depth shader that are dithered, this is needed for transparent objects to not write to the depth buffer
     */
    setDitheringDepthDiscardMode(ditherDiscardDepth: boolean): void;
    private updateGridVisuals;
    private updateWorldAxesVisuals;
    private updateSkyboxVisuals;
}
//# sourceMappingURL=twinfinity-viewer.d.ts.map