/** @packageDocumentation
 * @module Tiles
 */
import { Point3d, Range2d, Range3d, Transform, Vector3d } from "@itwin/core-geometry";
import { AxisAlignedBox3d, BatchType, ElementAlignedBox3d, Feature, FeatureTable, MeshPolylineList, QParams2d, QParams3d, RenderTexture, TextureMapping, TileReadStatus, ViewFlagOverrides } from "@itwin/core-common";
import { IModelConnection } from "../IModelConnection";
import { InstancedGraphicParams } from "../common/render/InstancedGraphicParams";
import { Mesh } from "../common/internal/render/MeshPrimitives";
import { RenderGraphic } from "../render/RenderGraphic";
import { RenderSystem } from "../render/RenderSystem";
import { BatchedTileIdMap, RealityTileGeometry, TileContent } from "./internal";
import { DisplayParams } from "../common/internal/render/DisplayParams";
import { PointCloudArgs } from "../common/internal/render/PointCloudPrimitive";
import { TextureImageSource } from "../common/render/TextureParams";
import { GltfAccessor, GltfBuffer, GltfBufferViewProps, GltfDataType, GltfDictionary, GltfDocument, GltfId, GltfImage, GltfMaterial, GltfMesh, GltfMeshPrimitive, GltfNode, GltfSampler, GltfScene, GltfTexture, GltfWrapMode } from "../common/gltf/GltfSchema";
import { PickableGraphicOptions } from "../common/render/BatchOptions";
import { GraphicTemplate } from "../render/GraphicTemplate";
/** @internal */
export type GltfDataBuffer = Uint8Array | Uint16Array | Uint32Array | Float32Array;
/**
 * A chunk of binary data exposed as a typed array.
 * The count member indicates how many elements exist. This may be less than this.buffer.length due to padding added to the
 * binary stream to ensure correct alignment.
 * @internal
 */
export declare class GltfBufferData {
    readonly buffer: GltfDataBuffer;
    readonly count: number;
    constructor(buffer: GltfDataBuffer, count: number);
    /**
     * Create a GltfBufferData of the desired type. The actual type may differ from the desired type - for example, small 32-bit integers
     * may be represented as 8-bit or 16-bit integers instead.
     * If the actual data type is not convertible to the desired type, this function returns undefined.
     */
    static create(bytes: Uint8Array, actualType: GltfDataType, expectedType: GltfDataType, count: number): GltfBufferData | undefined;
    private static createDataBuffer;
}
/**
 * A view of a chunk of glTF binary data containing an array of elements of a specific data type.
 * The count member indicates how many elements exist; this may be smaller than this.data.length.
 * The count member may also indicate the number of elements of a type containing more than one value of the
 * underlying type. For example, a buffer of 4 32-bit floating point 'vec2' elements will have a count of 4,
 * but its data member will contain 8 32-bit floating point values (2 per vec2).
 * The accessor member may contain additional JSON data specific to a particular buffer.
 * @internal
 */
declare class GltfBufferView {
    readonly data: Uint8Array;
    readonly count: number;
    readonly type: GltfDataType;
    readonly accessor: GltfAccessor;
    readonly stride: number;
    get byteLength(): number;
    constructor(data: Uint8Array, count: number, type: GltfDataType, accessor: GltfAccessor, stride: number);
    toBufferData(desiredType: GltfDataType): GltfBufferData | undefined;
}
/** The result of [[GltfReader.read]].
 * @internal
 */
export interface GltfReaderResult extends TileContent {
    readStatus: TileReadStatus;
    range?: AxisAlignedBox3d;
}
type GltfTemplateResult = Omit<GltfReaderResult, "graphic"> & {
    template?: GraphicTemplate;
};
/** Data required for creating a [[GltfReader]] capable of deserializing [glTF](https://www.khronos.org/gltf/).
 * @internal
 */
