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
13 changes: 6 additions & 7 deletions src/ExtSplats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,15 +690,18 @@ export class ExtSplats implements SplatSource {
: quality
? 1.75
: 1.5;
const extArrays = [this.extArrays[0].slice(), this.extArrays[1].slice()];
const extArrays = [
this.extArrays[0].slice(),
this.extArrays[1].slice(),
] as const;
const rgba = rgbaArray ? (await rgbaArray.getArray()).slice() : undefined;
const extra = {
sh1: this.extra.sh1 ? (this.extra.sh1 as Uint32Array).slice() : undefined,
sh2: this.extra.sh2 ? (this.extra.sh2 as Uint32Array).slice() : undefined,
sh3: this.extra.sh3 ? (this.extra.sh3 as Uint32Array).slice() : undefined,
};
const decoded = await workerPool.withWorker(async (worker) => {
return (await worker.call(
return await worker.call(
quality ? "qualityLodExtSplats" : "tinyLodExtSplats",
{
numSplats: this.numSplats,
Expand All @@ -707,11 +710,7 @@ export class ExtSplats implements SplatSource {
lodBase,
rgba,
},
)) as {
numSplats: number;
extArrays: [Uint32Array, Uint32Array];
extra: Record<string, unknown>;
};
);
});

const lodSplats = new ExtSplats(decoded);
Expand Down
9 changes: 2 additions & 7 deletions src/PackedSplats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ export class PackedSplats implements SplatSource {
sh3: this.extra.sh3 ? (this.extra.sh3 as Uint32Array).slice() : undefined,
};
const decoded = await workerPool.withWorker(async (worker) => {
return (await worker.call(
return await worker.call(
quality ? "qualityLodPackedSplats" : "tinyLodPackedSplats",
{
numSplats: this.numSplats,
Expand All @@ -924,12 +924,7 @@ export class PackedSplats implements SplatSource {
rgba,
encoding: this.splatEncoding ?? DEFAULT_SPLAT_ENCODING,
},
)) as {
numSplats: number;
packedArray: Uint32Array;
extra: Record<string, unknown>;
splatEncoding: SplatEncoding;
};
);
});

const lodSplats = new PackedSplats(decoded);
Expand Down
45 changes: 15 additions & 30 deletions src/SparkRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1046,15 +1046,11 @@ export class SparkRenderer extends THREE.Mesh {
if (!this.sortWorker) {
this.sortWorker = new SplatWorker();
}
const result = (await this.sortWorker.call("sortSplats32", {
const result = await this.sortWorker.call("sortSplats32", {
numSplats,
readback,
ordering,
})) as {
readback: Uint32Array<ArrayBuffer>;
ordering: Uint32Array;
activeSplats: number;
};
});

if (this.sortDelay > 0) {
await new Promise((resolve) => setTimeout(resolve, this.sortDelay));
Expand Down Expand Up @@ -1250,9 +1246,9 @@ export class SparkRenderer extends THREE.Mesh {
numFetchers: this.numLodFetchers,
});

const { lodId } = (await worker.call("newLodTree", {
const { lodId } = await worker.call("newLodTree", {
capacity: this.pager.maxSplats,
})) as { lodId: number };
});
this.pagerId = lodId;
}

Expand Down Expand Up @@ -1346,17 +1342,17 @@ export class SparkRenderer extends THREE.Mesh {
splats: PackedSplats | ExtSplats | PagedSplats,
) {
if (splats instanceof PackedSplats || splats instanceof ExtSplats) {
const { lodId } = (await worker.call("initLodTree", {
const { lodId } = await worker.call("initLodTree", {
numSplats: splats.numSplats ?? 0,
lodTree: (splats.extra.lodTree as Uint32Array).slice(),
})) as { lodId: number };
});
this.lodIds.set(splats, { lodId, lastTouched: performance.now() });
this.lodIdToSplats.set(lodId, splats);
// console.log("*** initLodTree", lodId, splats.extra.lodTree, splats);
} else {
const { lodId } = (await worker.call("newSharedLodTree", {
const { lodId } = await worker.call("newSharedLodTree", {
lodId: this.pagerId,
})) as { lodId: number };
});
this.lodIds.set(splats, { lodId, lastTouched: performance.now() });
this.lodIdToSplats.set(lodId, splats);
// console.log("*** newSharedLodTree", lodId, this.pagerId, splats);
Expand Down Expand Up @@ -1438,20 +1434,13 @@ export class SparkRenderer extends THREE.Mesh {
);

const traverseStart = performance.now();
const result = (await worker.call("traverseLodTrees", {
const result = await worker.call("traverseLodTrees", {
maxSplats,
pixelScaleLimit,
lastPixelLimit: this.lastPixelLimit,
instances,
traverseMode: this.lodTraverseMode,
})) as {
keyIndices: Record<
string,
{ lodId: number; numSplats: number; indices: Uint32Array }
>;
chunks: [number, number][];
pixelLimit?: number;
};
});
this.lastTraverseTime = performance.now() - traverseStart;

const { keyIndices, chunks, pixelLimit } = result;
Expand Down Expand Up @@ -1518,16 +1507,12 @@ export class SparkRenderer extends THREE.Mesh {
) {
this.lastLodRaycastTime = performance.now();
const traverseStart = performance.now();
const result = (await worker.call("traverseLodTrees", {
const result = await worker.call("traverseLodTrees", {
maxSplats: Math.min(this.lodRaycast, Math.round(totalLodSplats * 0.1)),
pixelScaleLimit,
instances,
})) as {
keyIndices: Record<
string,
{ lodId: number; numSplats: number; indices: Uint32Array }
>;
};
traverseMode: this.lodTraverseMode,
});
const raycastTraverseTime = performance.now() - traverseStart;

const { keyIndices } = result;
Expand Down Expand Up @@ -2063,10 +2048,10 @@ export class SparkRenderer extends THREE.Mesh {
}

const result = await this.ensureLodWorker().exclusive(async (worker) => {
return (await worker.call("getLodTreeLevel", {
return await worker.call("getLodTreeLevel", {
lodId: instance.lodId,
level,
})) as { indices: Uint32Array };
});
});

if (splats.packedSplats?.lodSplats) {
Expand Down
126 changes: 20 additions & 106 deletions src/SplatLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { ExtSplats, type ExtSplatsOptions } from "./ExtSplats";
import { PackedSplats, type PackedSplatsOptions } from "./PackedSplats";
import { SplatMesh } from "./SplatMesh";
import { workerPool } from "./SplatWorker";
import { type SplatEncoding, SplatFileType } from "./defines";
import { PlyReader } from "./ply";
import { type ExtResult, type PackedResult, SplatFileType } from "./defines";
import { decompressPartialGzip, getTextureSize } from "./utils";

// SplatLoader implements the THREE.Loader interface and supports loading a variety
Expand Down Expand Up @@ -113,19 +112,6 @@ export class SplatLoader extends Loader {
nonLod = splatsNonLod;
}

// let init: {
// numSplats: number;
// packedArray: Uint32Array;
// extra: Record<string, unknown>;
// splatEncoding: SplatEncoding;
// } | null = null;
// let initExt: {
// numSplats: number;
// ext0: Uint32Array;
// ext1: Uint32Array;
// extra: Record<string, unknown>;
// } | null = null;

const onStatus = async (data: unknown) => {
const { loaded, total } = data as { loaded: number; total: number };
if (loaded !== undefined && onProgress) {
Expand Down Expand Up @@ -154,47 +140,12 @@ export class SplatLoader extends Loader {
}
worker.call("nextChunk", { chunk });
}

// if ((data as { orig?: unknown }).orig) {
// if (extSplats) {
// initExt = (data as { orig?: unknown }).orig as {
// numSplats: number;
// ext0: Uint32Array;
// ext1: Uint32Array;
// extra: Record<string, unknown>;
// };
// extSplats.initialize({
// numSplats: initExt?.numSplats,
// extArrays: [initExt?.ext0, initExt?.ext1],
// extra: initExt?.extra,
// });
// calledOnLoad = true;
// onLoad?.(extSplats);
// } else if (packedSplats) {
// init = (data as { orig?: unknown }).orig as {
// numSplats: number;
// packedArray: Uint32Array;
// extra: Record<string, unknown>;
// splatEncoding: SplatEncoding;
// };
// packedSplats.initialize({
// numSplats: init?.numSplats,
// packedArray: init?.packedArray,
// extra: init?.extra,
// splatEncoding: init?.splatEncoding,
// });
// calledOnLoad = true;
// onLoad?.(packedSplats);
// } else {
// console.warn("No splats to initialize");
// }
// }
};

const basedUrl = resolvedURL
? new URL(resolvedURL, window.location.href).toString()
: undefined;
const decoded = (await worker.call(
const decoded = await worker.call(
extSplats ? "loadExtSplats" : "loadPackedSplats",
{
url: basedUrl,
Expand All @@ -212,73 +163,36 @@ export class SplatLoader extends Loader {
lodAbove,
},
{ onStatus },
)) as {
numSplats: number;
packedArray?: Uint32Array;
ext0?: Uint32Array;
ext1?: Uint32Array;
extra: Record<string, unknown>;
splatEncoding?: SplatEncoding;
lodSplats?:
| {
numSplats: number;
packedArray?: Uint32Array;
ext0?: Uint32Array;
ext1?: Uint32Array;
extra: Record<string, unknown>;
splatEncoding?: SplatEncoding;
}
| PackedSplats
| ExtSplats;
};
);

if (decoded.lodSplats) {
// NOTE: Make use of the fact that ExtResult and PackedResult are compatible
// with the ExtSplatsOptions and PackedSplatsOptions types.
const options = decoded as ExtSplatsOptions | PackedSplatsOptions;

// Convert the lodSplats from the Ext/PackedResult
// into actual ExtSplats or PackedSplats if present
if ("lodSplats" in decoded) {
if (extSplats) {
decoded.lodSplats = new ExtSplats({
...(decoded.lodSplats as {
numSplats: number;
extArrays: [Uint32Array, Uint32Array];
extra: Record<string, unknown>;
}),
options.lodSplats = new ExtSplats({
...(decoded.lodSplats as ExtResult),
});
} else {
decoded.lodSplats = new PackedSplats({
...(decoded.lodSplats as {
numSplats: number;
packedArray: Uint32Array;
extra: Record<string, unknown>;
splatEncoding: SplatEncoding;
}),
options.lodSplats = new PackedSplats({
...(decoded.lodSplats as PackedResult),
maxSplats: packedSplats?.maxSplats,
});
}
}

let resultSplats: ExtSplats | PackedSplats;
if (extSplats) {
const initExtSplats = {
// ...(initExt ?? {}),
...decoded,
};
extSplats.initialize(initExtSplats as ExtSplatsOptions);
// if (!calledOnLoad) {
onLoad?.(extSplats);
// }
resultSplats = extSplats;
extSplats.initialize(options as ExtSplatsOptions);
} else {
const initSplats = {
// ...(init ?? {}),
...decoded,
};
if (packedSplats) {
packedSplats.initialize(initSplats as PackedSplatsOptions);
// if (!calledOnLoad) {
onLoad?.(packedSplats);
// }
} else {
// if (!calledOnLoad) {
onLoad?.(new PackedSplats(initSplats as PackedSplatsOptions));
// }
}
resultSplats = packedSplats ?? new PackedSplats();
resultSplats.initialize(options as PackedSplatsOptions);
}
onLoad?.(resultSplats);
})
.catch((error) => {
this.manager.itemError(resolvedURL ?? "");
Expand Down
17 changes: 12 additions & 5 deletions src/SplatPager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,17 @@ export class PagedSplats implements SplatSource {
throw new Error("PagedSplats.pager not set");
}
if (!this.pager.extSplats) {
const result = (await worker.call("loadPackedSplats", {
const result = await worker.call("loadPackedSplats", {
fileBytes: decodeBytes,
pathName: this.chunkUrl(chunk),
sh1Codes: this.sh1Codes?.slice(),
sh2Codes: this.sh2Codes?.slice(),
sh3Codes: this.sh3Codes?.slice(),
})) as { lodSplats: PackedResult };
sh3Codes: (this.sh3Codes as Uint32Array | undefined)?.slice(),
});
if (!("lodSplats" in result)) {
throw new Error("Loaded chunk does not contain LoD splats");
}

const lodSplats = result.lodSplats;
if (!this.splatEncoding) {
this.splatEncoding = lodSplats.splatEncoding;
Expand Down Expand Up @@ -287,15 +291,18 @@ export class PagedSplats implements SplatSource {
}

const sh3Codes = this.sh3Codes as [Uint32Array, Uint32Array] | undefined;
const result = (await worker.call("loadExtSplats", {
const result = await worker.call("loadExtSplats", {
fileBytes: decodeBytes,
pathName: this.chunkUrl(chunk),
sh1Codes: this.sh1Codes?.slice(),
sh2Codes: this.sh2Codes?.slice(),
sh3Codes: sh3Codes
? [sh3Codes[0].slice(), sh3Codes[1].slice()]
: undefined,
})) as { lodSplats: ExtResult };
});
if (!("lodSplats" in result)) {
throw new Error("Loaded chunk does not contain LoD splats");
}
const lodSplats = result.lodSplats;
if (!this.splatEncoding) {
this.splatEncoding = DEFAULT_SPLAT_ENCODING;
Expand Down
Loading
Loading