@playcanvas/splat-transform 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -69,7 +69,7 @@ splat-transform [GLOBAL] input [ACTIONS] ... output [ACTIONS]
69
69
 
70
70
  ## Actions
71
71
 
72
- Actions can be repeated and applied in any order:
72
+ Actions execute in the order specified and can be repeated. Any action may appear after any input or output file:
73
73
 
74
74
  ```none
75
75
  -t, --translate <x,y,z> Translate Gaussians by (x, y, z)
@@ -89,17 +89,19 @@ Actions can be repeated and applied in any order:
89
89
  Use n% to keep a percentage of Gaussians
90
90
  -G, --filter-floaters [size,op,min] Remove Gaussians not contributing to any solid voxel.
91
91
  Evaluates each Gaussian at occupied voxel centers.
92
- Default: size=0.05, opacity=0.1, min=0.004 (1/255)
92
+ Default: size=0.05, opacity=0.1, min=0.004 (1/255).
93
+ Bare flag (no value) uses all defaults.
93
94
  -D, --filter-cluster [res,op,min] Keep only the connected cluster at --seed-pos.
94
95
  GPU-voxelizes at coarse resolution (res world units/voxel).
95
- Default: res=1.0, opacity=0.999, min=0.1
96
+ Default: res=1.0, opacity=0.999, min=0.1.
97
+ Bare flag (no value) uses all defaults.
96
98
  -p, --params <key=val,...> Pass parameters to .mjs generator script
97
- -l, --lod <n> Specify the level of detail, n >= 0
99
+ -l, --lod <n> Tag the Gaussians with LOD level n (n >= 0)
98
100
  -m, --summary Print per-column statistics to stdout
99
101
  -M, --morton-order Reorder Gaussians by Morton code (Z-order curve)
100
102
  ```
101
103
 
102
- ## Global Options
104
+ ## General Options
103
105
 
