@voluma/vlam 0.1.0 → 0.2.0
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/LICENSE +21 -0
- package/README.md +60 -0
- package/THIRD_PARTY_NOTICES.md +86 -0
- package/dist/budget-governor.d.ts +154 -0
- package/dist/camera-budget-governor.d.ts +234 -0
- package/dist/chunk-cache-budget.d.ts +156 -0
- package/dist/chunk-fetch-scheduler.d.ts +168 -0
- package/dist/chunk-loader.d.ts +85 -0
- package/dist/compute-sorter.d.ts +131 -0
- package/dist/create-splat-renderer.d.ts +99 -0
- package/dist/dataset-source.d.ts +55 -0
- package/dist/depth-of-field.d.ts +73 -0
- package/dist/effects.d.ts +337 -0
- package/dist/effects.js +180 -0
- package/dist/effects.js.map +1 -0
- package/dist/formats/ksplat/index.d.ts +8 -0
- package/dist/formats/ksplat/parse-ksplat.d.ts +9 -0
- package/dist/formats/ksplat.js +167 -0
- package/dist/formats/ksplat.js.map +1 -0
- package/dist/formats/lcc/collision-mesh.d.ts +37 -0
- package/dist/formats/lcc/collision-partition.d.ts +35 -0
- package/dist/formats/lcc/index.d.ts +16 -0
- package/dist/formats/lcc/lcc.d.ts +28 -0
- package/dist/formats/lcc/lcc2-transform.d.ts +18 -0
- package/dist/formats/lcc/lcc2.d.ts +4 -0
- package/dist/formats/lcc/parse-collision-lci.d.ts +28 -0
- package/dist/formats/lcc/parse-lcc.d.ts +177 -0
- package/dist/formats/lcc/parse-mesh-ply.d.ts +21 -0
- package/dist/formats/lcc.js +969 -0
- package/dist/formats/lcc.js.map +1 -0
- package/dist/formats/ply/index.d.ts +12 -0
- package/dist/formats/ply/parse-compressed-ply.d.ts +16 -0
- package/dist/formats/ply/parse-splat-ply.d.ts +46 -0
- package/dist/formats/ply.js +230 -0
- package/dist/formats/ply.js.map +1 -0
- package/dist/formats/rad/frontier-worker-protocol.d.ts +177 -0
- package/dist/formats/rad/index.d.ts +10 -0
- package/dist/formats/rad/parse-rad.d.ts +88 -0
- package/dist/formats/rad/rad-column-decoders.d.ts +15 -0
- package/dist/formats/rad/rad-foveated-source.d.ts +71 -0
- package/dist/formats/rad/rad-parent-sizes.d.ts +45 -0
- package/dist/formats/rad/rad.d.ts +132 -0
- package/dist/formats/rad.js +1098 -0
- package/dist/formats/rad.js.map +1 -0
- package/dist/formats/sog/index.d.ts +9 -0
- package/dist/formats/sog/parse-sog.d.ts +45 -0
- package/dist/formats/sog.js +257 -0
- package/dist/formats/sog.js.map +1 -0
- package/dist/formats/splat/index.d.ts +8 -0
- package/dist/formats/splat/parse-splat.d.ts +10 -0
- package/dist/formats/splat.js +39 -0
- package/dist/formats/splat.js.map +1 -0
- package/dist/formats/spz/index.d.ts +8 -0
- package/dist/formats/spz/parse-spz.d.ts +10 -0
- package/dist/formats/spz.js +218 -0
- package/dist/formats/spz.js.map +1 -0
- package/dist/frontier-worker-CAnK_Cmu.js +566 -0
- package/dist/frontier-worker-CAnK_Cmu.js.map +1 -0
- package/dist/half-float-Cs4FDq8Q.js +30 -0
- package/dist/half-float-Cs4FDq8Q.js.map +1 -0
- package/dist/half-float.d.ts +15 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +9054 -0
- package/dist/index.js.map +1 -0
- package/dist/load-scene.d.ts +50 -0
- package/dist/load-worker-protocol.d.ts +82 -0
- package/dist/loading-wLo8vRbA.js +102 -0
- package/dist/loading-wLo8vRbA.js.map +1 -0
- package/dist/loading.d.ts +150 -0
- package/dist/lod-manifest.d.ts +61 -0
- package/dist/lod-scheduler.d.ts +229 -0
- package/dist/lod-source.d.ts +207 -0
- package/dist/logging-BfPdd7NJ.js +19 -0
- package/dist/logging-BfPdd7NJ.js.map +1 -0
- package/dist/logging.d.ts +37 -0
- package/dist/one-shot-worker-G80btnth.js +664 -0
- package/dist/one-shot-worker-G80btnth.js.map +1 -0
- package/dist/orientation.d.ts +35 -0
- package/dist/ply-header-BwgExCn-.js +125 -0
- package/dist/ply-header-BwgExCn-.js.map +1 -0
- package/dist/ply-header.d.ts +87 -0
- package/dist/radix-sort.d.ts +28 -0
- package/dist/radix-sorter.d.ts +46 -0
- package/dist/relighting.d.ts +50 -0
- package/dist/selection-volume.d.ts +87 -0
- package/dist/sh-pack-D5wAe5gg.js +54 -0
- package/dist/sh-pack-D5wAe5gg.js.map +1 -0
- package/dist/sh-pack.d.ts +49 -0
- package/dist/sort-scheduler.d.ts +62 -0
- package/dist/sort-worker-protocol.d.ts +37 -0
- package/dist/sorter.d.ts +31 -0
- package/dist/source-transform.d.ts +57 -0
- package/dist/splat-budget-PSojLJPO.js +157 -0
- package/dist/splat-budget-PSojLJPO.js.map +1 -0
- package/dist/splat-budget.d.ts +404 -0
- package/dist/splat-data-BZM5dhhx.js +10 -0
- package/dist/splat-data-BZM5dhhx.js.map +1 -0
- package/dist/splat-data.d.ts +150 -0
- package/dist/splat-depth-pack.d.ts +39 -0
- package/dist/splat-mesh-material.d.ts +255 -0
- package/dist/splat-mesh-picking.d.ts +87 -0
- package/dist/splat-mesh-pool.d.ts +241 -0
- package/dist/splat-mesh-types-8QDjTbZO.js +390 -0
- package/dist/splat-mesh-types-8QDjTbZO.js.map +1 -0
- package/dist/splat-mesh-types.d.ts +390 -0
- package/dist/splat-mesh.d.ts +737 -0
- package/dist/splat-modifier-stack.d.ts +38 -0
- package/dist/splat-modifier.d.ts +156 -0
- package/dist/splat-partition.d.ts +37 -0
- package/dist/splat-query.d.ts +51 -0
- package/dist/splat-scene.d.ts +127 -0
- package/dist/splat-sort-bounds.d.ts +11 -0
- package/dist/static-lod-splat-mesh.d.ts +53 -0
- package/dist/static-lod-worker-D2fyqQZO.js +474 -0
- package/dist/static-lod-worker-D2fyqQZO.js.map +1 -0
- package/dist/static-lod-worker-protocol.d.ts +37 -0
- package/dist/static-lod.d.ts +24 -0
- package/dist/storage-attribute-mirror.d.ts +103 -0
- package/dist/streamed-splat-mesh-utils.d.ts +146 -0
- package/dist/streamed-splat-mesh.d.ts +985 -0
- package/dist/unified-splat-renderer.d.ts +205 -0
- package/dist/webgpu-limits.d.ts +133 -0
- package/dist/work-buffer-gather.d.ts +119 -0
- package/dist/work-buffer-material.d.ts +42 -0
- package/dist/worker-sorter.d.ts +57 -0
- package/dist/xr-view.d.ts +92 -0
- package/package.json +135 -21
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
const o = `var ft = Object.defineProperty;
|
|
2
|
+
var pt = (o, t, e) => t in o ? ft(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
|
+
var k = (o, t, e) => pt(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
class bt {
|
|
5
|
+
constructor(t, e = 65536) {
|
|
6
|
+
k(this, "capacity");
|
|
7
|
+
/** Occupied slots are \`[0, count)\`. */
|
|
8
|
+
k(this, "count", 0);
|
|
9
|
+
/** global index → slot, for the resident frontier. */
|
|
10
|
+
k(this, "slotOf", /* @__PURE__ */ new Map());
|
|
11
|
+
/** slot → global index (valid for \`[0, count)\`). */
|
|
12
|
+
k(this, "slotGlobal");
|
|
13
|
+
/** chunk file → how many of its splats are resident. Never holds a zero. */
|
|
14
|
+
k(this, "residentPerFile", /* @__PURE__ */ new Map());
|
|
15
|
+
k(this, "chunkSize");
|
|
16
|
+
/**
|
|
17
|
+
* Leftover work from a truncated {@link update}, so {@link drain} can finish
|
|
18
|
+
* it without re-diffing.
|
|
19
|
+
*
|
|
20
|
+
* Recomputing the whole desired set to deliver the next \`maxAppends\` splats is
|
|
21
|
+
* what made a cold 4 M-splat frontier take ~66 full traversals plus ~66 full
|
|
22
|
+
* O(frontier) diffs - quadratic, and minutes of "stuck at 1.3 M" on
|
|
23
|
+
* \`cest_ca.rad\`. The leftovers are already computed during the truncation, so
|
|
24
|
+
* keeping them turns the ramp into one O(maxAppends) step per frame.
|
|
25
|
+
*
|
|
26
|
+
* Newcomers stay in the order the traversal emitted them (biggest-on-screen
|
|
27
|
+
* first), so the earliest drains deliver the most visible detail.
|
|
28
|
+
*/
|
|
29
|
+
k(this, "queuedNewcomers", []);
|
|
30
|
+
k(this, "queuedNewcomerIndex", 0);
|
|
31
|
+
/** Stale residents this plan deferred, in the slot order they were found. */
|
|
32
|
+
k(this, "queuedStale", []);
|
|
33
|
+
k(this, "queuedStaleIndex", 0);
|
|
34
|
+
this.capacity = t, this.chunkSize = e, this.slotGlobal = new Int32Array(t).fill(-1);
|
|
35
|
+
}
|
|
36
|
+
/** Whether a truncated plan left work {@link drain} can still deliver. */
|
|
37
|
+
get hasPendingDrain() {
|
|
38
|
+
return this.queuedNewcomerIndex < this.queuedNewcomers.length || this.queuedStaleIndex < this.queuedStale.length;
|
|
39
|
+
}
|
|
40
|
+
/** Forgets any deferred work, so the next plan re-diffs from scratch. */
|
|
41
|
+
clearQueue() {
|
|
42
|
+
this.queuedNewcomers = [], this.queuedNewcomerIndex = 0, this.queuedStale = [], this.queuedStaleIndex = 0;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Swap-removes \`global\` if resident, appending the resulting relocation to
|
|
46
|
+
* \`moves\`. Shared by {@link update}'s leaver pass and {@link drain}.
|
|
47
|
+
*/
|
|
48
|
+
evictGlobal(t, e) {
|
|
49
|
+
const s = this.slotOf.get(t);
|
|
50
|
+
if (s === void 0) return;
|
|
51
|
+
this.slotOf.delete(t), this.release(t);
|
|
52
|
+
const c = this.count - 1;
|
|
53
|
+
if (s !== c) {
|
|
54
|
+
const i = this.slotGlobal[c];
|
|
55
|
+
this.slotGlobal[s] = i, this.slotOf.set(i, s), e.push({ slot: s, global: i });
|
|
56
|
+
}
|
|
57
|
+
this.slotGlobal[c] = -1, this.count = c;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Continues a truncated {@link update} - evicts the next deferred leavers and
|
|
61
|
+
* appends the next \`maxAppends\` deferred newcomers - with no diff against the
|
|
62
|
+
* resident set. Only valid while the frontier that produced the queue is still
|
|
63
|
+
* the one being asked for; any new {@link update}, {@link resize} or
|
|
64
|
+
* {@link clear} discards it.
|
|
65
|
+
*/
|
|
66
|
+
drain(t) {
|
|
67
|
+
const e = this.count, s = [], c = this.queuedNewcomers.length - this.queuedNewcomerIndex, i = this.queuedStale.length - this.queuedStaleIndex, n = this.capacity - this.count, f = n + i, a = Math.max(0, c - f);
|
|
68
|
+
a > 0 && (this.queuedNewcomers.length -= a);
|
|
69
|
+
const u = Math.min(c - a, t, f), r = Math.min(
|
|
70
|
+
i,
|
|
71
|
+
Math.max(u - n, t - u)
|
|
72
|
+
);
|
|
73
|
+
for (let l = 0; l < r; l++)
|
|
74
|
+
this.evictGlobal(this.queuedStale[this.queuedStaleIndex + l], s);
|
|
75
|
+
this.queuedStaleIndex += r;
|
|
76
|
+
const d = this.count, h = new Uint32Array(u);
|
|
77
|
+
for (let l = 0; l < u; l++) {
|
|
78
|
+
const p = this.queuedNewcomers[this.queuedNewcomerIndex + l], w = d + l;
|
|
79
|
+
this.slotGlobal[w] = p, this.slotOf.set(p, w), this.retain(p), h[l] = p;
|
|
80
|
+
}
|
|
81
|
+
this.queuedNewcomerIndex += u, this.count = d + u;
|
|
82
|
+
for (let l = this.count; l < e; l++) this.slotGlobal[l] = -1;
|
|
83
|
+
const M = this.hasPendingDrain;
|
|
84
|
+
return M || this.clearQueue(), {
|
|
85
|
+
moves: s,
|
|
86
|
+
appendStart: d,
|
|
87
|
+
appends: h,
|
|
88
|
+
degenerateStart: this.count,
|
|
89
|
+
degenerateCount: Math.max(0, e - this.count),
|
|
90
|
+
count: this.count,
|
|
91
|
+
dropped: a,
|
|
92
|
+
truncated: M
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** Globals a truncated plan still intends to append, so the caller can keep
|
|
96
|
+
* their chunks cached - gathering an evicted one would write zeros into a slot
|
|
97
|
+
* inside the drawn prefix. */
|
|
98
|
+
pendingAppendGlobals() {
|
|
99
|
+
return this.queuedNewcomerIndex === 0 ? this.queuedNewcomers : this.queuedNewcomers.slice(this.queuedNewcomerIndex);
|
|
100
|
+
}
|
|
101
|
+
/** Records \`global\` as resident (its chunk gains a reference). */
|
|
102
|
+
retain(t) {
|
|
103
|
+
const e = Math.floor(t / this.chunkSize);
|
|
104
|
+
this.residentPerFile.set(e, (this.residentPerFile.get(e) ?? 0) + 1);
|
|
105
|
+
}
|
|
106
|
+
/** Drops \`global\` from the resident set (its chunk loses a reference). */
|
|
107
|
+
release(t) {
|
|
108
|
+
const e = Math.floor(t / this.chunkSize), s = (this.residentPerFile.get(e) ?? 0) - 1;
|
|
109
|
+
s > 0 ? this.residentPerFile.set(e, s) : this.residentPerFile.delete(e);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* True while any splat from chunk \`file\` is still resident in the slab.
|
|
113
|
+
*
|
|
114
|
+
* The worker's cache eviction must consult this: protecting only the chunks
|
|
115
|
+
* the *current* frontier selects is not enough, because \`maxAppends\` leaves
|
|
116
|
+
* deferred leavers resident and drawn for another plan or two. Evicting one of
|
|
117
|
+
* their chunks makes the next {@link gatherGlobals} of that splat - a
|
|
118
|
+
* swap-remove relocation - write zeros into a slot inside the drawn prefix,
|
|
119
|
+
* which shows as dark speckle in the region being refined.
|
|
120
|
+
*/
|
|
121
|
+
hasResidentIn(t) {
|
|
122
|
+
return this.residentPerFile.has(t);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Changes how many slots this pager may fill.
|
|
126
|
+
*
|
|
127
|
+
* The host grows and shrinks the storage behind these slots with the mesh's
|
|
128
|
+
* budget - a near mesh climbs, a distant one gives its pages back - so the
|
|
129
|
+
* pager has to follow. Growing keeps the resident frontier untouched;
|
|
130
|
+
* shrinking evicts the slots past the new capacity and reports them so the
|
|
131
|
+
* host can stop drawing them.
|
|
132
|
+
*
|
|
133
|
+
* @returns the slot range that was evicted, empty when growing.
|
|
134
|
+
*/
|
|
135
|
+
resize(t) {
|
|
136
|
+
if (t === this.capacity) return { start: 0, count: 0 };
|
|
137
|
+
this.clearQueue();
|
|
138
|
+
const e = new Int32Array(t).fill(-1), s = Math.min(this.count, t);
|
|
139
|
+
e.set(this.slotGlobal.subarray(0, s));
|
|
140
|
+
for (let i = s; i < this.count; i++) {
|
|
141
|
+
const n = this.slotGlobal[i];
|
|
142
|
+
n >= 0 && this.slotOf.delete(n) && this.release(n);
|
|
143
|
+
}
|
|
144
|
+
const c = { start: s, count: Math.max(0, this.count - s) };
|
|
145
|
+
return this.slotGlobal = e, this.capacity = t, this.count = s, c;
|
|
146
|
+
}
|
|
147
|
+
/** Current resident frontier size. */
|
|
148
|
+
get residentCount() {
|
|
149
|
+
return this.count;
|
|
150
|
+
}
|
|
151
|
+
/** True iff \`global\` is currently resident. */
|
|
152
|
+
has(t) {
|
|
153
|
+
return this.slotOf.has(t);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Diffs \`desired\` (the new frontier, as global indices) against the resident
|
|
157
|
+
* set and returns the plan to realize it. Mutates internal state to the new
|
|
158
|
+
* frontier as if the plan were applied, so the caller must execute every
|
|
159
|
+
* returned op. \`desired\` may be any iterable; duplicates are ignored.
|
|
160
|
+
*/
|
|
161
|
+
update(t, e) {
|
|
162
|
+
let s = new Set(t);
|
|
163
|
+
const c = this.count, i = [];
|
|
164
|
+
this.clearQueue();
|
|
165
|
+
let n = !1;
|
|
166
|
+
const f = (e == null ? void 0 : e.maxAppends) ?? 1 / 0;
|
|
167
|
+
if (Number.isFinite(f)) {
|
|
168
|
+
const l = [];
|
|
169
|
+
for (const S of s) this.slotOf.has(S) || l.push(S);
|
|
170
|
+
const p = [];
|
|
171
|
+
for (let S = 0; S < this.count; S++) {
|
|
172
|
+
const b = this.slotGlobal[S];
|
|
173
|
+
s.has(b) || p.push(b);
|
|
174
|
+
}
|
|
175
|
+
const w = this.capacity - this.count, F = Math.min(l.length, f, w + p.length), P = Math.min(
|
|
176
|
+
p.length,
|
|
177
|
+
Math.max(F - w, f - F)
|
|
178
|
+
);
|
|
179
|
+
if (n = F < l.length || P < p.length, n) {
|
|
180
|
+
const S = /* @__PURE__ */ new Set();
|
|
181
|
+
for (let b = P; b < p.length; b++) S.add(p[b]);
|
|
182
|
+
for (const b of s) this.slotOf.has(b) && S.add(b);
|
|
183
|
+
for (let b = 0; b < F; b++) S.add(l[b]);
|
|
184
|
+
s = S, this.queuedNewcomers = l.slice(F), this.queuedStale = p.slice(P);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
let a = this.count, u = 0;
|
|
188
|
+
for (; u < a; ) {
|
|
189
|
+
const l = this.slotGlobal[u];
|
|
190
|
+
if (s.has(l)) {
|
|
191
|
+
u++;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (this.slotOf.delete(l), this.release(l), a--, u < a) {
|
|
195
|
+
const p = this.slotGlobal[a];
|
|
196
|
+
this.slotGlobal[u] = p, s.has(p) && (this.slotOf.set(p, u), i.push({ slot: u, global: p }), u++);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const r = a, d = [];
|
|
200
|
+
for (const l of s) this.slotOf.has(l) || d.push(l);
|
|
201
|
+
const h = Math.min(d.length, this.capacity - r), M = new Uint32Array(h);
|
|
202
|
+
for (let l = 0; l < h; l++) {
|
|
203
|
+
const p = d[l], w = r + l;
|
|
204
|
+
this.slotGlobal[w] = p, this.slotOf.set(p, w), this.retain(p), M[l] = p;
|
|
205
|
+
}
|
|
206
|
+
this.count = r + h;
|
|
207
|
+
for (let l = this.count; l < c; l++) this.slotGlobal[l] = -1;
|
|
208
|
+
return {
|
|
209
|
+
moves: i,
|
|
210
|
+
appendStart: r,
|
|
211
|
+
appends: M,
|
|
212
|
+
degenerateStart: this.count,
|
|
213
|
+
degenerateCount: Math.max(0, c - this.count),
|
|
214
|
+
count: this.count,
|
|
215
|
+
dropped: d.length - h,
|
|
216
|
+
truncated: n
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/** Resets to empty (e.g. on scene reload). */
|
|
220
|
+
clear() {
|
|
221
|
+
this.clearQueue(), this.slotOf.clear(), this.residentPerFile.clear(), this.slotGlobal.fill(-1), this.count = 0;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const mt = {
|
|
225
|
+
coneFov0: 90,
|
|
226
|
+
coneFov: 120,
|
|
227
|
+
coneFoveate: 0.4,
|
|
228
|
+
behindFoveate: 0.2
|
|
229
|
+
};
|
|
230
|
+
function gt(o) {
|
|
231
|
+
return o === 1 ? 3 : o === 2 ? 8 : 15;
|
|
232
|
+
}
|
|
233
|
+
function st(o, t, e, s) {
|
|
234
|
+
const c = t.length, i = new Float32Array(c * 3), n = new Uint8Array(c * 4), f = new Float32Array(c * 6);
|
|
235
|
+
let a = 0, u = null;
|
|
236
|
+
for (const h of o.values())
|
|
237
|
+
if (h.shPacked) {
|
|
238
|
+
a = h.shPacked.bands, u = h.shPacked.range;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
const r = a ? gt(a) : 0, d = a ? new Uint32Array(c * r) : null;
|
|
242
|
+
for (let h = 0; h < c; h++) {
|
|
243
|
+
const M = t[h], l = Math.floor(M / e), p = o.get(l);
|
|
244
|
+
if (!p) {
|
|
245
|
+
s && s.missing++;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const w = M - l * e, F = p.positions, P = p.colors, S = p.covariances;
|
|
249
|
+
i[h * 3] = F[w * 3], i[h * 3 + 1] = F[w * 3 + 1], i[h * 3 + 2] = F[w * 3 + 2], n[h * 4] = P[w * 4], n[h * 4 + 1] = P[w * 4 + 1], n[h * 4 + 2] = P[w * 4 + 2], n[h * 4 + 3] = P[w * 4 + 3];
|
|
250
|
+
for (let b = 0; b < 6; b++) f[h * 6 + b] = S[w * 6 + b];
|
|
251
|
+
if (d && p.shPacked && p.shPacked.bands === a) {
|
|
252
|
+
const b = p.shPacked.packed;
|
|
253
|
+
for (let L = 0; L < r; L++) d[h * r + L] = b[w * r + L];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
count: c,
|
|
258
|
+
positions: i,
|
|
259
|
+
colors: n,
|
|
260
|
+
covariances: f,
|
|
261
|
+
...d && a && u ? { shPacked: { bands: a, packed: d, range: u } } : {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function yt(o, t, e = mt) {
|
|
265
|
+
return {
|
|
266
|
+
origin: o,
|
|
267
|
+
...t ? { forward: t } : {},
|
|
268
|
+
coneDot0: e.coneFov0 > 0 ? Math.cos(0.5 * e.coneFov0 * Math.PI / 180) : 1,
|
|
269
|
+
coneDot: e.coneFov > 0 ? Math.cos(0.5 * e.coneFov * Math.PI / 180) : 1,
|
|
270
|
+
coneFoveate: e.coneFoveate,
|
|
271
|
+
behindFoveate: e.behindFoveate
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function K(o, t, e, s, c, i = Number.POSITIVE_INFINITY) {
|
|
275
|
+
const n = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), a = new wt(), u = s.origin.x, r = s.origin.y, d = s.origin.z, h = s.forward, M = (h == null ? void 0 : h.x) ?? 0, l = (h == null ? void 0 : h.y) ?? 0, p = (h == null ? void 0 : h.z) ?? 0, w = h !== void 0, { coneDot0: F, coneDot: P, coneFoveate: S, behindFoveate: b } = s, L = (g) => {
|
|
276
|
+
const y = Math.floor(g / e), m = o.get(y);
|
|
277
|
+
return !m || !m.radTree ? null : { data: m, local: g - y * e };
|
|
278
|
+
}, E = (g, y) => {
|
|
279
|
+
let m = n.get(g);
|
|
280
|
+
m || (m = [], n.set(g, m)), m.push(y);
|
|
281
|
+
}, Z = (g, y) => {
|
|
282
|
+
const m = g.positions, q = y * 3, A = m[q] - u, x = m[q + 1] - r, T = m[q + 2] - d, U = Math.sqrt(A * A + x * x + T * T) || 1e-6, O = g.radTree.size[y] / U;
|
|
283
|
+
if (!w) return O;
|
|
284
|
+
const D = A * M + x * l + T * p;
|
|
285
|
+
if (D <= 0) return O * b;
|
|
286
|
+
const C = D / U;
|
|
287
|
+
if (C >= F) return O;
|
|
288
|
+
if (C >= P) {
|
|
289
|
+
const N = (C - P) / (F - P);
|
|
290
|
+
return O * (S + (1 - S) * N);
|
|
291
|
+
}
|
|
292
|
+
return O * (b + (S - b) * (C / P));
|
|
293
|
+
};
|
|
294
|
+
let R = 0;
|
|
295
|
+
const H = /* @__PURE__ */ new Set();
|
|
296
|
+
for (const g of t) {
|
|
297
|
+
if (H.has(g)) continue;
|
|
298
|
+
const y = L(g);
|
|
299
|
+
y && (H.add(g), a.push(g, Z(y.data, y.local)), R++);
|
|
300
|
+
}
|
|
301
|
+
let J = !1;
|
|
302
|
+
for (; a.size > 0; ) {
|
|
303
|
+
const g = a.peekPriority();
|
|
304
|
+
if (g <= c) break;
|
|
305
|
+
const y = a.peek(), m = L(y);
|
|
306
|
+
if (!m) {
|
|
307
|
+
a.pop(), R--;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const q = Math.floor(y / e), A = m.data.radTree, x = A.childCount[m.local];
|
|
311
|
+
if (x === 0) {
|
|
312
|
+
a.pop(), E(q, m.local);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const T = R - 1 + x;
|
|
316
|
+
if (T > i) {
|
|
317
|
+
J = !0;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
a.pop();
|
|
321
|
+
const U = A.childStart[m.local], O = Math.floor(U / e), D = Math.floor((U + x - 1) / e);
|
|
322
|
+
let C = !0;
|
|
323
|
+
for (let N = O; N <= D; N++)
|
|
324
|
+
o.has(N) || (C = !1, g > (f.get(N) ?? 0) && f.set(N, g));
|
|
325
|
+
if (!C) {
|
|
326
|
+
E(q, m.local);
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
for (let N = 0; N < x; N++) {
|
|
330
|
+
const j = U + N, X = L(j), ot = Z(X.data, X.local);
|
|
331
|
+
ot <= c ? E(Math.floor(j / e), X.local) : a.push(j, ot);
|
|
332
|
+
}
|
|
333
|
+
R = T;
|
|
334
|
+
}
|
|
335
|
+
let Y = !1;
|
|
336
|
+
for (; a.size > 0; ) {
|
|
337
|
+
const g = a.pop(), y = Math.floor(g / e), m = g - y * e;
|
|
338
|
+
if (E(y, m), !Y) {
|
|
339
|
+
const q = o.get(y), A = q == null ? void 0 : q.radTree, x = A ? A.childCount[m] : 0;
|
|
340
|
+
if (x > 0) {
|
|
341
|
+
const T = A.childStart[m], U = Math.floor(T / e), O = Math.floor((T + x - 1) / e);
|
|
342
|
+
let D = !0;
|
|
343
|
+
for (let C = U; C <= O && D; C++)
|
|
344
|
+
o.has(C) || (D = !1);
|
|
345
|
+
D && (Y = !0);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const tt = /* @__PURE__ */ new Map();
|
|
350
|
+
let et = 0;
|
|
351
|
+
for (const [g, y] of n)
|
|
352
|
+
tt.set(g, Uint32Array.from(y)), et += y.length;
|
|
353
|
+
return { selection: tt, count: et, touched: f, budgetClamped: J, refinable: Y };
|
|
354
|
+
}
|
|
355
|
+
class wt {
|
|
356
|
+
constructor() {
|
|
357
|
+
k(this, "items", []);
|
|
358
|
+
// global indices
|
|
359
|
+
k(this, "prio", []);
|
|
360
|
+
}
|
|
361
|
+
get size() {
|
|
362
|
+
return this.items.length;
|
|
363
|
+
}
|
|
364
|
+
/** Largest-priority item, without removing it. Undefined when empty. */
|
|
365
|
+
peek() {
|
|
366
|
+
return this.items[0];
|
|
367
|
+
}
|
|
368
|
+
/** Priority of {@link peek}. */
|
|
369
|
+
peekPriority() {
|
|
370
|
+
return this.prio[0];
|
|
371
|
+
}
|
|
372
|
+
push(t, e) {
|
|
373
|
+
const s = this.items, c = this.prio;
|
|
374
|
+
let i = s.length;
|
|
375
|
+
for (s.push(t), c.push(e); i > 0; ) {
|
|
376
|
+
const n = i - 1 >> 1;
|
|
377
|
+
if (c[n] >= e) break;
|
|
378
|
+
s[i] = s[n], c[i] = c[n], s[n] = t, c[n] = e, i = n;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
pop() {
|
|
382
|
+
const t = this.items, e = this.prio, s = t[0], c = t.pop(), i = e.pop();
|
|
383
|
+
if (t.length > 0) {
|
|
384
|
+
t[0] = c, e[0] = i;
|
|
385
|
+
const n = t.length;
|
|
386
|
+
let f = 0;
|
|
387
|
+
for (; ; ) {
|
|
388
|
+
const a = 2 * f + 1, u = a + 1;
|
|
389
|
+
let r = f;
|
|
390
|
+
if (a < n && e[a] > e[r] && (r = a), u < n && e[u] > e[r] && (r = u), r === f) break;
|
|
391
|
+
const d = t[f], h = e[f];
|
|
392
|
+
t[f] = t[r], e[f] = e[r], t[r] = d, e[r] = h, f = r;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return s;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
const G = /* @__PURE__ */ new Map(), Q = /* @__PURE__ */ new Map(), dt = /* @__PURE__ */ new Set();
|
|
399
|
+
let v = null, I = 65536, B = 256 * 1024 * 1024, _ = 0, V = /* @__PURE__ */ new Set(), z = Number.POSITIVE_INFINITY;
|
|
400
|
+
const $ = 1.6, St = 1 / 32, vt = 0.75, Mt = 0.5, nt = 6e4;
|
|
401
|
+
let W = null;
|
|
402
|
+
function it(o) {
|
|
403
|
+
const t = o.cameraLocal, e = o.cameraForward;
|
|
404
|
+
return \`\${t[0]},\${t[1]},\${t[2]}|\${e[0]},\${e[1]},\${e[2]}|\${o.limit}|\${o.budget}\`;
|
|
405
|
+
}
|
|
406
|
+
function ct(o) {
|
|
407
|
+
const t = [
|
|
408
|
+
o.positions.buffer,
|
|
409
|
+
o.colors.buffer,
|
|
410
|
+
o.covariances.buffer
|
|
411
|
+
];
|
|
412
|
+
return o.shPacked && t.push(o.shPacked.packed.buffer), t;
|
|
413
|
+
}
|
|
414
|
+
function Pt(o, t) {
|
|
415
|
+
if (o !== 0 || !t.radTree) return;
|
|
416
|
+
const { childCount: e, childStart: s } = t.radTree, c = t.count, i = new Uint8Array(c);
|
|
417
|
+
for (let n = 0; n < c; n++) {
|
|
418
|
+
const f = e[n];
|
|
419
|
+
if (f === 0) continue;
|
|
420
|
+
const a = s[n];
|
|
421
|
+
for (let u = 0; u < f; u++) {
|
|
422
|
+
const r = a + u - o * I;
|
|
423
|
+
r >= 0 && r < c && (i[r] = 1);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
for (let n = 0; n < c; n++) i[n] === 0 && dt.add(o * I + n);
|
|
427
|
+
}
|
|
428
|
+
function rt() {
|
|
429
|
+
const o = [];
|
|
430
|
+
if (!v || _ <= B) return o;
|
|
431
|
+
const t = v, e = [...G.keys()].filter((s) => s !== 0 && !V.has(s) && !t.hasResidentIn(s)).sort((s, c) => c - s);
|
|
432
|
+
for (const s of e) {
|
|
433
|
+
if (_ <= B) break;
|
|
434
|
+
_ -= Q.get(s) ?? 0, G.delete(s), Q.delete(s), o.push(s);
|
|
435
|
+
}
|
|
436
|
+
return o;
|
|
437
|
+
}
|
|
438
|
+
function at(o, t, e, s, c) {
|
|
439
|
+
const i = new Uint32Array(t.moves.length), n = new Uint32Array(t.moves.length);
|
|
440
|
+
for (let d = 0; d < t.moves.length; d++)
|
|
441
|
+
i[d] = t.moves[d].slot, n[d] = t.moves[d].global;
|
|
442
|
+
const f = { missing: 0 }, a = st(G, n, I, f), u = st(G, t.appends, I, f), r = {
|
|
443
|
+
type: "plan",
|
|
444
|
+
seq: o,
|
|
445
|
+
moveSlots: i,
|
|
446
|
+
moves: a,
|
|
447
|
+
appendStart: t.appendStart,
|
|
448
|
+
appends: u,
|
|
449
|
+
degenerateStart: t.degenerateStart,
|
|
450
|
+
degenerateCount: t.degenerateCount,
|
|
451
|
+
touched: e,
|
|
452
|
+
residentCount: t.count,
|
|
453
|
+
gatherMissing: f.missing,
|
|
454
|
+
dropped: t.dropped,
|
|
455
|
+
evicted: c,
|
|
456
|
+
solvedLimit: s,
|
|
457
|
+
capacity: v.capacity,
|
|
458
|
+
converged: !t.truncated,
|
|
459
|
+
cacheBytes: _,
|
|
460
|
+
cacheLimitBytes: B
|
|
461
|
+
};
|
|
462
|
+
self.postMessage(r, [
|
|
463
|
+
i.buffer,
|
|
464
|
+
...ct(a),
|
|
465
|
+
...ct(u),
|
|
466
|
+
e.buffer,
|
|
467
|
+
c.buffer
|
|
468
|
+
]);
|
|
469
|
+
}
|
|
470
|
+
let lt = new Uint32Array(0), ht = 0;
|
|
471
|
+
function ut() {
|
|
472
|
+
if (v != null && v.hasPendingDrain)
|
|
473
|
+
for (const o of v.pendingAppendGlobals())
|
|
474
|
+
V.add(Math.floor(o / I));
|
|
475
|
+
}
|
|
476
|
+
function kt(o) {
|
|
477
|
+
if (!v) return;
|
|
478
|
+
if (it(o) === W && v.hasPendingDrain) {
|
|
479
|
+
const r = v.drain(nt);
|
|
480
|
+
ut(), at(o.seq, r, Uint32Array.from(lt), ht, Uint32Array.from(rt()));
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const e = [...dt].filter((r) => G.has(Math.floor(r / I))), s = yt(
|
|
484
|
+
{ x: o.cameraLocal[0], y: o.cameraLocal[1], z: o.cameraLocal[2] },
|
|
485
|
+
{ x: o.cameraForward[0], y: o.cameraForward[1], z: o.cameraForward[2] },
|
|
486
|
+
o
|
|
487
|
+
), c = o.limit * St;
|
|
488
|
+
let i = Math.min(o.limit, Math.max(c, z)), n = K(G, e, I, s, i, o.budget);
|
|
489
|
+
if (n.budgetClamped && i < o.limit)
|
|
490
|
+
i = Math.min(o.limit, i * $), n = K(G, e, I, s, i, o.budget);
|
|
491
|
+
else if (!n.budgetClamped && n.refinable && i > c && n.count < o.budget * Mt) {
|
|
492
|
+
const r = Math.max(c, i / $), d = K(G, e, I, s, r, o.budget);
|
|
493
|
+
!d.budgetClamped && d.count <= o.budget && (i = r, n = d);
|
|
494
|
+
}
|
|
495
|
+
n.budgetClamped ? z = Math.min(o.limit, i * $) : n.refinable && n.count < o.budget * vt ? z = Math.max(c, i / $) : z = i, V = /* @__PURE__ */ new Set();
|
|
496
|
+
const f = [];
|
|
497
|
+
for (const [r, d] of n.selection) {
|
|
498
|
+
V.add(r);
|
|
499
|
+
const h = r * I;
|
|
500
|
+
for (let M = 0; M < d.length; M++) f.push(h + d[M]);
|
|
501
|
+
}
|
|
502
|
+
const a = v.update(f, { maxAppends: nt });
|
|
503
|
+
ut();
|
|
504
|
+
const u = Uint32Array.from(
|
|
505
|
+
[...n.touched].filter(([r]) => !G.has(r)).sort((r, d) => d[1] - r[1]).map(([r]) => r)
|
|
506
|
+
);
|
|
507
|
+
lt = u, ht = i, W = it(o), at(o.seq, a, Uint32Array.from(u), i, Uint32Array.from(rt()));
|
|
508
|
+
}
|
|
509
|
+
self.onmessage = (o) => {
|
|
510
|
+
var e;
|
|
511
|
+
const t = o.data;
|
|
512
|
+
if (t.type === "init") {
|
|
513
|
+
I = t.chunkSize, B = t.cpuCacheBytes, v = new bt(t.capacity, I), W = null;
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (t.type === "resize") {
|
|
517
|
+
v == null || v.resize(t.capacity);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (t.type === "cacheBudget") {
|
|
521
|
+
B = t.cpuCacheBytes;
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (t.type === "chunk") {
|
|
525
|
+
const s = {
|
|
526
|
+
count: t.count,
|
|
527
|
+
positions: t.positions,
|
|
528
|
+
colors: t.colors,
|
|
529
|
+
covariances: t.covariances,
|
|
530
|
+
radTree: { childCount: t.childCount, childStart: t.childStart, size: t.size },
|
|
531
|
+
...t.shBands && t.shPacked && t.shRange ? { shPacked: { bands: t.shBands, packed: t.shPacked, range: t.shRange } } : {}
|
|
532
|
+
}, c = Q.get(t.file);
|
|
533
|
+
c !== void 0 && (_ -= c);
|
|
534
|
+
const i = t.positions.byteLength + t.colors.byteLength + t.covariances.byteLength + t.childCount.byteLength + t.childStart.byteLength + t.size.byteLength + (((e = t.shPacked) == null ? void 0 : e.byteLength) ?? 0);
|
|
535
|
+
G.set(t.file, s), Q.set(t.file, i), _ += i, Pt(t.file, s);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
kt(t);
|
|
539
|
+
};
|
|
540
|
+
//# sourceMappingURL=frontier-worker-Wc3WwHLq.js.map
|
|
541
|
+
`, s = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", o], { type: "text/javascript;charset=utf-8" });
|
|
542
|
+
function r(n) {
|
|
543
|
+
let e;
|
|
544
|
+
try {
|
|
545
|
+
if (e = s && (self.URL || self.webkitURL).createObjectURL(s), !e) throw "";
|
|
546
|
+
const t = new Worker(e, {
|
|
547
|
+
type: "module",
|
|
548
|
+
name: n == null ? void 0 : n.name
|
|
549
|
+
});
|
|
550
|
+
return t.addEventListener("error", () => {
|
|
551
|
+
(self.URL || self.webkitURL).revokeObjectURL(e);
|
|
552
|
+
}), t;
|
|
553
|
+
} catch {
|
|
554
|
+
return new Worker(
|
|
555
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(o),
|
|
556
|
+
{
|
|
557
|
+
type: "module",
|
|
558
|
+
name: n == null ? void 0 : n.name
|
|
559
|
+
}
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
export {
|
|
564
|
+
r as default
|
|
565
|
+
};
|
|
566
|
+
//# sourceMappingURL=frontier-worker-CAnK_Cmu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontier-worker-CAnK_Cmu.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function N(r) {
|
|
2
|
+
const o = r & 32768 ? -1 : 1, t = r >>> 10 & 31, n = r & 1023;
|
|
3
|
+
return t === 0 ? o * 2 ** -14 * (n / 1024) : t === 31 ? n === 0 ? o * (1 / 0) : Number.NaN : o * 2 ** (t - 15) * (1 + n / 1024);
|
|
4
|
+
}
|
|
5
|
+
function c(r) {
|
|
6
|
+
if (Number.isNaN(r)) return 32256;
|
|
7
|
+
if (!Number.isFinite(r)) return r > 0 ? 31744 : 64512;
|
|
8
|
+
s[0] = r;
|
|
9
|
+
const o = a[0], t = o >>> 16 & 32768;
|
|
10
|
+
let n = o >>> 23 & 255, e = o & 8388607;
|
|
11
|
+
if (n < 113) {
|
|
12
|
+
if (n < 103) return t;
|
|
13
|
+
e |= 8388608;
|
|
14
|
+
const f = 113 - n, u = (e >>> f + 13) + (e >>> f + 12 & 1);
|
|
15
|
+
return t | u;
|
|
16
|
+
}
|
|
17
|
+
if (n > 142) return t | 31743;
|
|
18
|
+
const i = e + 4095 + (e >>> 13 & 1);
|
|
19
|
+
return i & 8388608 ? (n += 1, n > 142 ? t | 31743 : t | n - 112 << 10) : t | n - 112 << 10 | i >>> 13;
|
|
20
|
+
}
|
|
21
|
+
function l(r, o, t = 0, n = r.length - t, e = 0) {
|
|
22
|
+
for (let i = 0; i < n; i++)
|
|
23
|
+
o[e + i] = c(r[t + i]);
|
|
24
|
+
}
|
|
25
|
+
const s = new Float32Array(1), a = new Uint32Array(s.buffer);
|
|
26
|
+
export {
|
|
27
|
+
l as e,
|
|
28
|
+
N as h
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=half-float-Cs4FDq8Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"half-float-Cs4FDq8Q.js","sources":["../src/lib/half-float.ts"],"sourcesContent":["/** Decodes an IEEE 754 half-precision (binary16) value to a JS number. */\nexport function halfToFloat(value: number): number {\n const sign = value & 0x8000 ? -1 : 1;\n const exponent = (value >>> 10) & 0x1f;\n const fraction = value & 0x03ff;\n if (exponent === 0) return sign * 2 ** -14 * (fraction / 1024);\n if (exponent === 0x1f) return fraction === 0 ? sign * Infinity : Number.NaN;\n return sign * 2 ** (exponent - 15) * (1 + fraction / 1024);\n}\n\n/**\n * Encodes a JS number as IEEE 754 half-precision (binary16) bits.\n *\n * Finite values outside ±65504 clamp to the half max; NaN → quiet NaN;\n * ±Infinity stay infinite. Used when packing float32 pool backing into\n * `rgba16float` GPU textures.\n */\nexport function floatToHalf(value: number): number {\n if (Number.isNaN(value)) return 0x7e00;\n if (!Number.isFinite(value)) return value > 0 ? 0x7c00 : 0xfc00;\n\n // Reinterpret as float32 bits without a DataView allocation on the hot path.\n _f32[0] = value;\n const bits = _u32[0] as number;\n const sign = (bits >>> 16) & 0x8000;\n let exponent = (bits >>> 23) & 0xff;\n let mantissa = bits & 0x7fffff;\n\n // Too small for a normalized half → flush to signed zero (or denormal).\n if (exponent < 113) {\n if (exponent < 103) return sign;\n // Denormal: shift the implicit 1 into the mantissa.\n mantissa |= 0x800000;\n const shift = 113 - exponent;\n const denorm = (mantissa >>> (shift + 13)) + ((mantissa >>> (shift + 12)) & 1);\n return sign | denorm;\n }\n\n // Overflow → clamp to ±65504 (max finite half), not infinity: pool centers\n // and covariances that blow the half range should stay finite for sampling.\n if (exponent > 142) return sign | 0x7bff;\n\n // Round-to-nearest-even on the 10-bit mantissa.\n const rounded = mantissa + 0x0fff + ((mantissa >>> 13) & 1);\n if (rounded & 0x800000) {\n // Mantissa overflow into the exponent.\n exponent += 1;\n if (exponent > 142) return sign | 0x7bff;\n return sign | ((exponent - 112) << 10);\n }\n return sign | ((exponent - 112) << 10) | (rounded >>> 13);\n}\n\n/**\n * Packs `src[srcOffset..srcOffset+count)` into half bits at `dst[dstOffset..]`.\n * Lengths are in elements (floats / halfs), not bytes.\n */\nexport function encodeFloat32ToHalf(\n src: Float32Array,\n dst: Uint16Array,\n srcOffset = 0,\n count = src.length - srcOffset,\n dstOffset = 0,\n): void {\n for (let i = 0; i < count; i++) {\n dst[dstOffset + i] = floatToHalf(src[srcOffset + i] as number);\n }\n}\n\nconst _f32 = new Float32Array(1);\nconst _u32 = new Uint32Array(_f32.buffer);\n"],"names":["halfToFloat","value","sign","exponent","fraction","floatToHalf","_f32","bits","_u32","mantissa","shift","denorm","rounded","encodeFloat32ToHalf","src","dst","srcOffset","count","dstOffset"],"mappings":"AACO,SAASA,EAAYC,GAAuB;AACjD,QAAMC,IAAOD,IAAQ,QAAS,KAAK,GAC7BE,IAAYF,MAAU,KAAM,IAC5BG,IAAWH,IAAQ;AACzB,SAAIE,MAAa,IAAUD,IAAO,KAAK,OAAOE,IAAW,QACrDD,MAAa,KAAaC,MAAa,IAAIF,IAAO,UAAW,OAAO,MACjEA,IAAO,MAAMC,IAAW,OAAO,IAAIC,IAAW;AACvD;AASO,SAASC,EAAYJ,GAAuB;AACjD,MAAI,OAAO,MAAMA,CAAK,EAAG,QAAO;AAChC,MAAI,CAAC,OAAO,SAASA,CAAK,EAAG,QAAOA,IAAQ,IAAI,QAAS;AAGzD,EAAAK,EAAK,CAAC,IAAIL;AACV,QAAMM,IAAOC,EAAK,CAAC,GACbN,IAAQK,MAAS,KAAM;AAC7B,MAAIJ,IAAYI,MAAS,KAAM,KAC3BE,IAAWF,IAAO;AAGtB,MAAIJ,IAAW,KAAK;AAClB,QAAIA,IAAW,IAAK,QAAOD;AAE3B,IAAAO,KAAY;AACZ,UAAMC,IAAQ,MAAMP,GACdQ,KAAUF,MAAcC,IAAQ,OAASD,MAAcC,IAAQ,KAAO;AAC5E,WAAOR,IAAOS;AAAA,EAChB;AAIA,MAAIR,IAAW,IAAK,QAAOD,IAAO;AAGlC,QAAMU,IAAUH,IAAW,QAAWA,MAAa,KAAM;AACzD,SAAIG,IAAU,WAEZT,KAAY,GACRA,IAAW,MAAYD,IAAO,QAC3BA,IAASC,IAAW,OAAQ,MAE9BD,IAASC,IAAW,OAAQ,KAAOS,MAAY;AACxD;AAMO,SAASC,EACdC,GACAC,GACAC,IAAY,GACZC,IAAQH,EAAI,SAASE,GACrBE,IAAY,GACN;AACN,WAAS,IAAI,GAAG,IAAID,GAAO;AACzB,IAAAF,EAAIG,IAAY,CAAC,IAAIb,EAAYS,EAAIE,IAAY,CAAC,CAAW;AAEjE;AAEA,MAAMV,IAAO,IAAI,aAAa,CAAC,GACzBE,IAAO,IAAI,YAAYF,EAAK,MAAM;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Decodes an IEEE 754 half-precision (binary16) value to a JS number. */
|
|
2
|
+
export declare function halfToFloat(value: number): number;
|
|
3
|
+
/**
|
|
4
|
+
* Encodes a JS number as IEEE 754 half-precision (binary16) bits.
|
|
5
|
+
*
|
|
6
|
+
* Finite values outside ±65504 clamp to the half max; NaN → quiet NaN;
|
|
7
|
+
* ±Infinity stay infinite. Used when packing float32 pool backing into
|
|
8
|
+
* `rgba16float` GPU textures.
|
|
9
|
+
*/
|
|
10
|
+
export declare function floatToHalf(value: number): number;
|
|
11
|
+
/**
|
|
12
|
+
* Packs `src[srcOffset..srcOffset+count)` into half bits at `dst[dstOffset..]`.
|
|
13
|
+
* Lengths are in elements (floats / halfs), not bytes.
|
|
14
|
+
*/
|
|
15
|
+
export declare function encodeFloat32ToHalf(src: Float32Array, dst: Uint16Array, srcOffset?: number, count?: number, dstOffset?: number): void;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VLAM! | a WebGPU-first 3D Gaussian Splatting renderer for three.js.
|
|
3
|
+
*
|
|
4
|
+
* Public API surface. Everything else under `src/lib/` is internal and may
|
|
5
|
+
* change without notice.
|
|
6
|
+
*
|
|
7
|
+
* Format-specific parsers live on optional subpaths:
|
|
8
|
+
* - `@voluma/vlam/formats/ply` - 3DGS `.ply`, raw and compressed
|
|
9
|
+
* - `@voluma/vlam/formats/sog` - PlayCanvas SOG, bundled and unbundled
|
|
10
|
+
* - `@voluma/vlam/formats/rad` - Spark `.rad`/`.radc`
|
|
11
|
+
* - `@voluma/vlam/formats/lcc` - XGRIDS LCC / `.lcc2` + collision helpers
|
|
12
|
+
* - `@voluma/vlam/formats/spz` - Niantic `.spz`
|
|
13
|
+
* - `@voluma/vlam/formats/splat` - antimatter15 `.splat`
|
|
14
|
+
* - `@voluma/vlam/formats/ksplat` - mkkellogg `.ksplat`
|
|
15
|
+
*
|
|
16
|
+
* {@link loadScene} / {@link StreamedSplatMesh.load} still accept those formats
|
|
17
|
+
* without importing a subpath; the library loads format code on demand.
|
|
18
|
+
*
|
|
19
|
+
* @module core
|
|
20
|
+
*/
|
|
21
|
+
export { SplatMesh, MAX_SH_BANDS, DEFAULT_FOVEATION_TARGET_PX, DEFAULT_FOVEATION_DRAW_BUDGET, resolveSplatPerformanceProfile, type UnifiedSourceView, type SplatMeshOptions, type SplatUpdateOptions, type SplatSortStrategy, type SplatPerformanceProfile, type SplatRange, type SplatPickOptions, type SplatPickResult, type SplatNearestResult, type SplatRayResult, type SplatHeightResult, type SplatChannelType, type SplatChannelOptions, } from './splat-mesh';
|
|
22
|
+
export { SplatPool, type SplatPoolOptions } from './splat-mesh-pool';
|
|
23
|
+
export { SPLAT_DATA_TEXTURE_WIDTH, deviceMaxTextureSize, assertPoolRowsFitDevice, } from './splat-mesh-pool';
|
|
24
|
+
export { MAX_DOF_RADIUS_PX, MAX_DOF_VARIANCE, apertureAngleFromSize, computeDofCocVariancePx2, computeDofOpacityFade, clampDepthOfFieldSettings, type DepthOfFieldSettings, } from './depth-of-field';
|
|
25
|
+
export { DEFAULT_RELIGHT_BLEND, DEFAULT_RELIGHT_BRIGHTNESS, DEFAULT_RELIGHT_BACKGROUND, DEFAULT_RELIGHT_SOFTNESS, clampRelightingSettings, createPlaceholderRelightTexture, type RelightingSettings, type RelightingUniforms, } from './relighting';
|
|
26
|
+
export { type SplatOrientation, type OrientableFormat, createYUpTransform, yUpTransformForFormat, } from './orientation';
|
|
27
|
+
export { StreamedSplatMesh, type StreamedSplatMeshOptions, type InitialRevealState, type PersistentChannelOptions, type StreamedSplatPerformanceEvent, } from './streamed-splat-mesh';
|
|
28
|
+
export { StaticLodSplatMesh, type StaticLodSplatMeshOptions, type StaticLodSplatMeshLoadOptions, type StaticLodLoadProgress, } from './static-lod-splat-mesh';
|
|
29
|
+
export type { StaticLodBuildProgress } from './static-lod';
|
|
30
|
+
export { SplatScene, type SplatSceneOptions, type AddSourceOptions } from './splat-scene';
|
|
31
|
+
export { MAX_SOURCES } from './source-transform';
|
|
32
|
+
export type { SplatShInputs, Vec3Uniform } from './splat-mesh-material';
|
|
33
|
+
export { UnifiedSplatRenderer, supportsUnifiedSplatRenderer, type UnifiedSplatPickResult, type UnifiedSplatRendererOptions, type UnifiedSplatSourceOptions, } from './unified-splat-renderer';
|
|
34
|
+
export { resolveSplatBudget, detectSplatDeviceProfile, classifySplatGpuClass, probeSplatGpuClass, isFillConstrainedSplatDevice, recommendedMaxPixelRatio, recommendedRadMaxStdDev, recommendedXrFramebufferScale, resolveXrSplatBudget, resolveCpuCacheBytes, suggestAdaptivePixelRatio, estimateSplatPoolBytes, type SplatBudgetOptions, type SplatCostClass, type SplatDeviceProfile, type SplatGpuClass, type SplatGpuAdapterInfo, type AdaptivePixelRatioInput, type AdaptivePixelRatioResult, type SplatPoolBytesOptions, } from './splat-budget';
|
|
35
|
+
export { xrSessionInit } from './xr-view';
|
|
36
|
+
export { BudgetGovernor, type BudgetGovernorOptions, type BudgetGovernedMember, } from './budget-governor';
|
|
37
|
+
export { CameraBudgetGovernor, type CameraBudgetGovernorOptions, type CameraBudgetMember, type CameraBudgetMemberOptions, } from './camera-budget-governor';
|
|
38
|
+
export { createSplatRenderer, type CreateSplatRendererOptions, type SplatRendererGpu, type SplatRendererGpuAdapter, type SplatRendererGpuDevice, } from './create-splat-renderer';
|
|
39
|
+
export { recommendedWebGpuRequiredLimits, supportsWebGpuPowerPreference, webGpuPowerPreferenceOptions, estimateLargestStorageBufferBytes, estimateUnifiedWorkBufferBytes, estimateUnifiedWorkBufferPeakBytes, deviceMaxStorageBufferBindingSize, assertStorageBufferFitsDevice, WORK_BUFFER_CENTERS_BYTES_PER_SPLAT, WORK_BUFFER_BYTES_PER_SLOT, WEBGPU_DEFAULT_MAX_STORAGE_BUFFER_BINDING_SIZE, type WebGpuRequiredLimits, type WebGpuPowerPreference, } from './webgpu-limits';
|
|
40
|
+
export { loadScene, loadSceneFile, type SplatLoadOptions, type SplatFileLoadOptions, } from './load-scene';
|
|
41
|
+
export { ChunkLoader } from './chunk-loader';
|
|
42
|
+
export { ChunkFetchScheduler, type ChunkFetchSchedulerOptions, type ChunkFetchClient, type ChunkFetchHandle, type ChunkFetchKind, } from './chunk-fetch-scheduler';
|
|
43
|
+
export { ChunkCacheBudget, type ChunkCacheBudgetOptions, type ChunkCacheClient, type ChunkCacheHandle, } from './chunk-cache-budget';
|
|
44
|
+
export { SplatLoadError, isAbortError, type SplatProgressCallback, type SplatFormat, type SplatSourceFormat, type StreamedSplatFormat, type SplatRequestOptions, type SplatLoadPhase, type SplatInputOptions, type ChunkFileFormat, } from './loading';
|
|
45
|
+
export type { CollisionMeshTile } from './formats/lcc/collision-mesh';
|
|
46
|
+
export type { SceneCollision, CollisionMeshDescriptor, EnvironmentTile } from './lod-source';
|
|
47
|
+
export { httpDatasetSource, createLocalDataset } from './dataset-source';
|
|
48
|
+
export type { SplatDatasetSource, LocalDataset } from './dataset-source';
|
|
49
|
+
export type { SplatData, SplatShData, SplatPackedShData } from './splat-data';
|
|
50
|
+
export { createSelectionVolume, selectInData, countInData, type SelectionVolume, type SelectionVolumeKind, type SelectionVolumeOptions, } from './selection-volume';
|
|
51
|
+
export { partitionSplatData, type SplatPartition } from './splat-partition';
|
|
52
|
+
export type { SplatModifier, SplatContext, SplatOutputs, ModifierStackTarget, } from './splat-modifier';
|
|
53
|
+
export { ModifierSlots } from './splat-modifier';
|
|
54
|
+
export { setVlamLogHandler, type VlamLogHandler, type VlamLogLevel } from './logging';
|