export declare class GltfReaderProps {
    readonly version: number;
    readonly glTF: GltfDocument;
    readonly yAxisUp: boolean;
    readonly binaryData?: Uint8Array;
    readonly baseUrl?: URL;
    private constructor();
    /** Attempt to construct a new GltfReaderProps from the binary data beginning at the supplied stream's current read position. */
    static create(source: Uint8Array | GltfDocument, yAxisUp?: boolean, baseUrl?: URL): GltfReaderProps | undefined;
}
/** The GltfMeshData contains the raw GLTF mesh data. If the data is suitable to create a [[RealityMesh]] directly, basically in the quantized format produced by
  * ContextCapture, then a RealityMesh is created directly from this data. Otherwise, the mesh primitive is populated from the raw data and a MeshPrimitive
  * is generated. The MeshPrimitve path is much less efficient but should be rarely used.
  *
  * @internal
  */
export declare class GltfMeshData {
    primitive: Mesh;
    pointQParams?: QParams3d;
    points?: Uint16Array;
    pointRange?: Range3d;
    normals?: Uint16Array;
    uvQParams?: QParams2d;
    uvs?: Uint16Array;
    uvRange?: Range2d;
    indices?: Uint8Array | Uint16Array | Uint32Array;
    readonly type: "mesh";
    constructor(props: Mesh);
}
interface GltfPointCloud extends PointCloudArgs {
    readonly type: "pointcloud";
    pointRange: Range3d;
}
type GltfPrimitiveData = GltfMeshData | GltfPointCloud;
/** A function that returns true if deserialization of the data supplied by the reader should abort.
 * @internal
 */
export type ShouldAbortReadGltf = (reader: GltfReader) => boolean;
/** Arguments to [[GltfReader]] constructor.
 * @internal
 */
export interface GltfReaderArgs {
    /** Properties of the glTF source. */
    props: GltfReaderProps;
    /** The iModel with which the graphics are to be associated. */
    iModel: IModelConnection;
    /** If true, create 2d graphics. */
    is2d?: boolean;
    /** The render system that will produce the graphics. Defaults to [[IModelApp.renderSystem]]. */
    system?: RenderSystem;
    /** The type of batch to create. Defaults to [BatchType.Primary]($common).
     * @see [[RenderSystem.createBatch]].
     */
    type?: BatchType;
    /** An optional function that, if supplied, is invoked periodically to determine if the process of producing graphics from the glTF should terminate early. */
    shouldAbort?: ShouldAbortReadGltf;
    /** If true, each vertex in the graphics should belong to exactly one triangle. This is less efficient than sharing vertices between adjoining triangles, but
     * sometimes required - for example, for [ViewFlags.wiremesh]($common).
     */
    deduplicateVertices?: boolean;
    /** If true, the graphics produced will always use a [[VertexTable]]; otherwise, where possible a [[RealityMeshParams]] will be used instead.
     * Reality meshes are simpler but do not support some features like lighting.
     */
    vertexTableRequired?: boolean;
    /** A table structure to store the Gltf structural metadata if present.
     */
    idMap?: BatchedTileIdMap;
}
interface StructuralMetadataTableEntries {
    name: string;
    values: any[];
}
interface StructuralMetadataTable {
    name: string;
    entries: StructuralMetadataTableEntries[];
}
interface StructuralMetadata {
    tables: StructuralMetadataTable[];
}
/** Deserializes [glTF](https://www.khronos.org/gltf/).
 * @internal
 */
