@kalyptos/narcissus 0.1.3 → 0.2.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/dist/index.d.ts CHANGED
@@ -2,4 +2,5 @@ export * from './engine/index.ts';
2
2
  export { Missing } from './ports.ts';
3
3
  export { http } from './adapters/http.ts';
4
4
  export { files } from './adapters/files.ts';
5
+ export { encodeLayer, type Splats } from './format/index.ts';
5
6
  export * from './controls/index.ts';
package/dist/index.js CHANGED
@@ -1,17 +1,18 @@
1
- import { S as e, _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, p as m, r as h, s as g, t as _, u as v, v as y, x as b, y as x } from "./controls-IBLB-RWS.js";
2
- import { t as S } from "./ports-DZRKjdYD.js";
3
- import { t as C } from "./http-DL7R39Nc.js";
1
+ import { r as e } from "./format-CbtEy9NS.js";
2
+ import { C as t, S as n, _ as r, a as i, b as a, c as o, d as s, f as c, g as l, h as u, i as d, l as f, m as p, n as m, o as h, p as g, r as _, s as v, t as y, u as b, v as x, w as S, x as C, y as w } from "./controls--A-CvrQ5.js";
3
+ import { t as T } from "./ports-DZRKjdYD.js";
4
+ import { t as E } from "./http-DL7R39Nc.js";
4
5
  //#region src/engine/plugins/grade.wgsl?raw
5
- var w = "// the clarity grade on display colour, every pixel\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n\n// vibrance lifts muted colours most, a luma-only curve deepens blacks and keeps hue and greys\nfn gradeGamma(color: vec3f) -> vec3f {\n let l: f32 = dot(color, vec3f(0.2126, 0.7152, 0.0722));\n let chroma: f32 = max(color.r, max(color.g, color.b)) - min(color.r, min(color.g, color.b));\n let c: vec3f = l + (color - l) * (1.0 + 0.35 * (1.0 - chroma));\n var k: f32 = clamp((l - 0.02) / 0.98, 0.0, 1.0);\n k = mix(k, k * k * (3.0 - 2.0 * k), 0.2);\n return clamp(c * (k / max(l, 0.0001)), vec3f(0.0), vec3f(1.0));\n}\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n return vec4f(gradeGamma(textureLoad(scene, vec2i(coord.xy), 0).rgb), 1.0);\n}\n";
6
+ var D = "// the clarity grade on display colour, every pixel\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n\n// vibrance lifts muted colours most, a luma-only curve deepens blacks and keeps hue and greys\nfn gradeGamma(color: vec3f) -> vec3f {\n let l: f32 = dot(color, vec3f(0.2126, 0.7152, 0.0722));\n let chroma: f32 = max(color.r, max(color.g, color.b)) - min(color.r, min(color.g, color.b));\n let c: vec3f = l + (color - l) * (1.0 + 0.35 * (1.0 - chroma));\n var k: f32 = clamp((l - 0.02) / 0.98, 0.0, 1.0);\n k = mix(k, k * k * (3.0 - 2.0 * k), 0.2);\n return clamp(c * (k / max(l, 0.0001)), vec3f(0.0), vec3f(1.0));\n}\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n return vec4f(gradeGamma(textureLoad(scene, vec2i(coord.xy), 0).rgb), 1.0);\n}\n";
6
7
  //#endregion
7
8
  //#region src/engine/plugins/grade.ts
