Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions src/SplatMesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ export interface SplatSource {
}: { index: DynoVal<"int">; viewOrigin?: DynoVal<"vec3"> }): DynoVal<
typeof Gsplat
>;

forEachSplat(
callback: (
index: number,
center: THREE.Vector3,
scales: THREE.Vector3,
quaternion: THREE.Quaternion,
opacity: number,
color: THREE.Color,
) => void,
): void;
}

export class EmptySplatSource implements SplatSource {
Expand Down Expand Up @@ -213,6 +224,8 @@ export class EmptySplatSource implements SplatSource {
fetchSplat({ index }: { index: DynoVal<"int"> }): DynoVal<typeof Gsplat> {
return this.fetchDyno;
}

forEachSplat() {}
}

export class SplatMesh extends SplatGenerator {
Expand Down Expand Up @@ -546,11 +559,7 @@ export class SplatMesh extends SplatGenerator {
color: THREE.Color,
) => void,
) {
if (this.packedSplats) {
this.packedSplats.forEachSplat(callback);
} else if (this.extSplats) {
this.extSplats.forEachSplat(callback);
}
this.splats?.forEachSplat(callback);
}

// Call this when you are finished with the SplatMesh and want to free
Expand Down Expand Up @@ -583,9 +592,6 @@ export class SplatMesh extends SplatGenerator {
"Cannot get bounding box before SplatMesh is initialized",
);
}
if (!this.packedSplats && !this.extSplats) {
throw new Error("Bounding box requires PackedSplats or ExtSplats");
}
const minVec = new THREE.Vector3(
Number.POSITIVE_INFINITY,
Number.POSITIVE_INFINITY,
Expand Down Expand Up @@ -627,11 +633,7 @@ export class SplatMesh extends SplatGenerator {
}
}

if (this.packedSplats) {
this.packedSplats.forEachSplat(callback);
} else if (this.extSplats) {
this.extSplats.forEachSplat(callback);
}
this.splats?.forEachSplat(callback);
const box = new THREE.Box3(minVec, maxVec);
return box;
}
Expand Down
44 changes: 43 additions & 1 deletion src/SplatPager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
SplatFileType,
} from "./defines";
import { pagedSplatTexCoord } from "./dyno";
import { getTextureSize } from "./utils";
import { decodeExtSplat, getTextureSize, unpackSplat } from "./utils";

export interface PagedSplatsOptions {
pager?: SplatPager;
Expand Down Expand Up @@ -430,6 +430,48 @@ export class PagedSplats implements SplatSource {
}
return this.pager.readSplatExt.apply({ index: splatIndex }).gsplat;
}

// Iterate over Gsplats index 0..=(this.numSplats-1), unpack each Gsplat
// and invoke the callback function with the Gsplat attributes.
forEachSplat(
callback: (
index: number,
center: THREE.Vector3,
scales: THREE.Vector3,
quaternion: THREE.Quaternion,
opacity: number,
color: THREE.Color,
) => void,
) {
if (!this.pager || !this.numSplats) {
return;
}
const extSplats = this.pager.extSplats;
const indices = this.dynoIndices.value.image.data as Uint32Array;
const packedSplatArray = this.pager.packedTexture.value.image
.data as Uint32Array;
const extPackedSplatArray = this.pager.extTexture.value.image
.data as Uint32Array;
const extArrays: [Uint32Array, Uint32Array] = [
packedSplatArray,
extPackedSplatArray,
];

for (let i = 0; i < this.numSplats; ++i) {
const splatIndex = indices[i];
const unpacked = extSplats
? decodeExtSplat(extArrays, splatIndex)
: unpackSplat(packedSplatArray, splatIndex, this.splatEncoding);
callback(
i,
unpacked.center,
unpacked.scales,
unpacked.quaternion,
unpacked.opacity,
unpacked.color,
);
}
}
}

export interface SplatPagerOptions {
Expand Down
Loading