export declare abstract class GltfReader {
    protected readonly _glTF: GltfDocument;
    protected readonly _version: number;
    protected readonly _iModel: IModelConnection;
    protected readonly _is3d: boolean;
    protected readonly _system: RenderSystem;
    protected readonly _returnToCenter?: Point3d;
    protected readonly _yAxisUp: boolean;
    protected readonly _baseUrl?: URL;
    protected readonly _type: BatchType;
    protected readonly _deduplicateVertices: boolean;
    protected readonly _vertexTableRequired: boolean;
    private readonly _canceled?;
    protected readonly _sceneNodes: GltfId[];
    protected _computedContentRange?: ElementAlignedBox3d;
    private readonly _resolvedTextures;
    private readonly _dracoMeshes;
    private _containsPointCloud;
    protected _instanceFeatures: Feature[];
    protected _instanceElementIdToFeatureId: Map<string, number>;
    protected _structuralMetadata?: StructuralMetadata;
    protected readonly _idMap?: BatchedTileIdMap;
    protected get _nodes(): GltfDictionary<GltfNode>;
    protected get _meshes(): GltfDictionary<GltfMesh>;
    protected get _accessors(): GltfDictionary<GltfAccessor>;
    protected get _bufferViews(): GltfDictionary<GltfBufferViewProps & {
        resolvedBuffer?: Uint8Array;
    }>;
    protected get _materials(): GltfDictionary<GltfMaterial>;
    protected get _samplers(): GltfDictionary<GltfSampler>;
    protected get _textures(): GltfDictionary<GltfTexture>;
    protected get _images(): GltfDictionary<GltfImage & {
        resolvedImage?: TextureImageSource;
    }>;
    protected get _buffers(): GltfDictionary<GltfBuffer & {
        resolvedBuffer?: Uint8Array;
    }>;
    /** Asynchronously deserialize the tile data and return the result. */
    abstract read(): Promise<GltfReaderResult>;
    protected get _isCanceled(): boolean;
    protected get _isVolumeClassifier(): boolean;
    /** Traverse the nodes specified by their Ids, recursing into their child nodes.
     * @param nodeIds The Ids of the nodes to traverse.
     * @throws Error if a node appears more than once during traversal
     */
    traverseNodes(nodeIds: Iterable<GltfId>): Iterable<GltfNode>;
    /** Traverse the nodes specified by their scene, recursing into their child nodes.
     * @throws Error if a node appears more than once during traversal
     */
    traverseScene(): Iterable<GltfNode>;
    protected get viewFlagOverrides(): ViewFlagOverrides | undefined;
    private getTileTransform;
    protected readGltfAndCreateGraphics(isLeaf: boolean, featureTable: FeatureTable | undefined, contentRange: ElementAlignedBox3d | undefined, transformToRoot?: Transform, pseudoRtcBias?: Vector3d, instances?: InstancedGraphicParams): GltfReaderResult;
    protected readGltfAndCreateTemplate(isLeaf: boolean, featureTable: FeatureTable | undefined, contentRange: ElementAlignedBox3d | undefined, noDispose: boolean, transformToRoot?: Transform, pseudoRtcBias?: Vector3d, instances?: InstancedGraphicParams): GltfTemplateResult;
    readGltfAndCreateGeometry(transformToRoot?: Transform, needNormals?: boolean, needParams?: boolean): RealityTileGeometry;
    private geometryFromMeshData;
    private readInstanceAttributes;
    private readTemplateNodes;
    private readNodeAndCreatePolyfaces;
    private polyfaceFromGltfMesh;
    getBufferView(json: {
        [k: string]: any;
    }, accessorName: string): GltfBufferView | undefined;
    readBufferData32(json: {
        [k: string]: any;
    }, accessorName: string): GltfBufferData | undefined;
    readBufferData16(json: {
        [k: string]: any;
    }, accessorName: string): GltfBufferData | undefined;
    readBufferData8(json: {
        [k: string]: any;
    }, accessorName: string): GltfBufferData | undefined;
    readBufferDataFloat(json: {
        [k: string]: any;
    }, accessorName: string): GltfBufferData | undefined;
    protected constructor(args: GltfReaderArgs);
    protected readBufferData(json: {
        [k: string]: any;
    }, accessorName: string, type: GltfDataType): GltfBufferData | undefined;
    protected readFeatureIndices(_json: any): number[] | undefined;
    private extractId;
    private extractTextureId;
    private extractNormalMapId;
    private isMaterialTransparent;
    protected createDisplayParams(material: GltfMaterial, hasBakedLighting: boolean): DisplayParams | undefined;
    private readMeshPrimitives;
    protected readMeshPrimitive(primitive: GltfMeshPrimitive, featureTable?: FeatureTable, pseudoRtcBias?: Vector3d): GltfPrimitiveData | undefined;
    private readPointCloud2;
    private readDracoMeshPrimitive;
    private deduplicateVertices;
    /**
     *
     * @param positions quantized points
     * @param primitive input json
     * @param pseudoRtcBias a bias applied to each point - this is a workaround for tiles generated by
     * context capture which have a large offset from the tileset origin that exceeds the
     * capacity of 32 bit integers. This is essentially an ad hoc RTC applied at read time.
     */
    private readVertices;
    protected readIndices(json: {
        [k: string]: any;
    }, accessorName: string): number[] | undefined;
    protected readBatchTable(_mesh: Mesh, _json: GltfMeshPrimitive): void;
    protected readPrimitiveFeatures(_primitive: GltfMeshPrimitive): Feature | number[] | undefined;
    protected readMeshIndices(mesh: GltfMeshData, json: {
        [k: string]: any;
    }): boolean;
    protected readNormals(mesh: GltfMeshData, json: {
        [k: string]: any;
    }, accessorName: string): boolean;
    protected readColors(mesh: GltfMeshData, attribute: {
        [k: string]: any;
    }, accessorName: string): boolean;
    private readUVParams;
    protected readPolylines(polylines: MeshPolylineList, json: {
        [k: string]: any;
    }, accessorName: string, disjoint: boolean): boolean;
    protected resolveResources(): Promise<void>;
    private _resolveResources;
    private decodeDracoMesh;
    private resolveUrl;
    private resolveBuffer;
    private resolveImage;
    /** The glTF spec says that if GltfSampler.wrapS/T are omitted, they default to Repeat.
     * However, the reality data service serves tiles that lack any wrapS/T property, and we want those clamped to edge, not repeated.
     * (We also don't want to produce mip-maps for them, which is determined indirectly from the wrap mode).
     * Allow the default to be optionally overridden.
     */
    defaultWrapMode: GltfWrapMode;
    /** Exposed strictly for testing. */
    getTextureType(sampler?: GltfSampler): RenderTexture.Type;
    private resolveTexture;
    protected findTextureMapping(id: string | undefined, isTransparent: boolean, normalMapId: string | undefined): TextureMapping | undefined;
}
/** Arguments supplied to [[readGltfGraphics]] to produce a [[RenderGraphic]] from a [glTF](https://www.khronos.org/gltf/) asset.
 * @public
 * @extensions
 */
