@playcanvas/splat-transform
Version:
Library and CLI tool for 3D Gaussian splat format conversion and transformation
108 lines (107 loc) • 4.54 kB
TypeScript
import { DataTable } from '../data-table';
import { type FileSystem } from '../io/write';
import type { CollisionMeshShape, DeviceCreator } from '../types';
import { type SparseOctree } from './sparse-octree';
import { type NavSeed } from '../voxel';
/**
* Options for writing a voxel octree file.
*/
type WriteVoxelOptions = {
/** Output filename ending in .voxel.json */
filename: string;
/** Gaussian splat data to voxelize */
dataTable: DataTable;
/** Size of each voxel in world units. Default: 0.05 */
voxelResolution?: number;
/** Opacity threshold for solid voxels - voxels below this are considered empty. Default: 0.1 */
opacityCutoff?: number;
/** Optional function to create a GPU device for voxelization */
createDevice?: DeviceCreator;
/** Exterior fill radius in world units. Enables exterior fill when set. Requires navSeed; ignored without it. */
navExteriorRadius?: number;
/** Capsule dimensions for carve. Height of 0 disables carve. When height > 0, only voxels contactable from the seed are kept. Requires navSeed. */
navCapsule?: {
height: number;
radius: number;
};
/** Seed position in world space for exterior fill and carve flood fill. */
navSeed?: NavSeed;
/** Fill each voxel column upward from the bottom until hitting solid. Runs before carve so the carve's BFS is confined to the actual navigable bubble. Default: false */
floorFill?: boolean;
/** When `floorFill` is enabled, dilation radius in world units used to identify "interior" XZ columns to patch. Empty XZ areas larger than `2 * floorFillDilation` from any solid column are treated as exterior and left empty. Default: 0 (patch every empty column). */
floorFillDilation?: number;
/** When set, a collision mesh (.collision.glb) is generated alongside the voxel output. `true` is equivalent to `smooth`. */
collisionMesh?: boolean | CollisionMeshShape;
};
/**
* Metadata for a voxel octree file.
*/
interface VoxelMetadata {
/** File format version */
version: string;
/** Grid bounds aligned to 4x4x4 block boundaries */
gridBounds: {
min: number[];
max: number[];
};
/** Scene bounds (in PlayCanvas coordinate space for v1.1+) */
sceneBounds: {
min: number[];
max: number[];
};
/** Size of each voxel in world units */
voxelResolution: number;
/** Voxels per leaf dimension (always 4) */
leafSize: number;
/** Maximum tree depth */
treeDepth: number;
/** Number of interior nodes */
numInteriorNodes: number;
/** Number of mixed leaf nodes */
numMixedLeaves: number;
/** Total number of Uint32 entries in the nodes array */
nodeCount: number;
/** Total number of Uint32 entries in the leafData array */
leafDataCount: number;
}
/**
* Write octree data to files.
*
* @param fs - File system for writing output files.
* @param jsonFilename - Output filename for JSON metadata.
* @param octree - Sparse octree structure to write.
*/
declare const writeOctreeFiles: (fs: FileSystem, jsonFilename: string, octree: SparseOctree) => Promise<void>;
/**
* Voxelizes Gaussian splat data and writes the result as a sparse voxel octree.
*
* This function performs GPU-accelerated voxelization of Gaussian splat data
* and outputs two or three files:
* - `filename` (.voxel.json) - JSON metadata including bounds, resolution, and array sizes
* - Corresponding .voxel.bin - Binary octree data (nodes + leafData as Uint32 arrays)
* - Corresponding .collision.glb - Triangle mesh extracted from the voxel output (GLB format, optional)
*
* The binary file layout is:
* - Bytes 0 to (nodeCount * 4 - 1): nodes array (Uint32, little-endian)
* - Bytes (nodeCount * 4) to end: leafData array (Uint32, little-endian)
*
* @param options - Options including filename, data, and voxelization settings.
* @param fs - File system for writing output files.
*
* @example
* ```ts
* import { writeVoxel, MemoryFileSystem } from '@playcanvas/splat-transform';
*
* const fs = new MemoryFileSystem();
* await writeVoxel({
* filename: 'scene.voxel.json',
* dataTable: myDataTable,
* voxelResolution: 0.05,
* opacityCutoff: 0.1,
* collisionMesh: true,
* createDevice: async () => myGraphicsDevice
* }, fs);
* ```
*/
declare const writeVoxel: (options: WriteVoxelOptions, fs: FileSystem) => Promise<void>;
export { writeVoxel, writeOctreeFiles, type WriteVoxelOptions, type VoxelMetadata };