8
- function T() {
9
- return (t) => t.post({
9
+ function O() {
10
+ return (e) => e.post({
10
11
  name: "grade",
11
- setup(t, n) {
12
- let r = new e(t, "grade", w, n);
12
+ setup(e, t) {
13
+ let n = new S(e, "grade", D, t);
13
14
  return {
14
- run: (e, t, n, i, a) => r.encode(e, [n], a),
15
+ run: (e, t, r, i, a) => n.encode(e, [r], a),
15
16
  destroy() {}
16
17
  };
17
18
  }
@@ -19,34 +20,34 @@ function T() {
19
20
  }
20
21
  //#endregion
21
22
  //#region src/engine/plugins/dof.wgsl?raw
22
- var E = "// far-field depth of field: each pixel gathers a disc as wide as its blur, from taps whose own blur reaches it\n\nstruct Dof {\n focus: f32,\n range: f32,\n near: f32,\n // ln(far / near)\n span: f32,\n // pixels at full blur\n radius: f32,\n}\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n@group(0) @binding(1) var depth: texture_depth_2d;\n@group(0) @binding(2) var<uniform> dof: Dof;\n\nconst TAPS = 32u;\nconst GOLDEN = 2.39996323;\n\n// blur radius in pixels: none up to the focus, full a range past it\nfn blur(p: vec2i) -> f32 {\n let z = dof.near * exp(textureLoad(depth, p, 0) * dof.span);\n return clamp((z - dof.focus) / dof.range, 0.0, 1.0) * dof.radius;\n}\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n let p = vec2i(coord.xy);\n let r = blur(p);\n var sum = textureLoad(scene, p, 0).rgb;\n if (r < 0.5) {\n return vec4f(sum, 1.0);\n }\n let last = vec2i(textureDimensions(scene)) - 1;\n var weight = 1.0;\n // golden-angle spiral, even over the disc\n for (var k = 0u; k < TAPS; k++) {\n let rho = sqrt((f32(k) + 0.5) / f32(TAPS)) * r;\n let angle = f32(k) * GOLDEN;\n let q = clamp(p + vec2i(round(rho * vec2f(cos(angle), sin(angle)))), vec2i(0), last);\n // a sharper tap keeps its colour, so focused edges don't bleed into the blur\n let w = clamp(blur(q) - rho + 1.0, 0.0, 1.0);\n sum += textureLoad(scene, q, 0).rgb * w;\n weight += w;\n }\n return vec4f(sum / weight, 1.0);\n}\n", D = .5, O = 3;
23
- function k(t, n = () => 1) {
24
- return (r) => r.post({
23
+ var k = "// far-field depth of field: each pixel gathers a disc as wide as its blur, from taps whose own blur reaches it\n\nstruct Dof {\n focus: f32,\n range: f32,\n near: f32,\n // ln(far / near)\n span: f32,\n // pixels at full blur\n radius: f32,\n}\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n@group(0) @binding(1) var depth: texture_depth_2d;\n@group(0) @binding(2) var<uniform> dof: Dof;\n\nconst TAPS = 32u;\nconst GOLDEN = 2.39996323;\n\n// blur radius in pixels: none up to the focus, full a range past it\nfn blur(p: vec2i) -> f32 {\n let z = dof.near * exp(textureLoad(depth, p, 0) * dof.span);\n return clamp((z - dof.focus) / dof.range, 0.0, 1.0) * dof.radius;\n}\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n let p = vec2i(coord.xy);\n let r = blur(p);\n var sum = textureLoad(scene, p, 0).rgb;\n if (r < 0.5) {\n return vec4f(sum, 1.0);\n }\n let last = vec2i(textureDimensions(scene)) - 1;\n var weight = 1.0;\n // golden-angle spiral, even over the disc\n for (var k = 0u; k < TAPS; k++) {\n let rho = sqrt((f32(k) + 0.5) / f32(TAPS)) * r;\n let angle = f32(k) * GOLDEN;\n let q = clamp(p + vec2i(round(rho * vec2f(cos(angle), sin(angle)))), vec2i(0), last);\n // a sharper tap keeps its colour, so focused edges don't bleed into the blur\n let w = clamp(blur(q) - rho + 1.0, 0.0, 1.0);\n sum += textureLoad(scene, q, 0).rgb * w;\n weight += w;\n }\n return vec4f(sum / weight, 1.0);\n}\n", A = .5, j = 3;
24
+ function M(e, t = () => 1) {
25
+ return (n) => n.post({
25
26
  name: "dof",
26
27
  depth: !0,
27
- setup(r, i) {
28
- let a = new e(r, "dof", E, i), o = r.createBuffer({
28
+ setup(n, r) {
29
+ let i = new S(n, "dof", k, r), a = n.createBuffer({
29
30
  label: "dof",
30
31
  size: 32,
31
32
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
32
- }), s = { buffer: o }, c = /* @__PURE__ */ new Float32Array(8);
33
+ }), o = { buffer: a }, s = /* @__PURE__ */ new Float32Array(8);
33
34
  return {
34
- run(e, i, l, u, d) {
35
- let f = t(), { near: p, far: m, height: h } = i;
36
- c.set([
35
+ run(r, c, l, u, d) {
36
+ let f = e(), { near: p, far: m, height: h } = c;
37
+ s.set([
37
38
  f,
38
- f * D,
39
+ f * A,
39
40
  p,
40
41
  Math.log(m / p),
41
- O * h * n() / 540
42
- ]), r.queue.writeBuffer(o, 0, c), a.encode(e, [
42
+ j * h * t() / 540
43
+ ]), n.queue.writeBuffer(a, 0, s), i.encode(r, [
43
44
  l,
44
45
  u,
45
- s
46
+ o
46
47
  ], d);
47
48
  },
48
49
  destroy() {
49
- o.destroy();
50
+ a.destroy();
50
51
  }
51
52
  };
52
53
  }
@@ -54,14 +55,14 @@ function k(t, n = () => 1) {
54
55
  }
55
56
  //#endregion
56
57
  //#region src/engine/plugins/fog.wgsl?raw
57
- var A = "// u[0] holds the fog colour and the start depth, u[1].x the far clip\nfn fog(s: ptr<function, Splat>, u: array<vec4f, 2>) {\n let t = clamp(((*s).depth - u[0].w) / max(u[1].x - u[0].w, 1e-3), 0.0, 1.0);\n (*s).colour = mix((*s).colour, u[0].rgb, t);\n}\n";
58
+ var N = "// u[0] holds the fog colour and the start depth, u[1].x the far clip\nfn fog(s: ptr<function, Splat>, u: array<vec4f, 2>) {\n let t = clamp(((*s).depth - u[0].w) / max(u[1].x - u[0].w, 1e-3), 0.0, 1.0);\n (*s).colour = mix((*s).colour, u[0].rgb, t);\n}\n";
58
59
  //#endregion
59
60
  //#region src/engine/plugins/fog.ts
60
- function j(e, t = .5) {
61
+ function P(e, t = .5) {
61
62
  return (n) => n.shade({
62
63
  name: "fog",
63
64
  uniforms: 2,
64
- wgsl: A,
65
+ wgsl: N,
65
66
  update(n, r) {
66
67
  r.set(e), r[3] = t * n.far, r[4] = n.far, r.fill(0, 5, 8);
67
68
  }
@@ -69,13 +70,13 @@ function j(e, t = .5) {
69
70
  }
70
71
  //#endregion
71
72
  //#region src/adapters/files.ts
72
- function M(e) {
73
+ function F(e) {
73
74
  return async (t, n) => {
74
75
  let r = e.get(t);
75
- if (!r) throw new S(`no file ${t}`);
76
+ if (!r) throw new T(`no file ${t}`);
76
77
  let i = n ? r.slice(n[0], n[1]) : r;
77
78
  return new Uint8Array(await i.arrayBuffer());
78
79
  };
79
80
  }
80
81
  //#endregion
81
- export { _ as Controls, f as FOV, h as LIMITS, b as MIN_BUDGET, S as Missing, x as NoWebGpu, l as blend, n as cameraOf, p as clampPose, r as createEngine, g as defaultView, k as dof, M as files, i as fly, j as fog, u as formatPose, T as grade, v as height, C as http, a as look, o as lookAt, m as opening, d as pan, c as parsePose, s as project, t as settled, y as viewOf };
82
+ export { y as Controls, m as FOV, _ as LIMITS, t as MIN_BUDGET, T as Missing, C as NoWebGpu, d as blend, i as cameraOf, h as clampPose, n as createEngine, v as defaultView, M as dof, e as encodeLayer, F as files, o as fit, f as flight, b as fly, P as fog, s as formatPose, O as grade, c as height, E as http, g as look, p as lookAt, u as opening, l as pan, r as parsePose, x as project, w as settled, a as viewOf };
@@ -0,0 +1,212 @@
1
+ import { S as e, _ as t, a as n, i as r, n as i, t as a, y as o, z as s } from "./format-CbtEy9NS.js";
2
+ import { t as c } from "./ports-DZRKjdYD.js";
3
+ //#region src/engine/stream/synthetic.ts
4
+ var l = 128, u = 16384, d = Math.min(u, 2048, Math.max(256, Math.ceil(u / 12 / 64) * 64)), f = 128 + 19 * u + d * 9, p = 65535, m = 5, h = f + Math.ceil(f / p) * m, g = 12, _ = .4, v = .6, y = 1.2, b = .15, x = .1, S = .04, C = [
5
+ [
6
+ 12,
7
+ 1 / 7e3,
8
+ 0,
9
+ 1 / 9e3,
10
+ .7
11
+ ],
12
+ [
13
+ 9,
14
+ 1 / 2300,
15
+ 1.1,
16
+ 1 / 3100,
17
+ .4
18
+ ],
19
+ [
20
+ 6,
21
+ 1 / 800,
22
+ .3,
23
+ 1 / 1100,
24
+ 2
25
+ ],
26
+ [
27
+ 3,
28
+ 1 / 150,
29
+ .9,
30
+ 1 / 210,
31
+ 1.7
32
+ ]
33
+ ], w = 30, T = C.reduce((e, [t, n, , r]) => e + t * (n + r), 0), E = Float32Array.from({ length: d * 9 }, (e, t) => {
34
+ let n = Math.floor(t / 9), r = t % 9, i = (n * (37 + 2 * r) + 11 * r) % 255 - 127;
35
+ return r === 0 && (i = n % 255 - 127), r === 1 && (i = 20 * Math.floor(n / 255) - 50), i / 127 * S;
36
+ }), D = new TextEncoder(), O = {
37
+ version: 1,
38
+ crs: "synthetic",
39
+ height: "synthetic",
40
+ leaf: 250,
41
+ roots: [512e4, 6144e3].map((e) => ({
42
+ level: g,
43
+ e: 0,
44
+ n: e
45
+ })).map((e) => ({
46
+ ...e,
47
+ idx: o(e, N(e, "idx"), "idx")
48
+ })),
49
+ extent: {
50
+ e: [44e4, 9e5],
51
+ n: [605e4, 641e4],
52
+ h: [0, 80]
53
+ }
54
+ }, k = D.encode(JSON.stringify(O));
55
+ function A() {
56
+ return async (e, n) => {
57
+ if (e.endsWith("world.json")) return M(k, n);
58
+ let r = t(e), i = e.slice(e.lastIndexOf(".") + 1);
59
+ if (!r || i !== "idx" && i !== "pack" || !F(r) || r.hash !== N(r, i)) throw new c(`no file ${e}`);
60
+ return i === "idx" ? M(await V(r), n) : H(r, n, e);
61
+ };
62
+ }
63
+ function j(e, t) {
64
+ let n = w;
65
+ for (let [r, i, a, o, s] of C) n += r * Math.sin(i * e + a) * Math.sin(o * t + s);
66
+ return n;
67
+ }
68
+ function M(e, t) {
69
+ return t ? e.slice(t[0], t[1]) : e.slice();
70
+ }
71
+ function N(e, t) {
72
+ return a(D.encode(`${e.level}/${e.e}/${e.n}.${t}`));
73
+ }
74
+ function P(e, t, n) {
75
+ let { e: r, n: i } = O.extent;
76
+ return e < r[1] && e + n > r[0] && t < i[1] && t + n > i[0];
77
+ }
78
+ function F({ level: e, e: t, n }) {
79
+ let r = 250 * 2 ** e;
80
+ return e <= g && t % r === 0 && n % r === 0 && P(t, n, r);
81
+ }
82
+ function I(e) {
83
+ return e === 0 ? [1, 0] : e === g ? [
84
+ 16,
85
+ 15,
86
+ 14,
87
+ 13
88
+ ] : [e + 1];
89
+ }
90
+ function L(e) {
91
+ let t = 0;
92
+ for (let n = 0; n < 8; n++) t |= (e >> 2 * n & 1) << n;
93
+ return t;
94
+ }
95
+ function R(e) {
96
+ let t = [];
97
+ for (let n of I(e.level)) {
98
+ let r = s * 2 ** n, i = 250 * 2 ** e.level / r;
99
+ for (let a = 0; a < i * i; a++) {
100
+ let i = L(a), o = L(a >> 1);
101
+ P(e.e + i * r, e.n + o * r, r) && t.push({
102
+ g: n,
103
+ i,
104
+ j: o
105
+ });
106
+ }
107
+ }
108
+ return t;
109
+ }
110
+ function z(e, t) {
111
+ let n = e.level - t, r = 250 * 2 ** n, i = [];
112
+ for (let a = 0; n >= 0 && a < 2 ** t; a++) for (let o = 0; o < 2 ** t; o++) {
113
+ let t = {
114
+ level: n,
115
+ e: e.e + o * r,
116
+ n: e.n + a * r
117
+ };
118
+ P(t.e, t.n, r) && i.push({
119
+ column: o,
120
+ row: a,
121
+ unit: t
122
+ });
123
+ }
124
+ return i;
125
+ }
126
+ function B(e, { g: t, i: n, j: r }, i) {
127
+ let a = s * 2 ** t, o = a / l, c = 3 * y * o, d = 1.17 * o, f = j(e.e + (n + .5) * a, e.n + (r + .5) * a), p = T * a / 2, m = Float32Array.of(n * a - c, r * a - c, Math.max(0, f - p) - d, (n + 1) * a + c, (r + 1) * a + c, Math.min(60, f + p) + d), g = u / 4;
128
+ return {
129
+ g: t,
130
+ i: n,
131
+ j: r,
132
+ count: u,
133
+ quadrants: [
134
+ g,
135
+ 2 * g,
136
+ 3 * g
137
+ ],
138
+ box: m,
139
+ offset: i,
140
+ length: h
141
+ };
142
+ }
143
+ function V(e) {
144
+ let t = R(e), n = [];
145
+ for (let { column: t, row: r, unit: i } of z(e, 1)) n.push({
146
+ quadrant: t + 2 * r,
147
+ idx: N(i, "idx")
148
+ });
149
+ let r = [];
150
+ for (let t of [2, 3]) for (let { column: n, row: i, unit: a } of z(e, t)) r.push({
151
+ depth: t,
152
+ column: n,
153
+ row: i,
154
+ idx: N(a, "idx")
155
+ });
156
+ return i({
157
+ level: e.level,
158
+ e: e.e,
159
+ n: e.n,
160
+ pack: N(e, "pack"),
161
+ packSize: t.length * (h + 52) + 16,
162
+ col: null,
163
+ rows: t.map((t, n) => B(e, t, n * h)),
164
+ children: n,
165
+ descendants: r
166
+ });
167
+ }
168
+ function H(e, t, n) {
169
+ let r = R(e);
170
+ if (!t || t[0] % h !== 0 || t[1] % h !== 0 || t[0] >= t[1] || t[1] > r.length * h) throw Error(`${n}: the synthetic world serves whole pages only`);
171
+ let i = new Uint8Array(t[1] - t[0]);
172
+ for (let n = 0; n < i.length; n += h) U(G(e, r[(t[0] + n) / h]), i, n);
173
+ return i;
174
+ }
175
+ function U(e, t, n) {
176
+ let r = n;
177
+ for (let n = 0; n < e.length; n += p) {
178
+ let i = Math.min(p, e.length - n);
179
+ t[r] = +(n + i === e.length), t[r + 1] = i & 255, t[r + 2] = i >> 8, t[r + 3] = ~i & 255, t[r + 4] = ~i >> 8 & 255, t.set(e.subarray(n, n + i), r + m), r += m + i;
180
+ }
181
+ }
182
+ var W = (e) => n(parseInt(a(D.encode(e)).slice(8), 16));
183
+ function G(t, { g: n, i, j: a }) {
184
+ let o = u, c = s * 2 ** n / l, f = W(`${t.level}/${t.e}/${t.n}/${n}/${i}/${a}`), p = new Float64Array(3 * o), m = new Float32Array(4 * o), h = new Float32Array(3 * o), g = new Float32Array(o), y = new Float32Array(3 * o), S = new Float32Array(9 * o);
185
+ for (let n = 0; n < o; n++) {
186
+ let r = (i * l + n % l + .5 + _ * (2 * f() - 1)) * c, o = (a * l + Math.floor(n / l) + .5 + _ * (2 * f() - 1)) * c, s = j(t.e + r, t.n + o);
187
+ p[3 * n] = r, p[3 * n + 1] = o, p[3 * n + 2] = s;
188
+ let u = Math.PI * f(), C = x / 2 * (2 * f() - 1);
189
+ m[4 * n] = Math.cos(u) * Math.cos(C), m[4 * n + 1] = Math.cos(u) * Math.sin(C), m[4 * n + 2] = Math.sin(u) * Math.sin(C), m[4 * n + 3] = Math.sin(u) * Math.cos(C);
190
+ for (let e = 0; e < 2; e++) h[3 * n + e] = Math.log(c * (v + .6 * f()));
191
+ h[3 * n + 2] = Math.log(c * b * (.5 + .5 * f())), g[n] = .35 + .65 * f();
192
+ let w = s / 60, T = .5 + .5 * Math.sin((t.e + r) / 410) * Math.sin((t.n + o) / 330);
193
+ y[3 * n] = (.32 + .2 * w + .1 * T - .5) / e, y[3 * n + 1] = (.42 + .15 * T - .1 * w - .5) / e, y[3 * n + 2] = (.25 + .1 * w + .04 * f() - .5) / e;
194
+ let D = n % d;
195
+ S.set(E.subarray(9 * D, 9 * (D + 1)), 9 * n);
196
+ }
197
+ return r({
198
+ count: o,
199
+ position: p,
200
+ rotation: m,
201
+ scale: h,
202
+ alpha: g,
203
+ dc: y,
204
+ sh: S
205
+ }, {
206
+ g: n,
207
+ i,
208
+ j: a
209
+ }).payload;
210
+ }
211
+ //#endregion
212
+ export { A as synthetic };
@@ -1 +1 @@
1
- export { t as exportPly, r as info, o as openWorld, n as plySplat, i as probe, a as validate, s as walk } from "../tools-NykPVccD.js";
1
+ export { t as exportPly, r as info, o as openWorld, n as plySplat, i as probe, a as validate, s as walk } from "../tools-DnfuHeoO.js";
@@ -0,0 +1,227 @@
1
+ import { S as e, _ as t, b as n, f as r, g as i, h as a, l as o, m as s, o as c, p as l, s as u, u as d, y as f } from "./format-CbtEy9NS.js";
2
+ import { t as p } from "./ports-DZRKjdYD.js";
3
+ //#region src/tools/walk.ts
4
+ var m = 16;
5
+ async function h(e, t) {
6
+ let n = await e(t, null);
7
+ return l(JSON.parse(new TextDecoder().decode(n)));
8
+ }
9
+ async function* g(e, t, n, a) {
10
+ let o = r(t), c = async (t) => {
11
+ try {
12
+ let n = await e(o + t, null);
13
+ return {
14
+ path: t,
15
+ idx: await i(n),
16
+ bytes: n
17
+ };
18
+ } catch (e) {
19
+ if (!a) throw e;
20
+ return a(t, e), null;
21
+ }
22
+ }, l = n.roots.map((e) => e.idx);
23
+ for (; l.length > 0;) {
24
+ let e = [];
25
+ for (let t = 0; t < l.length; t += m) for (let n of await Promise.all(l.slice(t, t + m).map(c))) if (n) {
26
+ yield n;
27
+ for (let { key: t, hash: r } of s(n.idx).slice(0, n.idx.children.length)) e.push(f(t, r, "idx"));
28
+ }
29
+ l = e;
30
+ }
31
+ }
32
+ //#endregion
33
+ //#region src/tools/validate.ts
34
+ var _ = (e) => e instanceof Error ? e.message : String(e), v = (e) => e instanceof p ? "is missing" : _(e);
35
+ async function y(e, t, n = {}) {
36
+ let i = {
37
+ units: 0,
38
+ files: 0,
39
+ bytes: 0,
40
+ faults: []
41
+ }, a = (e, t) => i.faults.push({
42
+ path: e,
43
+ fault: v(t)
44
+ }), o;
45
+ try {
46
+ o = await h(e, t);
47
+ } catch (e) {
48
+ return a("world.json", e), i;
49
+ }
50
+ let s = r(t), c = async (t) => {
51
+ await b(e, s, t, n.deep ?? !1, i), n.progress?.(i);
52
+ }, l = n.deep ? 2 : 8, u = !n.server, d = [];
53
+ for await (let n of g(e, t, o, a)) {
54
+ if (!u) {
55
+ u = !0;
56
+ let e = f(n.idx, n.idx.pack, "pack");
57
+ for (let t of await S(s + e)) i.faults.push({
58
+ path: e,
59
+ fault: t
60
+ });
61
+ }
62
+ d.push(c(n)), !(d.length < l) && (await Promise.all(d), d = []);
63
+ }
64
+ return await Promise.all(d), i;
65
+ }
66
+ async function b(e, n, r, i, o) {
67
+ let { idx: s, path: l, bytes: u } = r, p = (e, t) => o.faults.push({
68
+ path: e,
69
+ fault: t
70
+ });
71
+ o.units++, o.files++, o.bytes += u.length;
72
+ let m = t(l);
73
+ if ((m.level !== s.level || m.e !== s.e || m.n !== s.n) && p(l, `holds unit ${s.level}/${s.e}/${s.n}`), i && c(u) !== m.hash && p(l, "does not have the hash in its name"), s.col) {
74
+ let t = f(s, s.col, "col");
75
+ try {
76
+ let r = await e(n + t, null);
77
+ o.files++, o.bytes += r.length, await d(r), i && c(r) !== s.col && p(t, "does not have the hash in its name");
78
+ } catch (e) {
79
+ p(t, v(e));
80
+ }
81
+ }
82
+ let h = f(s, s.pack, "pack");
83
+ try {
84
+ o.files++, o.bytes += s.packSize;
85
+ let t = i ? await e(n + h, null) : null;
86
+ if (t && t.length !== s.packSize) throw Error(`holds ${t.length} bytes, its .idx gives ${s.packSize}`);
87
+ t && c(t) !== s.pack && p(h, "does not have the hash in its name");
88
+ let r = async (r, i) => {
89
+ let a = t ? t.subarray(r, i) : await e(n + h, [r, i]);
90
+ if (a.length !== i - r) throw Error(`gives ${a.length} bytes for ${r}-${i}`);
91
+ return a;
92
+ }, l = await a(r, s.packSize), u = new Map(l.map((e) => [`${e.g}/${e.i}/${e.j}`, e]));
93
+ for (let e of s.rows) {
94
+ let n = `${e.g}/${e.i}/${e.j}`, i = `page ${n}`, a = u.get(n);
95
+ if (!a || a.offset !== e.offset || a.length !== e.length) p(h, `does not list ${i} as its .idx does`);
96
+ else if (t) {
97
+ let t = await x(await r(e.offset, e.offset + e.length), e);
98
+ t && p(h, `${i} ${t}`);
99
+ }
100
+ }
101
+ } catch (e) {
102
+ p(h, v(e));
103
+ }
104
+ }
105
+ async function x(e, t) {
106
+ let r;
107
+ try {
108
+ r = await n(e);
109
+ } catch {
110
+ return "is not a valid deflate stream";
111
+ }
112
+ try {
113
+ let e = u(r, null);
114
+ if (e.count !== t.count) return `holds ${e.count} splats, its row ${t.count}`;
115
+ if (e.quadrants.some((e, n) => e !== t.quadrants[n])) return "does not start its quadrants where its row does";
116
+ } catch (e) {
117
+ return `does not decode: ${_(e)}`;
118
+ }
119
+ }
120
+ async function S(e) {
121
+ let t = "https://narcissus.example", n = [], r;
122
+ try {
123
+ r = await fetch(e, { headers: {
124
+ Range: "bytes=0-0",
125
+ Origin: t
126
+ } }), await r.arrayBuffer();
127
+ } catch (e) {
128
+ return [`the server did not answer: ${_(e)}`];
129
+ }
130
+ r.status !== 206 && n.push(`the server answers a range request with status ${r.status}, not 206`);
131
+ let i = r.headers.get("access-control-allow-origin");
132
+ return i !== "*" && i !== t && n.push("the server sends no access-control-allow-origin for another origin"), n;
133
+ }
134
+ //#endregion
135
+ //#region src/tools/info.ts
136
+ async function C(e, t) {
137
+ let n = await h(e, t), r = {
138
+ world: n,
139
+ units: [],
140
+ levels: [],
141
+ bytes: 0
142
+ };
143
+ for await (let { idx: i } of g(e, t, n)) {
144
+ r.units[i.level] = (r.units[i.level] ?? 0) + 1, r.bytes += i.packSize;
145
+ for (let e of i.rows) {
146
+ let t = r.levels[e.g] ??= {
147
+ pages: 0,
148
+ splats: 0
149
+ };
150
+ t.pages++, t.splats += e.count;
151
+ }
152
+ }
153
+ return r.units = Array.from(r.units, (e) => e ?? 0), r.levels = Array.from(r.levels, (e) => e ?? {
154
+ pages: 0,
155
+ splats: 0
156
+ }), r;
157
+ }
158
+ //#endregion
159
+ //#region src/tools/ply.ts
160
+ var w = [
161
+ "x",
162
+ "y",
163
+ "z",
164
+ ...[
165
+ 0,
166
+ 1,
167
+ 2
168
+ ].map((e) => `f_dc_${e}`),
169
+ ...Array.from({ length: 9 }, (e, t) => `f_rest_${t}`),
170
+ "opacity",
171
+ ...[
172
+ 0,
173
+ 1,
174
+ 2
175
+ ].map((e) => `scale_${e}`),
176
+ ...[
177
+ 0,
178
+ 1,
179
+ 2,
180
+ 3
181
+ ].map((e) => `rot_${e}`)
182
+ ], T = Math.SQRT1_2, E = [.5 / 255, 254.5 / 255];
183
+ function D(t, n, r) {
184
+ let [i, a, o, s] = t.rotation, c = Math.min(E[1], Math.max(E[0], t.alpha));
185
+ r[0] = t.position[0] - n[0], r[1] = -t.position[2], r[2] = t.position[1] - n[1];
186
+ for (let n = 0; n < 3; n++) r[3 + n] = (t.colour[n] - .5) / e, r[6 + 3 * n] = t.sh[3 * n + 1], r[7 + 3 * n] = -t.sh[3 * n], r[8 + 3 * n] = t.sh[3 * n + 2], r[16 + n] = Math.log(t.scale[n]);
187
+ r[15] = Math.log(c / (1 - c)), r[19] = T * (i - a), r[20] = T * (i + a), r[21] = T * (o - s), r[22] = T * (o + s);
188
+ }
189
+ async function* O(e, t, i = {}) {
190
+ let { level: a = 0, box: s } = i, c = await h(e, t), l = r(t), p = (e, { box: t }) => !s || e.e + t[0] <= s[2] && e.e + t[3] >= s[0] && e.n + t[1] <= s[3] && e.n + t[4] >= s[1], m = [], _ = 0;
191
+ for await (let { idx: n } of g(e, t, c)) {
192
+ let e = n.rows.filter((e) => e.g === a && p(n, e));
193
+ if (e.length !== 0) {
194
+ m.push({
195
+ idx: n,
196
+ rows: e
197
+ });
198
+ for (let t of e) _ += t.count;
199
+ }
200
+ }
201
+ let v = [Math.floor(s ? s[0] : c.extent.e[0]), Math.floor(s ? s[1] : c.extent.n[0])];
202
+ yield new TextEncoder().encode([
203
+ "ply",
204
+ "format binary_little_endian 1.0",
205
+ `comment level ${a} of a guldmund tree in ${c.crs}, heights in ${c.height}`,
206
+ "comment x east, y down, z north, in metres",
207
+ `comment origin ${v[0]} ${v[1]}: add it to x and z for easting and northing`,
208
+ `element vertex ${_}`,
209
+ ...w.map((e) => `property float ${e}`),
210
+ "end_header",
211
+ ""
212
+ ].join("\n"));
213
+ let y = w.length;
214
+ for (let { idx: t, rows: r } of m) {
215
+ let i = l + f(t, t.pack, "pack"), a = t.col ? await d(await e(l + f(t, t.col, "col"), null)) : null;
216
+ for (let s of r) {
217
+ let r = await e(i, [s.offset, s.offset + s.length]), c = u(await n(r), a), l = new Float32Array(c.count * y);
218
+ for (let e = 0; e < c.count; e++) {
219
+ let n = o(c, e);
220
+ n.position[0] += t.e, n.position[1] += t.n, D(n, v, l.subarray(e * y, (e + 1) * y));
221
+ }
222
+ yield new Uint8Array(l.buffer);
223
+ }
224
+ }
225
+ }
226
+ //#endregion
227
+ export { y as a, S as i, D as n, h as o, C as r, g as s, O as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalyptos/narcissus",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "A WebGPU engine and tools for Guldmund Trees, streamed gaussian-splat scenes",
5
5
  "license": "BSD-3-Clause",
6
6
  "repository": {