export interface ReadGltfGraphicsArgs {
    /** A representation of the glTF data as one of:
     *  - The binary data in glb format as a Uint8Array; or
     *  - A JSON object conforming to the [glTF 2.0 specification](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html); or
     *  - A Uint8Array containing the utf8-encoded stringified JSON of an object conforming to the [glTF 2.0 specification](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html).
     */
    gltf: Uint8Array | object;
    /** The iModel with which the graphics will be associated - typically obtained from the [[Viewport]] into which they will be drawn. */
    iModel: IModelConnection;
    /** Options for making the graphic [pickable]($docs/learning/frontend/ViewDecorations#pickable-view-graphic-decorations).
     * Only the [[PickableGraphicOptions.id]] property is required to make the graphics pickable. If a `modelId` is also supplied and differs from the `id`,
     * the graphics will also be selectable.
     */
    pickableOptions?: PickableGraphicOptions;
    /** The base URL for any relative URIs in the glTF. Typically, this is the same as the URL for the glTF asset itself.
     * If not supplied, relative URIs cannot be resolved. For glTF assets containing no relative URIs, this is not required.
     */
    baseUrl?: URL | string;
    /** @alpha */
    contentRange?: ElementAlignedBox3d;
    /** @alpha */
    transform?: Transform;
    /** @alpha */
    hasChildren?: boolean;
    /** @internal */
    idMap?: BatchedTileIdMap;
}
/** The output of [[readGltf]].
 * @public
 */