104
106
  ```none
105
107
  -h, --help Show this help and exit
@@ -109,29 +111,80 @@ Actions can be repeated and applied in any order:
109
111
  --mem Show memory usage in progress output
110
112
  --tty Interactive bar rendering (default on a TTY; --no-tty to disable)
111
113
  -w, --overwrite Overwrite output file if it exists
112
- -i, --iterations <n> Iterations for SOG SH compression (more=better). Default: 10
114
+ ```
115
+
116
+ ## GPU Options
117
+
118
+ Used by SOG compression and GPU voxelization (`--filter-cluster`, `--filter-floaters`, `.voxel.json` output).
119
+
120
+ ```none
113
121
  -L, --list-gpus List available GPU adapters and exit
114
- -g, --gpu <n|cpu> Select device for SOG compression: GPU adapter index | 'cpu'
122
+ -g, --gpu <n|cpu> Device for GPU operations: GPU adapter index | 'cpu'
123
+ ('cpu' disables GPU and is incompatible with
124
+ GPU-only features like --filter-cluster)
125
+ ```
126
+
127
+ ## SOG Compression Options
128
+
129
+ Apply when writing `.sog`, `meta.json`, `lod-meta.json`, or `.html` outputs.
130
+
131
+ ```none
132
+ -i, --iterations <n> Iterations for SH compression (more=better). Default: 10
133
+ ```
134
+
135
+ ## HTML Viewer Output Options
136
+
137
+ Apply when writing `.html` outputs.
138
+
139
+ ```none
115
140
  -E, --viewer-settings <settings.json> HTML viewer settings JSON file
116
141
  -U, --unbundled Generate unbundled HTML viewer with separate files
142
+ ```
143
+
144
+ > [!NOTE]
145
+ > See the [SuperSplat Viewer Settings Schema](https://github.com/playcanvas/supersplat-viewer?tab=readme-ov-file#settings-schema) for details on how to pass data to the `-E` option.
146
+
147
+ ## LCC Input Options
148
+
149
+ Apply when reading `.lcc` files.
150
+
151
+ ```none
117
152
  -O, --lod-select <n,n,...> Comma-separated LOD levels to read from LCC input
153
+ ```
154
+
155
+ ## LOD Output Options
156
+
157
+ Apply when writing `lod-meta.json` (multi-LOD streaming SOG bundle).
158
+
159
+ ```none
118
160
  -C, --lod-chunk-count <n> Approximate number of Gaussians per LOD chunk in K. Default: 512
119
161
  -X, --lod-chunk-extent <n> Approximate size of an LOD chunk in world units (m). Default: 16
120
- --voxel-params [size,opacity] Voxel size and opacity threshold for .voxel.json. Default: 0.05,0.1
121
- --voxel-external-fill [size] Fill exterior voxels by dilation from seed. Default size: 1.6
122
- --voxel-floor-fill [radius] Fill each column upward from bottom until hitting solid (runs before carve).
162
+ ```
163
+
164
+ ## Voxel Output Options
165
+
166
+ Apply when writing `.voxel.json` (sparse voxel octree for collision detection). See the [Collision Mesh Guide](guides/COLLISION.md) for a deep dive on each step and tuning.
167
+
168
+ ```none
169
+ --voxel-params [size,opacity] Voxel size and opacity threshold. Default: 0.05,0.1
170
+ --voxel-external-fill [size] Seal exterior voxels via boundary flood fill (interior scenes).
171
+ [size] (world units) is the dilation distance applied
172
+ before the flood fill to bridge small wall gaps.
173
+ --seed-pos is used to verify the volume is enclosed at
174
+ the seed; the fill is skipped if the seed is reachable
175
+ from outside.
176
+ Default size: 1.6
177
+ --voxel-floor-fill [radius] Fill each column upward from bottom until hitting solid (exterior scenes).
123
178
  Optional radius (world units): only patch XZ areas surrounded by floor
124
179
  within 2*radius; large empty exterior areas are left alone.
125
180
  Default radius: 1.6
126
- --voxel-carve [h,r] Carve navigable space using capsule flood fill from seed.
181
+ --voxel-carve [h,r] Carve navigable space using capsule flood fill from seed.
127
182
  Default: height=1.6, radius=0.2
128
- --seed-pos <x,y,z> Seed position for voxel processing and --filter-cluster. Default: 0,0,0
129
- -K, --collision-mesh [smooth|faces] Generate collision mesh (.collision.glb). Default shape: smooth.
183
+ --seed-pos <x,y,z> Seed position for voxel fill/carve and --filter-cluster.
184
+ Default: 0,0,0
185
+ -K, --collision-mesh [smooth|faces] Generate collision mesh (.collision.glb). Default: smooth
130
186
  ```
131
187
 
132
- > [!NOTE]
133
- > See the [SuperSplat Viewer Settings Schema](https://github.com/playcanvas/supersplat-viewer?tab=readme-ov-file#settings-schema) for details on how to pass data to the `-E` option.
134
-
135
188
  ## Examples
136
189
 
137
190
  ### Basic Operations
@@ -244,22 +297,54 @@ splat-transform gen-grid.mjs -p width=10,height=10,scale=10,color=0.1 scenes/gri
244
297
 
245
298
  ### Voxel Format
246
299
 
247
- The voxel format stores sparse voxel octree data for collision detection. It consists of two files: `.voxel.json` (metadata) and `.voxel.bin` (binary octree data).
300
+ The voxel format stores sparse voxel octree data for collision detection. It consists of two files: `.voxel.json` (metadata) and `.voxel.bin` (binary octree data). Pass `-K` to also emit a `.collision.glb` mesh derived from the voxel grid.
301
+
302
+ For a step-by-step walkthrough of each option (with illustrations), see the [Collision Mesh Guide](guides/COLLISION.md).
303
+
304
+ #### Recommended pipeline
248
305
 
249
306
  ```bash
250
- # Generate voxel collision data from a splat file
251
- splat-transform input.ply output.voxel.json
307
+ splat-transform input.ply \
308
+ --filter-cluster --seed-pos x,y,z \
309
+ [--voxel-external-fill | --voxel-floor-fill] [--voxel-carve] \
310
+ [-K [smooth|faces]] \
311
+ output.voxel.json
312
+ ```
252
313
 
253
- # Generate voxel data with custom resolution and opacity threshold
254
- splat-transform --voxel-params 0.1,0.3 input.ply output.voxel.json
314
+ `--filter-cluster` isolates the central scene and discards stray floaters before voxelization. `--seed-pos` is shared by `--filter-cluster` and the voxel fill/carve passes — set it once to a known-walkable point inside the scene.
255
315
 
256
- # Generate voxel data with exterior fill and carve
257
- splat-transform --voxel-external-fill --voxel-carve input.ply output.voxel.json
316
+ #### Interior scenes (rooms, indoor scans)
317
+
318
+ Use `--voxel-external-fill` to seal the void around the room interior, then `--voxel-carve` to hollow out the navigable space:
319
+
320
+ ```bash
321
+ splat-transform room.ply \
322
+ --filter-cluster --seed-pos 0,1,0 \
323
+ --voxel-external-fill --voxel-carve \
324
+ -K room.voxel.json
325
+ ```
326
+
327
+ #### Exterior scenes (outdoor objects, terrain)
328
+
329
+ Use `--voxel-floor-fill` to fill the ground beneath surfaces, optionally followed by `--voxel-carve`:
330
+
331
+ ```bash
332
+ splat-transform terrain.ply \
333
+ --filter-cluster --seed-pos 0,0,0 \
334
+ --voxel-floor-fill \
335
+ -K terrain.voxel.json
336
+ ```
337
+
338
+ #### Other examples
339
+
340
+ ```bash
341
+ # Voxelize with custom resolution and opacity threshold
342
+ splat-transform --voxel-params 0.1,0.3 input.ply output.voxel.json
258
343
 
259
- # Generate voxel data with custom seed position and carve parameters
344
+ # Custom carve capsule (height, radius)
260
345
  splat-transform --seed-pos 1,0,0 --voxel-carve 2.0,0.3 input.ply output.voxel.json
261
346
 
262
- # Generate voxel data with a watertight voxel-face collision mesh
347
+ # Watertight voxel-face collision mesh
263
348
  splat-transform -K faces input.ply output.voxel.json
264
349
  ```
265
350
 
package/dist/cli.mjs CHANGED
@@ -17494,11 +17494,11 @@ class CompressedChunk {
17494
17494
  /**
17495
17495
  * The splat-transform version (semver MAJOR.MINOR.PATCH).
17496
17496
  */
17497
- const version = '2.0.4';
17497
+ const version = '2.0.5';
17498
17498
  /**
17499
17499
  * The splat-transform revision (short Git hash of HEAD at build time).
17500
17500
  */
17501
- const revision = 'fa46db3';
17501
+ const revision = '1fc5209';
17502
17502
 
17503
17503
  const generatedByString = `Generated by splat-transform ${version}`;
17504
17504
  const chunkProps = [
@@ -29706,98 +29706,71 @@ SUPPORTED INPUTS
29706
29706
  SUPPORTED OUTPUTS
29707
29707
  .ply .compressed.ply .sog meta.json lod-meta.json .glb .csv .html .voxel.json null
29708
29708
 
29709
- ACTIONS (can be repeated, in any order)
29709
+ ACTIONS (executed in order; can be repeated)
29710
29710
  -t, --translate <x,y,z> Translate Gaussians by (x, y, z)
29711
- -r, --rotate <x,y,z> Rotate Gaussians by Euler angles (x, y, z), in degrees
29711
+ -r, --rotate <x,y,z> Rotate Gaussians by Euler angles, in degrees
29712
29712
  -s, --scale <factor> Uniformly scale Gaussians by factor
29713
29713
  -H, --filter-harmonics <0|1|2|3> Remove spherical harmonic bands > n
29714
- -N, --filter-nan Remove Gaussians with NaN values and most Inf values;
29715
- retains +Infinity in opacity and -Infinity in scale_*
29714
+ -N, --filter-nan Remove Gaussians with NaN values and most Inf values
29716
29715
  -B, --filter-box <x,y,z,X,Y,Z> Remove Gaussians outside box (min, max corners)
29717
- -S, --filter-sphere <x,y,z,radius> Remove Gaussians outside sphere (center, radius)
29718
- -V, --filter-value <name,cmp,value> Keep Gaussians where <name> <cmp> <value>
29716
+ -S, --filter-sphere <x,y,z,radius> Remove Gaussians outside sphere
29717
+ -V, --filter-value <name,cmp,value> Keep Gaussians where <name> <cmp> <value>;
29719
29718
  cmp ∈ {lt,lte,gt,gte,eq,neq}
29720
- opacity, scale_*, f_dc_* use transformed values
29721
- (linear opacity 0-1, linear scale, linear color 0-1).
29722
- Append _raw for raw PLY values (e.g. opacity_raw).
29723
- -F, --decimate <n|n%> Simplify to n Gaussians via progressive pairwise merging
29724
- Use n% to keep a percentage of Gaussians
29725
- -G, --filter-floaters [size,op,min] Remove Gaussians not contributing to any solid voxel.
29726
- Evaluates each Gaussian at occupied voxel centers.
29727
- Default: size=0.05, opacity=0.1, min=0.004 (1/255)
29728
- -D, --filter-cluster [res,op,min] Keep only the connected cluster at --seed-pos.
29729
- GPU-voxelizes at coarse resolution (res world units/voxel).
29730
- Default: res=1.0, opacity=0.999, min=0.1
29719
+ -F, --decimate <n|n%> Simplify to n (or n%) Gaussians via pairwise merging
29720
+ -G, --filter-floaters [size,op,min] Remove Gaussians not contributing to any solid voxel. Default: 0.05,0.1,0.004
29721
+ -D, --filter-cluster [res,op,min] Keep only the connected cluster at --seed-pos. Default: 1.0,0.999,0.1
29731
29722
  -p, --params <key=val,...> Pass parameters to .mjs generator script
29732
- -l, --lod <n> Specify the level of detail, n >= 0
29723
+ -l, --lod <n> Tag the Gaussians with LOD level n (n >= 0)
29733
29724
  -m, --summary Print per-column statistics to stdout
29734
29725
  -M, --morton-order Reorder Gaussians by Morton code (Z-order curve)
29735
29726
 
29736
- GLOBAL OPTIONS
29727
+ GENERAL
29737
29728
  -h, --help Show this help and exit
29738
29729
  -v, --version Show version and exit
29739
29730
  -q, --quiet Suppress non-error output
29740
29731
  --verbose Show debug-level diagnostics
29741
29732
  --mem Show peak memory in progress output
29742
- --tty Interactive bar rendering (default on a TTY; --no-tty to disable)
29733
+ --tty Interactive bar rendering (--no-tty to disable)
29743
29734
  -w, --overwrite Overwrite output file if it exists
29744
- -i, --iterations <n> Iterations for SOG SH compression (more=better). Default: 10
29745
- -L, --list-gpus List available GPU adapters and exit
29746
- -g, --gpu <n|cpu> Select device for SOG compression: GPU adapter index | 'cpu'
29747
- -E, --viewer-settings <settings.json> HTML viewer settings JSON file
29748
- -U, --unbundled Generate unbundled HTML viewer with separate files
29749
- -O, --lod-select <n,n,...> Comma-separated LOD levels to read from LCC input
29750
- -C, --lod-chunk-count <n> Approximate number of Gaussians per LOD chunk in K. Default: 512
29751
- -X, --lod-chunk-extent <n> Approximate size of an LOD chunk in world units (m). Default: 16
29752
- --voxel-params [size,opacity] Voxel size and opacity threshold for .voxel.json. Default: 0.05,0.1
29753
- --voxel-external-fill [size] Fill exterior voxels by dilation from seed. Default size: 1.6
29754
- --voxel-floor-fill [size] Fill below-floor voxels by upward column walk from bottom. Default size: 1.6
29755
- --voxel-carve [h,r] Carve navigable space using capsule flood fill from seed. Default: 1.6,0.2
29756
- --seed-pos <x,y,z> Seed position for voxel processing and --filter-cluster. Default: 0,0,0
29757
- -K, --collision-mesh [smooth|faces] Generate collision mesh (.collision.glb). Default shape: smooth
29758
-
29759
- EXAMPLES
29760
- # Scale then translate
29761
- splat-transform bunny.ply -s 0.5 -t 0,0,10 bunny-scaled.ply
29762
-
29763
- # Merge two files with transforms and compress to SOG format
29764
- splat-transform -w cloudA.ply -r 0,90,0 cloudB.ply -s 2 merged.sog
29765
29735
 
29766
- # Generate unbundled HTML viewer with separate CSS, JS and SOG files
29767
- splat-transform -U bunny.ply bunny-viewer.html
29768
-
29769
- # Generate synthetic splats using a generator script
29770
- splat-transform gen-grid.mjs -p width=500,height=500,scale=0.1 grid.ply
29771
-
29772
- # Generate LOD with custom chunk size and node split size
29773
- splat-transform -O 0,1,2 -C 1024 -X 32 input.lcc output/lod-meta.json
29736
+ GPU (used by SOG compression and GPU voxelization: --filter-cluster, --filter-floaters, .voxel.json output)
29737
+ -L, --list-gpus List available GPU adapters and exit
29738
+ -g, --gpu <n|cpu> Device for GPU operations: GPU adapter index | 'cpu'
29739
+ ('cpu' disables GPU and is incompatible with GPU-only features)
29774
29740
 
29775
- # Generate voxel data
29776
- splat-transform input.ply output.voxel.json
29741
+ SOG COMPRESSION (.sog, meta.json, lod-meta.json, .html outputs)
29742
+ -i, --iterations <n> SH compression iterations (more=better). Default: 10
29777
29743
 
29778
- # Generate voxel data with collision mesh
29779
- splat-transform -K input.ply output.voxel.json
29744
+ HTML VIEWER OUTPUT (.html)
29745
+ -E, --viewer-settings <settings.json> HTML viewer settings JSON file
29746
+ -U, --unbundled Generate unbundled HTML viewer with separate files
29780
29747
 
29781
- # Generate voxel data with voxel-face collision mesh
29782
- splat-transform -K faces input.ply output.voxel.json
29748
+ LCC INPUT (.lcc)
29749
+ -O, --lod-select <n,n,...> Comma-separated LOD levels to read
29783
29750
 
29784
- # Generate voxel data with custom resolution and opacity threshold
29785
- splat-transform --voxel-params 0.1,0.3 input.ply output.voxel.json
29751
+ LOD OUTPUT (lod-meta.json)
29752
+ -C, --lod-chunk-count <n> Approximate Gaussians per LOD chunk in K. Default: 512
29753
+ -X, --lod-chunk-extent <n> Approximate LOD chunk size in world units. Default: 16
29786
29754
 
29787
- # Generate voxel data with exterior fill and carve
29788
- splat-transform --voxel-external-fill --voxel-carve input.ply output.voxel.json
29755
+ VOXEL OUTPUT (.voxel.json)
29756
+ --voxel-params [size,opacity] Voxel size + opacity threshold. Default: 0.05,0.1
29757
+ --voxel-external-fill [size] Seal exterior voxels via boundary flood fill (interior scenes). Default: 1.6
29758
+ --voxel-floor-fill [radius] Fill columns upward from bottom (exterior scenes). Default: 1.6
29759
+ --voxel-carve [h,r] Carve navigable space via capsule flood fill from seed. Default: 1.6,0.2
29760
+ --seed-pos <x,y,z> Seed position for voxel fill/carve and --filter-cluster. Default: 0,0,0
29761
+ -K, --collision-mesh [smooth|faces] Generate collision mesh (.collision.glb). Default: smooth
29789
29762
 
29790
- # Generate voxel data with custom seed position and carve parameters
29791
- splat-transform --seed-pos 1,0,0 --voxel-carve 2.0,0.3 input.ply output.voxel.json
29763
+ EXAMPLES
29764
+ # Convert formats
29765
+ splat-transform input.ply output.sog
29792
29766
 
29793
- # Print statistical summary, then write output
29794
- splat-transform bunny.ply --summary output.ply
29767
+ # Merge files with transforms
29768
+ splat-transform -w a.ply -r 0,90,0 b.ply -s 2 merged.sog
29795
29769
 
29796
- # Print summary without writing a file (discard output)
29797
- splat-transform bunny.ply -m null
29770
+ # Generate voxel collision data
29771
+ splat-transform input.ply --filter-cluster output.voxel.json
29798
29772
 
29799
- # Read input from a URL and write to a local file
29800
- splat-transform https://example.com/scene.ply scene.sog
29773
+ More examples: https://github.com/playcanvas/splat-transform#examples
29801
29774
  `;
29802
29775
  const main = async () => {
29803
29776
  const startTime = performance.now();