UNPKG

@playcanvas/splat-transform

Version:

Library and CLI tool for 3D Gaussian splat format conversion and transformation

108 lines (107 loc) 4.54 kB
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 };