@playcanvas/splat-transform 0.14.0 → 0.14.1

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
@@ -67,6 +67,7 @@ Actions can be repeated and applied in any order:
67
67
  -V, --filter-value <name,cmp,value> Keep splats where <name> <cmp> <value>
68
68
  cmp ∈ {lt,lte,gt,gte,eq,neq}
69
69
  -p, --params <key=val,...> Pass parameters to .mjs generator script
70
+ -l, --lod <n> Specify the level of detail of this model, n >= 0.
70
71
  ```
71
72
 
72
73
  ## Global Options
@@ -74,6 +75,7 @@ Actions can be repeated and applied in any order:
74
75
  ```none
75
76
  -h, --help Show this help and exit
76
77
  -v, --version Show version and exit
78
+ -q, --quiet Suppress non-error output
77
79
  -w, --overwrite Overwrite output file if it exists
78
80
  -c, --cpu Use CPU for SOG spherical harmonic compression
79
81
  -i, --iterations <n> Iterations for SOG SH compression (more=better). Default: 10
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomBytes } from 'crypto';
2
2
  import { open, readFile as readFile$1, unlink, mkdir, lstat, rename } from 'node:fs/promises';
3
3
  import { join, dirname, resolve as resolve$2, basename } from 'node:path';
4
- import { stdout, hrtime, exit } from 'node:process';
4
+ import { hrtime, exit } from 'node:process';
5
5
  import { parseArgs } from 'node:util';
6
6
  import { Buffer as Buffer$1 } from 'node:buffer';
7
7
  import os from 'node:os';
@@ -58527,7 +58527,7 @@ class TextureHandler extends ResourceHandler {
58527
58527
  }
58528
58528
  }
58529
58529
 
58530
- var version = "0.14.0";
58530
+ var version = "0.14.1";
58531
58531
 
58532
58532
  class Column {
58533
58533
  name;
@@ -58644,6 +58644,73 @@ class DataTable {
58644
58644
  }
58645
58645
  }
58646
58646
 
58647
+ /**
58648
+ * Simple logger utility. Currently supports quiet mode. Designed to be extended for multiple log
58649
+ * levels in the future.
58650
+ */
58651
+ class Logger {
58652
+ level = 'normal';
58653
+ setLevel(level) {
58654
+ this.level = level;
58655
+ }
58656
+ setQuiet(quiet) {
58657
+ this.level = quiet ? 'silent' : 'normal';
58658
+ }
58659
+ /**
58660
+ * Log informational messages (file operations, progress, etc.). Suppressed in quiet mode.
58661
+ * @param {...any} args - The arguments to log.
58662
+ */
58663
+ info(...args) {
58664
+ if (this.level !== 'silent') {
58665
+ console.log(...args);
58666
+ }
58667
+ }
58668
+ /**
58669
+ * Log warning messages. Suppressed in quiet mode.
58670
+ * @param {...any} args - The arguments to log.
58671
+ */
58672
+ warn(...args) {
58673
+ if (this.level !== 'silent') {
58674
+ console.warn(...args);
58675
+ }
58676
+ }
58677
+ /**
58678
+ * Log error messages. Always shown, even in quiet mode.
58679
+ * @param {...any} args - The arguments to log.
58680
+ */
58681
+ error(...args) {
58682
+ console.error(...args);
58683
+ }
58684
+ /**
58685
+ * Log debug/verbose messages. Currently treated the same as info, but can be filtered
58686
+ * separately in the future.
58687
+ * @param {...any} args - The arguments to log.
58688
+ */
58689
+ debug(...args) {
58690
+ if (this.level !== 'silent') {
58691
+ console.log(...args);
58692
+ }
58693
+ }
58694
+ /**
58695
+ * Write progress indicators directly to stdout (without newline). Suppressed in quiet mode.
58696
+ * @param text - The text to write.
58697
+ */
58698
+ progress(text) {
58699
+ if (this.level !== 'silent') {
58700
+ process.stdout.write(text);
58701
+ }
58702
+ }
58703
+ /**
58704
+ * Check if logger is in quiet/silent mode.
58705
+ * @returns True if the logger is in quiet/silent mode, false otherwise.
58706
+ */
58707
+ isQuiet() {
58708
+ return this.level === 'silent';
58709
+ }
58710
+ }
58711
+ // Export singleton instance
58712
+ const logger = new Logger();
58713
+
58647
58714
  /* eslint-disable indent */
58648
58715
  const kSqrt03_02 = Math.sqrt(3.0 / 2.0);
58649
58716
  const kSqrt01_03 = Math.sqrt(1.0 / 3.0);