export interface GltfGraphic {
    /** The graphic created from the glTF model. */
    graphic: RenderGraphic;
    /** The bounding box of the model, in local coordinates (y-axis up). */
    localBoundingBox: ElementAlignedBox3d;
    /** The bounding box of the model, in world coordinates (z-axis up). */
    boundingBox: AxisAlignedBox3d;
}
/** The output of [[readGltfTemplate]].
 * @beta
 */
export interface GltfTemplate {
    /** The graphic template created from the glTF model. */
    template: GraphicTemplate;
    /** The bounding box of the model, in local coordinates (y-axis up). */
    localBoundingBox: ElementAlignedBox3d;
    /** The bounding box of the model, in world coordinates (z-axis up). */
    boundingBox: AxisAlignedBox3d;
}
/** Produce a [[RenderGraphic]] from a [glTF](https://www.khronos.org/gltf/) asset suitable for use in [view decorations]($docs/learning/frontend/ViewDecorations).
 * @returns a graphic produced from the glTF asset's default scene, or `undefined` if a graphic could not be produced from the asset.
 * @see [[readGltf]] for more details.
 * @public
 * @extensions
 */
export declare function readGltfGraphics(args: ReadGltfGraphicsArgs): Promise<RenderGraphic | undefined>;
/** Produce a [[GraphicTemplate]] from a [glTF](https://www.khronos.org/gltf/) asset suitable for use in [view decorations]($docs/learning/frontend/ViewDecorations).
 * @returns a template produced from the glTF asset's default scene, or `undefined` if a template could not be produced from the asset.
 * @see [[readGltf]] for more details.
 * @beta
 */
export declare function readGltfTemplate(args: ReadGltfGraphicsArgs): Promise<GltfTemplate | undefined>;
/** Produce a [[RenderGraphic]] from a [glTF](https://www.khronos.org/gltf/) asset suitable for use in [view decorations]($docs/learning/frontend/ViewDecorations).
 * @returns a graphic produced from the glTF asset's default scene, or `undefined` if a graphic could not be produced from the asset.
 * The returned graphic also includes the bounding boxes of the glTF model in world and local coordiantes.
 * @note Support for the full [glTF 2.0 specification](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html) is currently a work in progress.
 * If a particular glTF asset fails to load and/or display properly, please
 * [submit an issue](https://github.com/iTwin/itwinjs-core/issues).
 * @see [Example decorator]($docs/learning/frontend/ViewDecorations#gltf-decorations) for an example of a decorator that reads and displays a glTF asset.
 * @see [[readGltfTemplate]] to produce a [[GraphicTemplate]] instead of a [[RenderGraphic]].
 * @public
 */
export declare function readGltf(args: ReadGltfGraphicsArgs): Promise<GltfGraphic | undefined>;
/** Implements [[readGltfGraphics]]. Exported strictly for tests.
 * @internal
 */
export declare class GltfGraphicsReader extends GltfReader {
    private readonly _featureTable?;
    private readonly _contentRange?;
    private readonly _transform?;
    private readonly _isLeaf;
    readonly binaryData?: Uint8Array;
    constructor(props: GltfReaderProps, args: ReadGltfGraphicsArgs);
    protected get viewFlagOverrides(): ViewFlagOverrides;
    private getGltfStructuralMetadataBuffer;
    private getGltfStructuralMetadataPropertyValues;
    private readGltfStructuralMetadata;
    readTemplate(): Promise<GltfTemplateResult>;
    read(): Promise<GltfReaderResult>;
    get structuralMetadata(): StructuralMetadata | undefined;
    get nodes(): GltfDictionary<GltfNode>;
    get scenes(): GltfDictionary<GltfScene>;
    get sceneNodes(): GltfId[];
    get textures(): GltfDictionary<GltfTexture>;
}
export {};
//# sourceMappingURL=GltfReader.d.ts.map