/** * Utsubo Streamed Splats (USS v1) codec — shared by the Node exporter * (tools/splat-stream-export.mjs) and the browser runtime (GaussianSplatsStream). * * Pure TypeScript, no browser or Node APIs: typed arrays in, typed arrays out. * Format specification: packages/core/.ai/SPLAT_STREAM_FORMAT.md * * Quantization follows the compressed-PLY ecosystem conventions already used by * GaussianSplatsLoader: 11-10-11 unorm positions/log-scales, smallest-three * quaternions (2-bit dropped-component mode + 3×10-bit ×√2), RGBA8 color with * post-activation straight alpha. * * @module SplatStreamCodec */ export declare const USC_MAGIC = 826495829; export declare const USC_VERSION = 1; export declare const USC_HEADER_BYTES = 48; export declare const USC_RECORD_BYTES = 16; /** Header flags word (offset 12). Bit 0: 16-bit-per-axis positions (20-byte records). */ export declare const USC_FLAG_HIGH_PRECISION_POSITIONS = 1; export declare const USC_HIGH_PRECISION_RECORD_BYTES = 20; export declare const STREAM_MANIFEST_TYPE = "utsubo-splat-stream"; export declare const STREAM_MANIFEST_VERSION = 1; /** Cull-chunk padding convention shared with MortonOrdering.computeChunkBounds. */ export declare const STREAM_BOUNDS_MAX_STD_DEV: number; /** Three-component spatial vector used by stream bounds. */ export type SplatStreamVec3 = [number, number, number]; /** Axis-aligned bounds stored in stream manifests and computed for cells. */ export interface SplatStreamBounds { min: SplatStreamVec3; max: SplatStreamVec3; } /** One contiguous range of Morton-ordered splats. */ export interface SplatStreamCellRange { start: number; count: number; } /** Expanded float attributes accepted by the `.usc` encoder. */ export interface SplatChunkData { positions: Float32Array; scales: Float32Array; rotations: Float32Array; colors: Float32Array; } /** Options applied while encoding one `.usc` payload. */ export interface SplatChunkEncodeOptions { scaleBoost?: number; /** * Store positions as 16-bit-per-axis unorm (20-byte records) instead of packed 11-10-11 * (16-byte). 32× finer steps — required for room-scale scenes where an 11-bit axis is * ~1 px of jitter; object-scale assets keep the compact default. */ highPrecisionPositions?: boolean; } /** Absolute splat indices accepted by the `.usc` encoder. */ export type SplatChunkIndices = Uint32Array | readonly number[]; /** Binary payload shapes accepted by the `.usc` decoder. */ export type SplatChunkInput = ArrayBuffer | Uint8Array; /** Expanded float attributes returned by the `.usc` decoder. */ export interface DecodedSplatChunk extends SplatChunkData { count: number; } /** One LOD level in a USS manifest. */ export interface SplatStreamLevel { ratio: number; [key: string]: unknown; } /** One spatial cell and its per-LOD payload references. */ export interface SplatStreamCell { bounds: SplatStreamBounds; counts: number[]; files: string[]; [key: string]: unknown; } /** Normalized LOD selection parameters. */ export interface SplatStreamLOD { baseDistance: number; multiplier: number; behindPenalty: number; } /** Validated USS v1 stream manifest. Unknown extension fields are preserved. */ export interface SplatStreamManifest { version: typeof STREAM_MANIFEST_VERSION; type: typeof STREAM_MANIFEST_TYPE; count: number; bounds: SplatStreamBounds; levels: SplatStreamLevel[]; cells: SplatStreamCell[]; shDegree: number; lod: Readonly; cellSize?: number; generator?: string; [key: string]: unknown; } /** * Quantize a normalized value into an unsigned integer of `bits` width. * Shared by the USS (`.usc`) and USV (`.usw`/`.ust`) codecs. */ export declare function quantizeUnorm(value: number, bits: number): number; /** * Dequantize `bits` wide unsigned integer into [0, 1]. * Shared by the USS (`.usc`) and USV (`.usw`/`.ust`) codecs. */ export declare function unpackUnorm(value: number, bits: number): number; /** * Pack a quaternion into one u32 with the smallest-three convention shared by `.usc` * and `.usw`: `mode<<30 | a<<20 | b<<10 | c`, mode = dropped (largest-|.|) component in * (w, x, y, z) order, stored components mapped from [-1/√2, 1/√2] to 10-bit unorm, the * dropped component forced positive so sqrt reconstruction recovers the same rotation. * * @param {number} x @param {number} y @param {number} z @param {number} w Quaternion (any norm). * @returns {number} Packed u32 word. */ export declare function packQuaternionSmallestThree(x: number, y: number, z: number, w: number): number; /** * Unpack a {@link packQuaternionSmallestThree} word into a normalized xyzw quaternion. * * @param {number} word Packed u32. * @param {Float32Array} out Destination array. * @param {number} offset Destination offset (xyzw written at offset..offset+3). */ export declare function unpackQuaternionSmallestThree(word: number, out: Float32Array, offset: number): void; /** * LOD scale compensation baked into level files: boosting each log-scale by * 0.5·ln(1/ratio) grows footprint area by 1/ratio, preserving screen coverage * when only `ratio` of the splats render. * * @param {number} ratio Level subsampling ratio (0 < ratio <= 1). * @returns {number} Additive log-space scale boost. */ export declare function scaleBoostForRatio(ratio: number): number; /** * Rank a cell's splats by importance (opacity × mean linear scale) and * systematic-sample the ranked list. Taking every (1/ratio)-th entry of the * ranked ordering preserves the importance distribution — top-k-only sampling * would keep just the largest splats and destroy fine detail. * * Deterministic: same input ⇒ same output. * * @param {Float32Array} scales Log-space scales (xyz per splat), full asset arrays. * @param {Float32Array} colors RGBA (alpha in [3]), full asset arrays. * @param {number} start First splat index of the cell. * @param {number} count Cell splat count. * @param {number} ratio Subsampling ratio (0 < ratio <= 1). * @returns {Uint32Array} Selected ABSOLUTE splat indices (ascending by rank position). */ export declare function buildLevelIndices(scales: Float32Array, colors: Float32Array, start: number, count: number, ratio: number): Uint32Array; /** * Exact AABB of a splat subset, padded by maxStdDev × the largest linear scale — * the same convention as MortonOrdering.computeChunkBounds, so streamed cell * bounds slot directly into the hierarchical culling path. * * @param {Float32Array} positions xyz per splat. * @param {Float32Array} scales Log-space scales. * @param {number} start First splat index. * @param {number} count Splat count. * @param {number} [maxStdDev=√8] Splat extent padding in standard deviations. * @returns {{min:number[], max:number[]}} Padded bounds. */ export declare function computeCellBounds(positions: Float32Array, scales: Float32Array, start: number, count: number, maxStdDev?: number): SplatStreamBounds; /** * Partition `count` Morton-ordered splats into contiguous cells of at most * `cellSize` splats. Morton contiguity makes each range spatially compact. * * @param {number} count Total splats. * @param {number} cellSize Max splats per cell. * @returns {Array<{start:number, count:number}>} Cell ranges. */ export declare function partitionCells(count: number, cellSize: number): SplatStreamCellRange[]; /** * Encode a splat subset into a `.usc` chunk payload. * * @param {Object} data Splat arrays: positions (xyz), scales (LOG xyz), rotations (xyzw), colors (rgba 0-1, straight alpha). * @param {Uint32Array|number[]} indices Absolute splat indices to encode, in output order. * @param {Object} [options] * @param {number} [options.scaleBoost=0] Additive log-space scale boost baked into the file (LOD compensation). * @returns {ArrayBuffer} `.usc` payload. */ export declare function encodeChunk(data: SplatChunkData, indices: SplatChunkIndices, options?: SplatChunkEncodeOptions): ArrayBuffer; /** * Decode a `.usc` chunk payload into expanded splat arrays, ready for * ExpandedFloatSplatSource.uploadRange (log-space scales; normalized xyzw * rotations; straight rgba colors). * * @param {ArrayBuffer|Uint8Array} input `.usc` payload. * @returns {{count:number, positions:Float32Array, scales:Float32Array, rotations:Float32Array, colors:Float32Array}} */ export declare function decodeChunk(input: SplatChunkInput): DecodedSplatChunk; /** * Validate a stream manifest, returning a normalized copy. * * @param {Object} manifest Parsed manifest JSON. * @returns {Object} Frozen, validated manifest. */ export declare function validateStreamManifest(manifest: unknown): Readonly;