Skip to content

Commit 09d6c07

Browse files
committed
Introduce writeSpz function to replace SpzWriter for splat-painter example
1 parent 466ade7 commit 09d6c07

4 files changed

Lines changed: 30 additions & 37 deletions

File tree

examples/editor/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
import * as THREE from "three";
7070
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
7171
import { GUI } from "lil-gui";
72-
import { constructGrid, SparkControls, SparkRenderer, SplatMesh, textSplats, dyno, transcodeSpz, isMobile, isPcSogs, LN_SCALE_MIN, LN_SCALE_MAX } from "@sparkjsdev/spark";
72+
import { constructGrid, SparkControls, SparkRenderer, SplatMesh, textSplats, dyno, transcodeSpz, isMobile, LN_SCALE_MIN, LN_SCALE_MAX } from "@sparkjsdev/spark";
7373
import { getAssetFileURL } from "../js/get-asset-url.js";
7474

7575
const scene = new THREE.Scene();

examples/splat-painter/index.html

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
RgbaArray,
6363
readRgbaArray,
6464
SparkControls,
65-
SpzWriter,
65+
writeSpz,
6666
unpackSplat,
6767
PackedSplats,
6868
} from "@sparkjsdev/spark";
@@ -405,7 +405,7 @@
405405
alert("No splat mesh loaded for export.");
406406
return;
407407
}
408-
408+
409409
try {
410410
console.log("Starting SPZ export with painted changes...");
411411

@@ -416,7 +416,7 @@
416416
});
417417
currentSplatMesh.updateGenerator();
418418
}
419-
419+
420420
const rgba = new RgbaArray();
421421
rgba.render({
422422
renderer,
@@ -470,7 +470,7 @@
470470
unpacked.color.g = rgbaBytes[rgbaOffset + 1] / 255;
471471
unpacked.color.b = rgbaBytes[rgbaOffset + 2] / 255;
472472
unpacked.opacity = opacity;
473-
473+
474474
// Push to new PackedSplats
475475
newPackedSplats.pushSplat(
476476
unpacked.center,
@@ -482,39 +482,13 @@
482482

483483
processedCount++;
484484
}
485-
485+
486486
console.log(`Processed ${processedCount} splats`);
487487

488488
// Now export the PackedSplats to SPZ
489-
console.log("Creating SPZ writer...");
490-
const maxSh = ioOptions.maxSh;
491-
const spzWriter = new SpzWriter({
492-
numSplats: nonZeroCount,
493-
shDegree: maxSh,
494-
fractionalBits: ioOptions.fractionalBits,
495-
flagAntiAlias: true,
496-
});
497-
498489
console.log("Writing splats to SPZ...");
499-
// Iterate through the new packed array
500-
for (let i = 0; i < nonZeroCount; i++) {
501-
const unpacked = unpackSplat(
502-
newPackedSplats.packedArray,
503-
i,
504-
newPackedSplats.splatEncoding
505-
);
506-
507-
spzWriter.setCenter(i, unpacked.center.x, unpacked.center.y, unpacked.center.z);
508-
spzWriter.setScale(i, unpacked.scales.x, unpacked.scales.y, unpacked.scales.z);
509-
spzWriter.setQuat(i, unpacked.quaternion.x, unpacked.quaternion.y, unpacked.quaternion.z, unpacked.quaternion.w);
510-
spzWriter.setAlpha(i, unpacked.opacity);
511-
spzWriter.setRgb(i, unpacked.color.r, unpacked.color.g, unpacked.color.b);
512-
}
513-
const spzBytes = await spzWriter.finalize();
514-
if (spzWriter.clippedCount > 0) {
515-
console.log(`Clipped ${spzWriter.clippedCount} splats. Consider decreasing fractional-bits from ${ioOptions.fractionalBits} to reduce clipping.`);
516-
}
517-
490+
const { fileBytes: spzBytes } = writeSpz(newPackedSplats, ioOptions.maxSh, ioOptions.fractionalBits);
491+
518492
console.log("Creating download...");
519493
const blob = new Blob([spzBytes], { type: "application/octet-stream" });
520494
const url = URL.createObjectURL(blob);
@@ -531,7 +505,7 @@
531505
}
532506
},
533507
};
534-
508+
535509
const ioFolder = gui.addFolder("I/O");
536510
ioFolder.add(ioOptions, "loadFile").name("Load Splats (SPZ/PLY)");
537511
ioFolder.add(ioOptions, "saveToSpz").name("Save Splats (SPZ)");

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export {
1212
SplatLoader,
1313
getSplatFileType,
1414
} from "./SplatLoader";
15-
export { transcodeSpz } from "./spz";
15+
export { transcodeSpz, writeSpz } from "./spz";
1616

1717
export { PackedSplats, type PackedSplatsOptions } from "./PackedSplats";
1818
export { ExtSplats, type ExtSplatsOptions } from "./ExtSplats";

src/spz.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import type { PackedSplats } from "./PackedSplats";
12
import {
23
type TranscodeSpzInput,
34
getSplatFileType,
45
getSplatFileTypeFromPath,
56
} from "./SplatLoader";
67

7-
import { decode_to_gsplatarray } from "spark-rs";
8+
import { decode_to_gsplatarray, packedsplats_to_gsplatarray } from "spark-rs";
89

910
export async function transcodeSpz(input: TranscodeSpzInput) {
1011
const splatArrays = [];
@@ -59,3 +60,21 @@ export async function transcodeSpz(input: TranscodeSpzInput) {
5960

6061
return { fileBytes: spzBytes, clippedCount: 0 };
6162
}
63+
64+
export function writeSpz(
65+
packedSplats: PackedSplats,
66+
maxSh?: number,
67+
fractionalBits?: number,
68+
) {
69+
if (!packedSplats.packedArray) {
70+
throw new Error("");
71+
}
72+
const gsplats = packedsplats_to_gsplatarray(
73+
packedSplats.numSplats,
74+
packedSplats.packedArray,
75+
packedSplats.extra,
76+
packedSplats.splatEncoding,
77+
);
78+
const spzBytes = gsplats.encode_to_spz(maxSh ?? 3, fractionalBits ?? 12);
79+
return { fileBytes: spzBytes };
80+
}

0 commit comments

Comments
 (0)