import { Loader } from 'three'; import type { LoadingManager } from 'three'; import type { GaussianSplats, GaussianSplatsAttributeMode, GaussianSplatsSortAlgorithm } from './GaussianSplats.cjs'; export type GaussianSplatSourceFormat = 'ply' | 'splat' | 'splats' | 'sog'; export type GaussianSplatsWorkerMode = boolean | 'auto'; export type GaussianSplatsProcessingStage = 'source-parse' | 'sanitize' | 'morton-ordering' | 'chunk-bounds' | 'complete'; export interface GaussianSplatsProcessingProgress { type: 'processing'; stage: GaussianSplatsProcessingStage; loaded: number; total: number; progress: number; } export type GaussianSplatsProcessProgressCallback = (progress: GaussianSplatsProcessingProgress) => void; export type GaussianSplatsLoadCallback = (splats: GaussianSplats) => void; export type GaussianSplatsNetworkProgressCallback = (event: ProgressEvent) => void; export type GaussianSplatsLoadErrorCallback = (error: unknown) => void; /** Accepted parse inputs: resident bytes, a fetch Response, or a raw byte stream. */ export type GaussianSplatsParseSource = ArrayBuffer | Response | ReadableStream; export interface GaussianSplatsLoaderOptions { maxSplats?: number | undefined; maxBufferBytes?: number | undefined; enableSH?: boolean | undefined; shDegree?: number | undefined; frustumCulling?: boolean | undefined; sortEnabled?: boolean | undefined; sortAlgorithm?: GaussianSplatsSortAlgorithm | undefined; mortonOrdering?: boolean | undefined; worker?: GaussianSplatsWorkerMode | undefined; workerThreshold?: number | undefined; transferSourceBuffer?: boolean | undefined; maxStdDev?: number | undefined; attributeMode?: GaussianSplatsAttributeMode | undefined; /** Expanded SH storage precision: packed half floats (default) or float32. */ shFormat?: 'half' | 'float' | undefined; signal?: AbortSignal | undefined; onProcessProgress?: GaussianSplatsProcessProgressCallback | undefined; [name: string]: unknown; } export interface GaussianSplatsLoaderDefaultOptions extends GaussianSplatsLoaderOptions { maxSplats: number; enableSH: boolean; shDegree: number; frustumCulling: boolean; sortEnabled: boolean; sortAlgorithm: GaussianSplatsSortAlgorithm; mortonOrdering: boolean; worker: GaussianSplatsWorkerMode; workerThreshold: number; } export interface GaussianSplatsLoadTimings { sourceParseMilliseconds: number; sanitizeMilliseconds: number; mortonMilliseconds: number; chunkBoundsMilliseconds: number; /** Fused permute + sanitize + GPU-layout pack + chunk-bounds pass (packed loads only). */ packMilliseconds?: number | undefined; workerMilliseconds?: number | undefined; } export interface GaussianSOGImage { data: Uint8Array | Uint8ClampedArray; width: number; height: number; via?: 'webgl' | 'image-decoder' | 'canvas' | undefined; } interface GaussianSOGMissingImage { data: null; } type GaussianSOGImageResult = GaussianSOGImage | GaussianSOGMissingImage; export type GaussianSOGImageCollection = Record; interface GaussianSOGAttributeMetadata extends Record { bands?: number | undefined; count?: number | undefined; mins?: number | number[] | undefined; maxs?: number | number[] | undefined; codebook?: Array | null | undefined; files?: string[] | undefined; } type GaussianSOGMetadataField = GaussianSOGAttributeMetadata | string; export interface GaussianSOGMetadata extends Record { version?: number | undefined; count?: number | undefined; mins?: number[] | undefined; maxs?: number[] | undefined; means?: GaussianSOGMetadataField | undefined; quats?: GaussianSOGMetadataField | undefined; scales?: GaussianSOGMetadataField | undefined; sh0?: GaussianSOGMetadataField | undefined; sh?: GaussianSOGMetadataField | undefined; shN?: GaussianSOGMetadataField | undefined; } export interface GaussianSOGSource { images: GaussianSOGImageCollection; meta: GaussianSOGMetadata; version: number; } export interface GaussianSOGSphericalHarmonics { labels: Uint32Array; palette: Float32Array; coefficientCount: number; } export interface GaussianSOGPaletteResult { sogSH: GaussianSOGSphericalHarmonics | null; shDegree: number; } export interface GaussianSOGExpandedSHResult { shCoefficients: Float32Array | null; shDegree: number; } interface GaussianSplatDataCommon extends Record { count: number; shDegree: number; shCoefficients: Float32Array | null; /** Packed half-float SH (two uint32 per coefficient, splat-major) from the fused pack path. */ shCoefficientsHalf?: Uint32Array | null | undefined; /** Output→source permutation the GPU applies to shCoefficientsHalf (null = already final order). */ shPermutation?: Uint32Array | null | undefined; /** Pre-interleaved [position, scale] vec4 pairs from the fused pack path. */ packedPositionsScales?: Float32Array | null | undefined; /** Pre-interleaved [rotation, color] vec4 pairs from the fused pack path. */ packedRotationsColors?: Float32Array | null | undefined; normals?: Float32Array | null; sourceFormat?: GaussianSplatSourceFormat | undefined; chunkBounds?: Float32Array | undefined; chunkSize?: number | undefined; chunkBoundsMaxStdDev?: number | undefined; sogSource?: GaussianSOGSource | undefined; sogSH?: GaussianSOGSphericalHarmonics | null | undefined; version?: number | undefined; } export interface GaussianExpandedSplatData extends GaussianSplatDataCommon { positions: Float32Array; scales: Float32Array; rotations: Float32Array; colors: Float32Array; } export interface GaussianDirectSOGSplatData extends GaussianSplatDataCommon { positions: null; scales: null; rotations: null; colors: null; sogSource: GaussianSOGSource; } /** Expanded data whose arrays were fused-packed into the GPU layouts by the loader. */ export interface GaussianPackedExpandedSplatData extends GaussianSplatDataCommon { positions: null; scales: null; rotations: null; colors: null; packedPositionsScales: Float32Array; packedRotationsColors: Float32Array; } export type GaussianSplatData = GaussianExpandedSplatData | GaussianDirectSOGSplatData | GaussianPackedExpandedSplatData; export interface GaussianSplatsWorkerOptions { maxSplats: number | undefined; maxBufferBytes: number | undefined; enableSH: boolean | undefined; shDegree: number | undefined; mortonOrdering: boolean | undefined; maxStdDev: number | undefined; attributeMode: GaussianSplatsAttributeMode | undefined; shFormat: 'half' | 'float' | undefined; } export interface GaussianSplatsWorkerResult { data: GaussianSplatData; timings: GaussianSplatsLoadTimings; } export interface GaussianSplatsWorkerParseRequest { type: 'parse'; buffer: ArrayBuffer | ReadableStream; url: string; options: GaussianSplatsWorkerOptions; } export interface GaussianSplatsWorkerProgressMessage { type: 'progress'; progress: GaussianSplatsProcessingProgress; } export interface GaussianSplatsWorkerReadyMessage { type: 'ready'; } export interface GaussianSplatsWorkerResultMessage { type: 'result'; result: GaussianSplatsWorkerResult; } export interface GaussianSplatsSerializedError { name: string | undefined; message: string; stack: string | undefined; } export interface GaussianSplatsWorkerErrorMessage { type: 'error'; error: GaussianSplatsSerializedError; } export type GaussianSplatsWorkerResponse = GaussianSplatsWorkerReadyMessage | GaussianSplatsWorkerProgressMessage | GaussianSplatsWorkerResultMessage | GaussianSplatsWorkerErrorMessage; type PLYTypeName = 'char' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'float' | 'double' | 'int8' | 'uint8' | 'int16' | 'uint16' | 'int32' | 'uint32' | 'float32' | 'float64'; interface PLYTypeDefinition { size: number; read: (dataView: DataView, offset: number, littleEndian?: boolean) => number; } export interface PLYProperty { name: string; type: PLYTypeName; size: number; } interface ResolvedPLYProperty { offset: number; read: PLYTypeDefinition['read']; type: PLYTypeName; } export type PLYPropertyTable = Record; export declare const DEFAULT_WORKER_THRESHOLD: number; export declare function getExtension(url: string): string; export declare function throwUnsupportedFormat(ext: string): never; export declare function createAbortError(signal: AbortSignal | undefined): Error; export declare function throwIfAborted(signal: AbortSignal | undefined): void; /** Collect a byte stream into a single contiguous ArrayBuffer. */ export declare function accumulateStream(stream: ReadableStream, signal: AbortSignal | undefined): Promise; interface ExpandedFinalizeResult { data: GaussianSplatData; sanitizeMilliseconds: number; mortonMilliseconds: number; chunkBoundsMilliseconds: number; packMilliseconds: number; } /** True when a load will use the fused GPU-layout pack path (packed source + half SH). */ export declare function isPackEligible(options: GaussianSplatsLoaderOptions): boolean; /** * Shared post-parse pipeline for expanded splat data: sanitize, Morton-order, chunk bounds. * * The default path fuses all three into a single pass that also writes the expanded GPU * buffer layouts (interleaved vec4 pairs, packed half-float SH), so the main thread wraps the * arrays as storage attributes without further copying. Modes that need planar float arrays * (compact/auto quantization, custom source factories, mortonOrdering:false) keep the legacy * planar pipeline. */ export declare function finalizeExpandedSplatData(data: GaussianExpandedSplatData, options: GaussianSplatsLoaderOptions): ExpandedFinalizeResult; /** * Calculate maximum supported splats based on GPU buffer limits. * @param {number} shDegree - SH degree (0-3) * @param {boolean} enableSH - Whether SH is enabled * @param {boolean} compressedSH - Whether SH uses per-splat palette labels. * @returns {number} Maximum supported splat count */ export declare function getMaxSupportedSplats(shDegree: number | undefined, enableSH: boolean | undefined, compressedSH?: boolean, maxBufferSize?: number, halfSH?: boolean): number; /** @internal Shared byte parser for the loader and its worker. */ export declare class GaussianSplatsDataParser extends Loader { defaultOptions: GaussianSplatsLoaderDefaultOptions; /** * Create a GaussianSplatsLoader. * * @param {THREE.LoadingManager} [manager] Loading manager. */ constructor(manager?: LoadingManager); _parseDataAsync(buffer: ArrayBuffer | ReadableStream, url: string, options?: GaussianSplatsLoaderOptions): Promise; /** * Parse PLY format. * @private * @param {ArrayBuffer} buffer * @param {number} maxSplats Maximum splats to load. * @returns {Object} Parsed data. */ protected _parsePLY(buffer: ArrayBuffer, maxSplats: number, packSHHalf?: boolean): GaussianExpandedSplatData; /** * Detect SH degree from property names. * @private * @param {Object} propIndex Property name to index map. * @returns {number} SH degree (0-3). */ protected _detectSHDegree(propIndex: PLYPropertyTable): number; /** * Parse SPLAT format (packed binary). * Standard format used by antimatter15/splat, SuperSplat, etc. * @private * @param {ArrayBuffer} buffer * @param {number} maxSplats Maximum splats to load. * @returns {Object} Parsed data. */ protected _parseSPLAT(buffer: ArrayBuffer, maxSplats: number): GaussianExpandedSplatData; /** * Parse compressed PLY format with per-chunk bounds (PlayCanvas/SuperSplat format). * * Data layout (SEQUENTIAL, not interleaved): * 1. ALL chunk headers (72 bytes each × numChunks) * 2. ALL vertex data (16 bytes each × numVertices) * 3. ALL SH data (optional, N bytes each × numVertices) * * @private * @param {ArrayBuffer} buffer * @param {number} numChunks Number of chunks (from "element chunk N") * @param {number} vertexCount Number of vertices (from "element vertex N") * @param {number} shElementCount Number of SH elements (from "element sh N") * @param {Array} chunkProperties Properties for chunk element * @param {Array} vertexProperties Properties for vertex element * @param {Array} shProperties Properties for SH element * @param {number} dataOffset Byte offset where binary data starts * @param {boolean} isLittleEndian Endianness * @param {number} maxSplats Maximum splats to load * @returns {Object} Parsed data. */ protected _parseCompressedPLYWithBounds(buffer: ArrayBuffer, numChunks: number, vertexCount: number, shElementCount: number, _chunkProperties: readonly PLYProperty[], _vertexProperties: readonly PLYProperty[], shProperties: readonly PLYProperty[], dataOffset: number, isLittleEndian: boolean, maxSplats: number): GaussianExpandedSplatData; /** * Parse SOG format (PlayCanvas compressed WebP-based format). * SOG files are ZIP archives containing meta.json and WebP images. * Achieves ~15-20x compression compared to PLY. * * @private * @param {ArrayBuffer} buffer ZIP archive data. * @param {number} maxSplats Maximum splats to load. * @param {Object} [options] SOG parsing options. * @param {boolean} [options.direct=false] Preserve packed base attributes for GPU-side decoding. * @returns {Promise} Parsed data. */ protected _parseSOG(buffer: ArrayBuffer, maxSplats: number, { direct }?: { direct?: boolean | undefined; }): Promise; _createDirectSOGData(images: GaussianSOGImageCollection, meta: GaussianSOGMetadata, count: number, version: number, sogSource: GaussianSOGSource): GaussianDirectSOGSplatData; _parseSOGSphericalHarmonicsPalette(labelsImg: GaussianSOGImage, centroidsImg: GaussianSOGImage, meta: GaussianSOGMetadata, count: number, imgWidth: number): GaussianSOGPaletteResult; _validateSOGImages(images: GaussianSOGImageCollection, count: number, meta?: GaussianSOGMetadata): void; /** * Decode WebP images from SOG archive. * @private * @param {Object} files Unzipped file contents. * @param {Object} meta SOG metadata. * @returns {Promise} Decoded image data. */ protected _decodeSOGImages(files: Record, meta: GaussianSOGMetadata): Promise; /** * Dequantize SOG image data into splat arrays. * @private * @param {Object} images Decoded image data. * @param {Object} meta SOG metadata. * @param {number} count Number of splats to process. * @param {number} version SOG format version (1 or 2). * @returns {Object} Parsed data arrays. */ protected _dequantizeSOGData(images: GaussianSOGImageCollection, meta: GaussianSOGMetadata, count: number, version: number): GaussianExpandedSplatData; /** * Parse spherical harmonics coefficients from SOG label/centroid images. * @private * @param {Object} labelsImg Labels image data. * @param {Object} centroidsImg Centroids image data. * @param {Object} meta SOG metadata. * @param {number} count Number of splats. * @param {number} imgWidth Image width for pixel indexing. * @returns {Object} SH coefficients and degree. */ protected _parseSOGSphericalHarmonics(labelsImg: GaussianSOGImage, centroidsImg: GaussianSOGImage, meta: GaussianSOGMetadata, count: number, imgWidth: number): GaussianSOGExpandedSHResult; } export {};