@@ -60853,7 +60920,7 @@ const generateOrdering = (dataTable, indices) => {
60853
60920
  const ylen = My - my;
60854
60921
  const zlen = Mz - mz;
60855
60922
  if (!isFinite(xlen) || !isFinite(ylen) || !isFinite(zlen)) {
60856
- console.log('invalid extents', xlen, ylen, zlen);
60923
+ logger.debug('invalid extents', xlen, ylen, zlen);
60857
60924
  return;
60858
60925
  }
60859
60926
  // all points are identical
@@ -60889,7 +60956,7 @@ const generateOrdering = (dataTable, indices) => {
60889
60956
  ++end;
60890
60957
  }
60891
60958
  if (end - start > 256) {
60892
- // console.log('sorting', end - start);
60959
+ // logger.debug('sorting', end - start);
60893
60960
  generate(indices.subarray(start, end));
60894
60961
  }
60895
60962
  start = end;
@@ -61096,7 +61163,7 @@ const createDevice = async () => {
61096
61163
  await graphicsDevice.createDevice();
61097
61164
  // print gpu info
61098
61165
  const info = graphicsDevice.gpuAdapter.info;
61099
- console.log(`Created gpu device="${info.device || '-'}" arch="${info.architecture || '-'}" descr="${info.description || '-'}"`);
61166
+ logger.debug(`Created gpu device="${info.device || '-'}" arch="${info.architecture || '-'}" descr="${info.description || '-'}"`);
61100
61167
  // create the application
61101
61168
  const app = new Application(canvas, { graphicsDevice });
61102
61169
  // create external backbuffer
@@ -61639,7 +61706,7 @@ const kmeans = async (points, k, iterations, device) => {
61639
61706
  const labels = new Uint32Array(points.numRows);
61640
61707
  let converged = false;
61641
61708
  let steps = 0;
61642
- console.log(`Running k-means clustering: dims=${points.numColumns} points=${points.numRows} clusters=${k} iterations=${iterations}...`);
61709
+ logger.debug(`Running k-means clustering: dims=${points.numColumns} points=${points.numRows} clusters=${k} iterations=${iterations}...`);
61643
61710
  while (!converged) {
61644
61711
  if (gpuClustering) {
61645
61712
  await gpuClustering.execute(points, centroids, labels);
@@ -61665,12 +61732,12 @@ const kmeans = async (points, k, iterations, device) => {
61665
61732
  if (steps >= iterations) {
61666
61733
  converged = true;
61667
61734
  }
61668
- stdout.write('#');
61735
+ logger.progress('#');
61669
61736
  }
61670
61737
  if (gpuClustering) {
61671
61738
  gpuClustering.destroy();
61672
61739
  }
61673
- console.log(' done 🎉');
61740
+ logger.debug(' done 🎉');
61674
61741
  return { centroids, labels };
61675
61742
  };
61676
61743
 
@@ -61766,7 +61833,7 @@ const writeSog = async (fileHandle, dataTable, outputFilename, options, indices
61766
61833
  const layout = identity; // rectChunks;
61767
61834
  const write = async (filename, data, w = width, h = height) => {
61768
61835
  const pathname = resolve$2(dirname(outputFilename), filename);
61769
- console.log(`writing '${pathname}'...`);
61836
+ logger.info(`writing '${pathname}'...`);
61770
61837
  // construct the encoder on first use
61771
61838
  if (!webPCodec) {
61772
61839
  webPCodec = await WebPCodec.create();
@@ -62192,7 +62259,7 @@ const calcBound = (dataTable, indices) => {
62192
62259
  const m = b.getMin();
62193
62260
  const M = b.getMax();
62194
62261
  if (!isFinite(m.x) || !isFinite(m.y) || !isFinite(m.z) || !isFinite(M.x) || !isFinite(M.y) || !isFinite(M.z)) {
62195
- console.warn('Skipping invalid bounding box:', { m, M, index });
62262
+ logger.warn('Skipping invalid bounding box:', { m, M, index });
62196
62263
  continue;
62197
62264
  }
62198
62265
  min[0] = Math.min(min[0], m.x);
@@ -62336,7 +62403,7 @@ const writeLod = async (fileHandle, dataTable, outputFilename, options) => {
62336
62403
  }
62337
62404
  // write file unit to sog
62338
62405
  const outputFile = await open(pathname, 'w');
62339
- console.log(`writing ${pathname}...`);
62406
+ logger.info(`writing ${pathname}...`);
62340
62407
  await writeSog(outputFile, unitDataTable, pathname, options, indices);
62341
62408
  await outputFile.close();
62342
62409
  }
@@ -62461,7 +62528,7 @@ const getOutputFormat = (filename) => {
62461
62528
  const readFile = async (filename, options, params) => {
62462
62529
  const inputFormat = getInputFormat(filename);
62463
62530
  let result;
62464
- console.log(`reading '${filename}'...`);
62531
+ logger.info(`reading '${filename}'...`);
62465
62532
  if (inputFormat === 'mjs') {
62466
62533
  result = [await readMjs(filename, params)];
62467
62534
  }
@@ -62501,7 +62568,7 @@ const readFile = async (filename, options, params) => {
62501
62568
  const writeFile = async (filename, dataTable, options) => {
62502
62569
  // get the output format, throws on failure
62503
62570
  const outputFormat = getOutputFormat(filename);
62504
- console.log(`writing '${filename}'...`);
62571
+ logger.info(`writing '${filename}'...`);
62505
62572
  // write to a temporary file and rename on success
62506
62573
  const tmpFilename = `.${basename(filename)}.${process.pid}.${Date.now()}.${randomBytes(6).toString('hex')}.tmp`;
62507
62574
  const tmpPathname = join(dirname(filename), tmpFilename);
@@ -62614,6 +62681,7 @@ const parseArguments = () => {
62614
62681
  overwrite: { type: 'boolean', short: 'w', default: false },
62615
62682
  help: { type: 'boolean', short: 'h', default: false },
62616
62683
  version: { type: 'boolean', short: 'v', default: false },
62684
+ quiet: { type: 'boolean', short: 'q', default: false },
62617
62685
  cpu: { type: 'boolean', short: 'c', default: false },
62618
62686
  iterations: { type: 'string', short: 'i', default: '10' },
62619
62687
  'lod-select': { type: 'string', short: 'O', default: '' },
@@ -62671,6 +62739,7 @@ const parseArguments = () => {
62671
62739
  overwrite: v.overwrite,
62672
62740
  help: v.help,
62673
62741
  version: v.version,
62742
+ quiet: v.quiet,
62674
62743
  cpu: v.cpu,
62675
62744
  iterations: parseInteger(v.iterations),
62676
62745
  lodSelect: v['lod-select'].split(',').filter(v => !!v).map(parseInteger),
@@ -62830,6 +62899,7 @@ ACTIONS (can be repeated, in any order)
62830
62899
  GLOBAL OPTIONS
62831
62900
  -h, --help Show this help and exit
62832
62901
  -v, --version Show version and exit
62902
+ -q, --quiet Suppress non-error output
62833
62903
  -w, --overwrite Overwrite output file if it exists
62834
62904
  -c, --cpu Use CPU for SOG spherical harmonic compression
62835
62905
  -i, --iterations <n> Iterations for SOG SH compression (more=better). Default: 10
@@ -62855,17 +62925,19 @@ EXAMPLES
62855
62925
  splat-transform -O 0,1,2 -C 1024 -X 32 input.lcc output/lod-meta.json
62856
62926
  `;
62857
62927
  const main = async () => {
62858
- console.log(`splat-transform v${version}`);
62859
62928
  const startTime = hrtime();
62860
62929
  // read args
62861
62930
  const { files, options } = parseArguments();
62931
+ // configure logger
62932
+ logger.setQuiet(options.quiet);
62933
+ logger.info(`splat-transform v${version}`);
62862
62934
  // show version and exit
62863
62935
  if (options.version) {
62864
62936
  exit(0);
62865
62937
  }
62866
62938
  // invalid args or show help
62867
62939
  if (files.length < 2 || options.help) {
62868
- console.error(usage);
62940
+ logger.error(usage);
62869
62941
  exit(1);
62870
62942
  }
62871
62943
  const inputArgs = files.slice(0, -1);
@@ -62878,7 +62950,7 @@ const main = async () => {
62878
62950
  else {
62879
62951
  // check overwrite before doing any work
62880
62952
  if (await fileExists(outputFilename)) {
62881
- console.error(`File '${outputFilename}' already exists. Use -w option to overwrite.`);
62953
+ logger.error(`File '${outputFilename}' already exists. Use -w option to overwrite.`);
62882
62954
  exit(1);
62883
62955
  }
62884
62956
  }
@@ -62905,17 +62977,17 @@ const main = async () => {
62905
62977
  if (dataTable.numRows === 0) {
62906
62978
  throw new Error('No splats to write');
62907
62979
  }
62908
- console.log(`Loaded ${dataTable.numRows} gaussians`);
62980
+ logger.info(`Loaded ${dataTable.numRows} gaussians`);
62909
62981
  // write file
62910
62982
  await writeFile(outputFilename, dataTable, options);
62911
62983
  }
62912
62984
  catch (err) {
62913
62985
  // handle errors
62914
- console.error(err);
62986
+ logger.error(err);
62915
62987
  exit(1);
62916
62988
  }
62917
62989
  const endTime = hrtime(startTime);
62918
- console.log(`done in ${endTime[0] + endTime[1] / 1e9}s`);
62990
+ logger.info(`done in ${endTime[0] + endTime[1] / 1e9}s`);
62919
62991
  // something in webgpu seems to keep the process alive after returning
62920
62992
  // from main so force exit
62921
62993
  exit(0);