layershift 0.6.0 → 0.7.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/README.md +8 -8
- package/dist/components/layershift.js +11 -11
- package/dist/npm/layershift.es.js +625 -576
- package/dist/types/components/layershift/global.d.ts +4 -4
- package/dist/types/components/layershift/index.d.ts +1 -1
- package/dist/types/components/layershift/layershift-element.d.ts +13 -1
- package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
- package/dist/types/components/layershift/lifecycle.d.ts +1 -1
- package/dist/types/components/layershift/portal-element.d.ts +1 -1
- package/dist/types/components/layershift/portal-element.d.ts.map +1 -1
- package/dist/types/components/layershift/types.d.ts +8 -8
- package/dist/types/components/layershift/types.d.ts.map +1 -1
- package/dist/types/depth/precomputed-depth.d.ts +1 -1
- package/dist/types/depth/precomputed-depth.d.ts.map +1 -1
- package/dist/types/renderers/renderer-base.d.ts +11 -0
- package/dist/types/renderers/renderer-base.d.ts.map +1 -1
- package/dist/types/shared/filter-config.d.ts +2 -2
- package/dist/types/shared/filter-config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -10,57 +10,57 @@ class Vt {
|
|
|
10
10
|
lastNextFrameIndex = -1;
|
|
11
11
|
lastLerpFactor = -1;
|
|
12
12
|
sample(t) {
|
|
13
|
-
const e =
|
|
13
|
+
const e = ie(t * this.depthData.fps, 0, this.depthData.frameCount - 1), i = Math.floor(e), n = Math.min(i + 1, this.depthData.frameCount - 1), r = e - i, o = i !== this.lastFrameIndex || n !== this.lastNextFrameIndex, l = Math.abs(r - this.lastLerpFactor) > 1e-3;
|
|
14
14
|
if (!o && !l)
|
|
15
15
|
return this.uint8Output;
|
|
16
|
-
this.lastFrameIndex =
|
|
17
|
-
const a = 1 - r, h = this.depthData.frames[
|
|
16
|
+
this.lastFrameIndex = i, this.lastNextFrameIndex = n, this.lastLerpFactor = r;
|
|
17
|
+
const a = 1 - r, h = this.depthData.frames[i], c = this.depthData.frames[n];
|
|
18
18
|
for (let f = 0; f < this.uint8Output.length; f += 1)
|
|
19
19
|
this.uint8Output[f] = h[f] * a + c[f] * r + 0.5 | 0;
|
|
20
20
|
return this.uint8Output;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
async function kt(s, t = 512, e = 512,
|
|
23
|
+
async function kt(s, t = 512, e = 512, i = 5, n) {
|
|
24
24
|
const r = await te(s);
|
|
25
|
-
return ee(r, t, e,
|
|
25
|
+
return ee(r, t, e, i);
|
|
26
26
|
}
|
|
27
27
|
async function te(s, t) {
|
|
28
28
|
const e = await fetch(s);
|
|
29
29
|
if (!e.ok)
|
|
30
30
|
throw new Error(`Failed to fetch depth data (${e.status} ${e.statusText}).`);
|
|
31
31
|
e.headers.get("content-length");
|
|
32
|
-
const
|
|
33
|
-
if (!
|
|
32
|
+
const i = e.body;
|
|
33
|
+
if (!i)
|
|
34
34
|
return new Uint8Array(await e.arrayBuffer());
|
|
35
|
-
const
|
|
35
|
+
const n = [];
|
|
36
36
|
let r = 0;
|
|
37
|
-
const o =
|
|
37
|
+
const o = i.getReader();
|
|
38
38
|
for (; ; ) {
|
|
39
39
|
const { done: h, value: c } = await o.read();
|
|
40
40
|
if (h)
|
|
41
41
|
break;
|
|
42
|
-
c && (
|
|
42
|
+
c && (n.push(c), r += c.byteLength);
|
|
43
43
|
}
|
|
44
44
|
const l = new Uint8Array(r);
|
|
45
45
|
let a = 0;
|
|
46
|
-
for (const h of
|
|
46
|
+
for (const h of n)
|
|
47
47
|
l.set(h, a), a += h.byteLength;
|
|
48
48
|
return l;
|
|
49
49
|
}
|
|
50
|
-
function ee(s, t, e,
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
50
|
+
function ee(s, t, e, i) {
|
|
51
|
+
const n = t * e;
|
|
52
|
+
if (n === 0)
|
|
53
53
|
throw new Error("Depth frame dimensions must be non-zero.");
|
|
54
|
-
if (s.byteLength %
|
|
54
|
+
if (s.byteLength % n !== 0)
|
|
55
55
|
throw new Error(
|
|
56
|
-
`Depth data byte length (${s.byteLength}) is not evenly divisible by frame size (${
|
|
56
|
+
`Depth data byte length (${s.byteLength}) is not evenly divisible by frame size (${n} = ${t}×${e}).`
|
|
57
57
|
);
|
|
58
|
-
const r = s.byteLength /
|
|
58
|
+
const r = s.byteLength / n, o = new Array(r);
|
|
59
59
|
for (let l = 0; l < r; l += 1) {
|
|
60
|
-
const a = l *
|
|
61
|
-
o[l] = s.subarray(a, a +
|
|
60
|
+
const a = l * n;
|
|
61
|
+
o[l] = s.subarray(a, a + n);
|
|
62
62
|
}
|
|
63
|
-
return { width: t, height: e, fps:
|
|
63
|
+
return { width: t, height: e, fps: i, frameCount: r, frames: o };
|
|
64
64
|
}
|
|
65
65
|
function X(s, t) {
|
|
66
66
|
const e = new Uint8Array(s * t);
|
|
@@ -72,10 +72,10 @@ function X(s, t) {
|
|
|
72
72
|
frames: [e]
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
function
|
|
75
|
+
function ie(s, t, e) {
|
|
76
76
|
return Math.min(e, Math.max(t, s));
|
|
77
77
|
}
|
|
78
|
-
const
|
|
78
|
+
const ne = {
|
|
79
79
|
parallaxStrength: 0.05,
|
|
80
80
|
contrastLow: 0.05,
|
|
81
81
|
contrastHigh: 0.95,
|
|
@@ -86,37 +86,37 @@ const ie = {
|
|
|
86
86
|
overscanPadding: 0.08
|
|
87
87
|
};
|
|
88
88
|
function re(s, t, e) {
|
|
89
|
-
const
|
|
89
|
+
const i = new Float32Array(256);
|
|
90
90
|
if (s.length === 0 || t <= 0 || e <= 0)
|
|
91
|
-
return Pt(
|
|
92
|
-
const
|
|
91
|
+
return Pt(i);
|
|
92
|
+
const n = oe(s.length), r = t * e;
|
|
93
93
|
let o = 0;
|
|
94
94
|
const l = new Uint32Array(256);
|
|
95
|
-
for (const m of
|
|
95
|
+
for (const m of n) {
|
|
96
96
|
const T = s[m], w = Math.min(T.length, r);
|
|
97
97
|
for (let A = 0; A < w; A += 1)
|
|
98
98
|
l[T[A]] += 1;
|
|
99
99
|
o += w;
|
|
100
100
|
}
|
|
101
101
|
if (o === 0)
|
|
102
|
-
return Pt(
|
|
102
|
+
return Pt(i);
|
|
103
103
|
const a = 1 / o;
|
|
104
104
|
for (let m = 0; m < 256; m += 1)
|
|
105
|
-
|
|
105
|
+
i[m] = l[m] * a;
|
|
106
106
|
const h = new Float32Array(256);
|
|
107
|
-
h[0] =
|
|
107
|
+
h[0] = i[0];
|
|
108
108
|
for (let m = 1; m < 256; m += 1)
|
|
109
|
-
h[m] = h[m - 1] +
|
|
110
|
-
const c =
|
|
109
|
+
h[m] = h[m - 1] + i[m];
|
|
110
|
+
const c = it(h, 0.05), f = it(h, 0.25), u = it(h, 0.5), x = it(h, 0.75), p = it(h, 0.95);
|
|
111
111
|
let d = 0;
|
|
112
112
|
for (let m = 0; m < 256; m += 1)
|
|
113
|
-
d += m / 255 *
|
|
113
|
+
d += m / 255 * i[m];
|
|
114
114
|
let y = 0;
|
|
115
115
|
for (let m = 0; m < 256; m += 1) {
|
|
116
116
|
const T = m / 255 - d;
|
|
117
|
-
y +=
|
|
117
|
+
y += i[m] * T * T;
|
|
118
118
|
}
|
|
119
|
-
const b = Math.sqrt(y), E = p - c, g = x - f, v = ae(
|
|
119
|
+
const b = Math.sqrt(y), E = p - c, g = x - f, v = ae(i);
|
|
120
120
|
return {
|
|
121
121
|
mean: d,
|
|
122
122
|
stdDev: b,
|
|
@@ -128,20 +128,20 @@ function re(s, t, e) {
|
|
|
128
128
|
effectiveRange: E,
|
|
129
129
|
iqr: g,
|
|
130
130
|
bimodality: v,
|
|
131
|
-
histogram:
|
|
131
|
+
histogram: i
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
function se(s) {
|
|
135
135
|
if (s.effectiveRange < 0.05 || s.stdDev < 0.02)
|
|
136
|
-
return { ...
|
|
137
|
-
const t = s.effectiveRange - 0.5, e = s.bimodality - 0.4,
|
|
136
|
+
return { ...ne };
|
|
137
|
+
const t = s.effectiveRange - 0.5, e = s.bimodality - 0.4, i = H(
|
|
138
138
|
0.05 - t * 0.03 + e * 0.01,
|
|
139
139
|
0.035,
|
|
140
140
|
0.065
|
|
141
|
-
),
|
|
141
|
+
), n = H(s.p5 - 0.03, 0, 0.25), r = H(s.p95 + 0.03, 0.75, 1), o = H((i - 0.03) / 0.05, 0, 1), l = H(0.6 - o * 0.25, 0.35, 0.6), a = H(0.6 - t * 0.2, 0.5, 0.7), h = H(0.4 + t * 0.2, 0.25, 0.5), c = 16, f = H(i + 0.03, 0.06, 0.1);
|
|
142
142
|
return {
|
|
143
|
-
parallaxStrength:
|
|
144
|
-
contrastLow:
|
|
143
|
+
parallaxStrength: i,
|
|
144
|
+
contrastLow: n,
|
|
145
145
|
contrastHigh: r,
|
|
146
146
|
verticalReduction: l,
|
|
147
147
|
dofStart: a,
|
|
@@ -159,12 +159,12 @@ function oe(s) {
|
|
|
159
159
|
Math.floor(s / 2),
|
|
160
160
|
Math.floor(3 * s / 4),
|
|
161
161
|
t
|
|
162
|
-
],
|
|
162
|
+
], i = /* @__PURE__ */ new Set(), n = [];
|
|
163
163
|
for (const r of e)
|
|
164
|
-
|
|
165
|
-
return
|
|
164
|
+
i.has(r) || (i.add(r), n.push(r));
|
|
165
|
+
return n;
|
|
166
166
|
}
|
|
167
|
-
function
|
|
167
|
+
function it(s, t) {
|
|
168
168
|
for (let e = 0; e < 256; e += 1)
|
|
169
169
|
if (s[e] >= t)
|
|
170
170
|
return e / 255;
|
|
@@ -182,14 +182,14 @@ function ae(s) {
|
|
|
182
182
|
for (let u = 0; u < 256; u += 1)
|
|
183
183
|
e += t[u];
|
|
184
184
|
e /= 256;
|
|
185
|
-
const
|
|
185
|
+
const i = e * 2, n = 25, r = [];
|
|
186
186
|
for (let u = 1; u < 255; u += 1)
|
|
187
|
-
t[u] > t[u - 1] && t[u] > t[u + 1] && t[u] >=
|
|
188
|
-
if (t[0] > t[1] && t[0] >=
|
|
187
|
+
t[u] > t[u - 1] && t[u] > t[u + 1] && t[u] >= i && r.push({ bin: u, height: t[u] });
|
|
188
|
+
if (t[0] > t[1] && t[0] >= i && r.push({ bin: 0, height: t[0] }), t[255] > t[254] && t[255] >= i && r.push({ bin: 255, height: t[255] }), r.sort((u, x) => x.height - u.height), r.length < 2) return 0;
|
|
189
189
|
const o = r[0];
|
|
190
190
|
let l = null;
|
|
191
191
|
for (let u = 1; u < r.length; u += 1)
|
|
192
|
-
if (Math.abs(r[u].bin - o.bin) >=
|
|
192
|
+
if (Math.abs(r[u].bin - o.bin) >= n) {
|
|
193
193
|
l = r[u];
|
|
194
194
|
break;
|
|
195
195
|
}
|
|
@@ -220,30 +220,30 @@ function H(s, t, e) {
|
|
|
220
220
|
return Math.min(e, Math.max(t, s));
|
|
221
221
|
}
|
|
222
222
|
function G(s, t, e) {
|
|
223
|
-
const
|
|
224
|
-
if (!
|
|
225
|
-
if (s.shaderSource(
|
|
226
|
-
const
|
|
227
|
-
throw s.deleteShader(
|
|
228
|
-
${
|
|
223
|
+
const i = s.createShader(t);
|
|
224
|
+
if (!i) throw new Error("Failed to create shader.");
|
|
225
|
+
if (s.shaderSource(i, e), s.compileShader(i), !s.getShaderParameter(i, s.COMPILE_STATUS)) {
|
|
226
|
+
const n = s.getShaderInfoLog(i) ?? "";
|
|
227
|
+
throw s.deleteShader(i), new Error(`Shader compilation failed:
|
|
228
|
+
${n}`);
|
|
229
229
|
}
|
|
230
|
-
return
|
|
230
|
+
return i;
|
|
231
231
|
}
|
|
232
232
|
function mt(s, t, e) {
|
|
233
|
-
const
|
|
234
|
-
if (!
|
|
235
|
-
if (s.attachShader(
|
|
236
|
-
const
|
|
237
|
-
throw s.deleteProgram(
|
|
238
|
-
${
|
|
233
|
+
const i = s.createProgram();
|
|
234
|
+
if (!i) throw new Error("Failed to create program.");
|
|
235
|
+
if (s.attachShader(i, t), s.attachShader(i, e), s.linkProgram(i), !s.getProgramParameter(i, s.LINK_STATUS)) {
|
|
236
|
+
const n = s.getProgramInfoLog(i) ?? "";
|
|
237
|
+
throw s.deleteProgram(i), new Error(`Program linking failed:
|
|
238
|
+
${n}`);
|
|
239
239
|
}
|
|
240
|
-
return s.detachShader(
|
|
240
|
+
return s.detachShader(i, t), s.detachShader(i, e), s.deleteShader(t), s.deleteShader(e), i;
|
|
241
241
|
}
|
|
242
242
|
function pt(s, t, e) {
|
|
243
|
-
const
|
|
244
|
-
for (const
|
|
245
|
-
n
|
|
246
|
-
return
|
|
243
|
+
const i = {};
|
|
244
|
+
for (const n of e)
|
|
245
|
+
i[n] = s.getUniformLocation(t, n);
|
|
246
|
+
return i;
|
|
247
247
|
}
|
|
248
248
|
const le = new Float32Array([
|
|
249
249
|
-1,
|
|
@@ -259,10 +259,10 @@ function Ot(s, t) {
|
|
|
259
259
|
const e = s.createVertexArray();
|
|
260
260
|
if (!e) throw new Error("Failed to create VAO.");
|
|
261
261
|
s.bindVertexArray(e);
|
|
262
|
-
const
|
|
263
|
-
s.bindBuffer(s.ARRAY_BUFFER,
|
|
264
|
-
const
|
|
265
|
-
return s.enableVertexAttribArray(
|
|
262
|
+
const i = s.createBuffer();
|
|
263
|
+
s.bindBuffer(s.ARRAY_BUFFER, i), s.bufferData(s.ARRAY_BUFFER, le, s.STATIC_DRAW);
|
|
264
|
+
const n = s.getAttribLocation(t, "aPosition");
|
|
265
|
+
return s.enableVertexAttribArray(n), s.vertexAttribPointer(n, 2, s.FLOAT, !1, 0, 0), s.bindVertexArray(null), e;
|
|
266
266
|
}
|
|
267
267
|
class Ht {
|
|
268
268
|
slots = /* @__PURE__ */ new Map();
|
|
@@ -300,8 +300,8 @@ class Ht {
|
|
|
300
300
|
return this.slots.size;
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
|
-
function O(s, t, e,
|
|
304
|
-
const r = G(s, s.VERTEX_SHADER, e), o = G(s, s.FRAGMENT_SHADER,
|
|
303
|
+
function O(s, t, e, i, n) {
|
|
304
|
+
const r = G(s, s.VERTEX_SHADER, e), o = G(s, s.FRAGMENT_SHADER, i), l = mt(s, r, o), a = pt(s, l, n);
|
|
305
305
|
return {
|
|
306
306
|
name: t,
|
|
307
307
|
program: l,
|
|
@@ -311,8 +311,8 @@ function O(s, t, e, n, i) {
|
|
|
311
311
|
}
|
|
312
312
|
};
|
|
313
313
|
}
|
|
314
|
-
function Dt(s, t, e,
|
|
315
|
-
const o = G(s, s.VERTEX_SHADER, e), l = G(s, s.FRAGMENT_SHADER,
|
|
314
|
+
function Dt(s, t, e, i, n, r) {
|
|
315
|
+
const o = G(s, s.VERTEX_SHADER, e), l = G(s, s.FRAGMENT_SHADER, i), a = mt(s, o, l), h = pt(s, a, n), c = {
|
|
316
316
|
texture: null,
|
|
317
317
|
unit: r.textureUnit,
|
|
318
318
|
attachment: s.COLOR_ATTACHMENT0
|
|
@@ -376,11 +376,11 @@ function ce(s) {
|
|
|
376
376
|
let t = "unknown";
|
|
377
377
|
const e = s.getExtension("WEBGL_debug_renderer_info");
|
|
378
378
|
e && (t = s.getParameter(e.UNMASKED_RENDERER_WEBGL) || "unknown");
|
|
379
|
-
const
|
|
379
|
+
const i = s.getParameter(s.MAX_TEXTURE_SIZE), n = typeof navigator < "u" && navigator.hardwareConcurrency || 0, r = typeof navigator < "u" && navigator.deviceMemory || 0, o = typeof window < "u" && window.devicePixelRatio || 1, l = typeof screen < "u" ? (screen.width || 0) * (screen.height || 0) : 0, a = typeof navigator < "u" && ("ontouchstart" in window || navigator.maxTouchPoints > 0), h = l > 0 && l < 1920 * 1080;
|
|
380
380
|
return {
|
|
381
381
|
gpuRenderer: t,
|
|
382
|
-
maxTextureSize:
|
|
383
|
-
hardwareConcurrency:
|
|
382
|
+
maxTextureSize: i,
|
|
383
|
+
hardwareConcurrency: n,
|
|
384
384
|
deviceMemory: r,
|
|
385
385
|
devicePixelRatio: o,
|
|
386
386
|
screenPixels: l,
|
|
@@ -414,8 +414,8 @@ const he = [
|
|
|
414
414
|
];
|
|
415
415
|
function de(s) {
|
|
416
416
|
let t = 0;
|
|
417
|
-
const e = s.gpuRenderer.toLowerCase(),
|
|
418
|
-
return
|
|
417
|
+
const e = s.gpuRenderer.toLowerCase(), i = he.some((r) => e.includes(r)), n = fe.some((r) => e.includes(r));
|
|
418
|
+
return i && (t -= 30), n && (t += 20), s.maxTextureSize >= 16384 ? t += 10 : s.maxTextureSize >= 8192 ? t += 5 : s.maxTextureSize <= 4096 && (t -= 15), s.hardwareConcurrency >= 8 ? t += 5 : s.hardwareConcurrency >= 4 ? t += 0 : s.hardwareConcurrency > 0 && s.hardwareConcurrency < 4 && (t -= 10), s.deviceMemory >= 8 ? t += 5 : s.deviceMemory >= 4 ? t += 0 : s.deviceMemory > 0 && s.deviceMemory < 4 && (t -= 15), s.isMobile && (t -= 10), t >= 0 ? "high" : t >= -25 ? "medium" : "low";
|
|
419
419
|
}
|
|
420
420
|
function Xt(s, t) {
|
|
421
421
|
const e = t && t !== "auto" ? t : de(ce(s));
|
|
@@ -482,12 +482,31 @@ class gt {
|
|
|
482
482
|
*
|
|
483
483
|
* For static sources (image) or when RVFC is unavailable, RAF-only.
|
|
484
484
|
*/
|
|
485
|
-
start(t, e,
|
|
486
|
-
this.stop(), this.mediaSource = t, this.readDepth = e, this.readInput =
|
|
485
|
+
start(t, e, i, n) {
|
|
486
|
+
this.stop(), this.mediaSource = t, this.readDepth = e, this.readInput = i, this.onVideoFrame = n ?? null, this.rvfcSupported = t.isLive && typeof t.requestVideoFrameCallback == "function", this.rvfcSupported ? this.rvfcHandle = t.requestVideoFrameCallback(this._videoFrameLoop) : t.isLive || this.onDepthUpdate(t.currentTime), this.animationFrameHandle = window.requestAnimationFrame(this._rafLoop);
|
|
487
487
|
}
|
|
488
488
|
/** Stop both render loops and release callbacks. */
|
|
489
489
|
stop() {
|
|
490
|
-
this.
|
|
490
|
+
this.stopLoops(), this.mediaSource = null, this.readDepth = null, this.readInput = null, this.onVideoFrame = null, this.rvfcSupported = !1;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Pause the render loops without releasing callbacks.
|
|
494
|
+
* The loops can be resumed with `resume()`.
|
|
495
|
+
*/
|
|
496
|
+
pause() {
|
|
497
|
+
this.stopLoops();
|
|
498
|
+
}
|
|
499
|
+
/** Resume render loops previously paused with `pause()`. */
|
|
500
|
+
resume() {
|
|
501
|
+
this.readInput && (this.animationFrameHandle || (this.rvfcSupported && this.mediaSource?.requestVideoFrameCallback && (this.rvfcHandle = this.mediaSource.requestVideoFrameCallback(this._videoFrameLoop)), this.animationFrameHandle = window.requestAnimationFrame(this._rafLoop)));
|
|
502
|
+
}
|
|
503
|
+
/** Whether the render loops are currently paused. */
|
|
504
|
+
get isPaused() {
|
|
505
|
+
return this.animationFrameHandle === 0 && this.readInput !== null;
|
|
506
|
+
}
|
|
507
|
+
/** Cancel animation loops without clearing callbacks. */
|
|
508
|
+
stopLoops() {
|
|
509
|
+
this.animationFrameHandle && (window.cancelAnimationFrame(this.animationFrameHandle), this.animationFrameHandle = 0), this.rvfcHandle && this.mediaSource?.cancelVideoFrameCallback && (this.mediaSource.cancelVideoFrameCallback(this.rvfcHandle), this.rvfcHandle = 0);
|
|
491
510
|
}
|
|
492
511
|
/** Stop rendering and release all GPU resources. */
|
|
493
512
|
dispose() {
|
|
@@ -515,11 +534,11 @@ class gt {
|
|
|
515
534
|
* Delegates to subclass `onDepthUpdate()` for depth texture upload.
|
|
516
535
|
*/
|
|
517
536
|
_videoFrameLoop = (t, e) => {
|
|
518
|
-
const
|
|
519
|
-
if (!
|
|
520
|
-
this.rvfcHandle =
|
|
521
|
-
const
|
|
522
|
-
this.onDepthUpdate(
|
|
537
|
+
const i = this.mediaSource;
|
|
538
|
+
if (!i || !i.requestVideoFrameCallback) return;
|
|
539
|
+
this.rvfcHandle = i.requestVideoFrameCallback(this._videoFrameLoop);
|
|
540
|
+
const n = e.mediaTime ?? i.currentTime;
|
|
541
|
+
this.onDepthUpdate(n), this.onVideoFrame && this.onVideoFrame(n, e.presentedFrames ?? 0);
|
|
523
542
|
};
|
|
524
543
|
// -----------------------------------------------------------------------
|
|
525
544
|
// Context loss handling
|
|
@@ -560,14 +579,14 @@ class gt {
|
|
|
560
579
|
* Clamp depth dimensions to the quality tier's maximum and allocate
|
|
561
580
|
* the subsample buffer if needed. Called during `initialize()`.
|
|
562
581
|
*/
|
|
563
|
-
clampDepthDimensions(t, e,
|
|
582
|
+
clampDepthDimensions(t, e, i) {
|
|
564
583
|
this.sourceDepthWidth = t, this.sourceDepthHeight = e;
|
|
565
|
-
let
|
|
566
|
-
if (
|
|
567
|
-
const o =
|
|
568
|
-
|
|
584
|
+
let n = t, r = e;
|
|
585
|
+
if (n > i || r > i) {
|
|
586
|
+
const o = i / Math.max(n, r);
|
|
587
|
+
n = Math.max(1, Math.round(n * o)), r = Math.max(1, Math.round(r * o));
|
|
569
588
|
}
|
|
570
|
-
this.depthWidth =
|
|
589
|
+
this.depthWidth = n, this.depthHeight = r, n !== t || r !== e ? this.depthSubsampleBuffer = new Uint8Array(n * r) : this.depthSubsampleBuffer = null;
|
|
571
590
|
}
|
|
572
591
|
/**
|
|
573
592
|
* CPU nearest-neighbor depth subsampling.
|
|
@@ -577,11 +596,11 @@ class gt {
|
|
|
577
596
|
*/
|
|
578
597
|
subsampleDepth(t) {
|
|
579
598
|
if (!this.depthSubsampleBuffer) return t;
|
|
580
|
-
const e = this.depthSubsampleBuffer,
|
|
599
|
+
const e = this.depthSubsampleBuffer, i = this.sourceDepthWidth, n = this.depthWidth, r = this.depthHeight;
|
|
581
600
|
for (let o = 0; o < r; o++) {
|
|
582
|
-
const a = Math.min(Math.round(o * this.sourceDepthHeight / r), this.sourceDepthHeight - 1) *
|
|
583
|
-
for (let c = 0; c <
|
|
584
|
-
const f = Math.min(Math.round(c *
|
|
601
|
+
const a = Math.min(Math.round(o * this.sourceDepthHeight / r), this.sourceDepthHeight - 1) * i, h = o * n;
|
|
602
|
+
for (let c = 0; c < n; c++) {
|
|
603
|
+
const f = Math.min(Math.round(c * i / n), i - 1);
|
|
585
604
|
e[h + c] = t[a + f];
|
|
586
605
|
}
|
|
587
606
|
}
|
|
@@ -598,7 +617,7 @@ class gt {
|
|
|
598
617
|
* Updates `this.uvOffset` and `this.uvScale`.
|
|
599
618
|
*/
|
|
600
619
|
computeCoverFitUV(t, e) {
|
|
601
|
-
const { width:
|
|
620
|
+
const { width: i, height: n } = this.getViewportSize(), r = i / n, o = t + e;
|
|
602
621
|
let l = 1, a = 1;
|
|
603
622
|
r > this.videoAspect ? a = this.videoAspect / r : l = r / this.videoAspect;
|
|
604
623
|
const h = 1 + o * 2;
|
|
@@ -1135,7 +1154,7 @@ function Te(s, t) {
|
|
|
1135
1154
|
"#version 300 es",
|
|
1136
1155
|
`#version 300 es
|
|
1137
1156
|
#define BILATERAL_RADIUS ${t}`
|
|
1138
|
-
),
|
|
1157
|
+
), i = G(s, s.VERTEX_SHADER, bt), n = G(s, s.FRAGMENT_SHADER, e), r = mt(s, i, n), o = pt(s, r, ve), l = xe[t] ?? 2.25;
|
|
1139
1158
|
let a = null;
|
|
1140
1159
|
const h = {
|
|
1141
1160
|
name: "bilateral-filter",
|
|
@@ -1220,19 +1239,19 @@ function Se(s) {
|
|
|
1220
1239
|
"#version 300 es",
|
|
1221
1240
|
`#version 300 es
|
|
1222
1241
|
#define MAX_POM_STEPS ${be}`
|
|
1223
|
-
), e = G(s, s.VERTEX_SHADER, me),
|
|
1242
|
+
), e = G(s, s.VERTEX_SHADER, me), i = G(s, s.FRAGMENT_SHADER, t), n = mt(s, e, i), r = pt(s, n, Ee);
|
|
1224
1243
|
return {
|
|
1225
1244
|
name: "depth-effect",
|
|
1226
|
-
program:
|
|
1245
|
+
program: n,
|
|
1227
1246
|
uniforms: r,
|
|
1228
1247
|
setStaticUniforms(o, l, a, h) {
|
|
1229
|
-
o.useProgram(
|
|
1248
|
+
o.useProgram(n), o.uniform1i(r.uImage, 0), o.uniform1i(r.uDepth, 1), o.uniform1f(r.uStrength, l.parallaxStrength), o.uniform1i(r.uPomEnabled, l.pomEnabled ? 1 : 0), o.uniform1i(r.uPomSteps, l.pomSteps), o.uniform1f(r.uContrastLow, l.contrastLow), o.uniform1f(r.uContrastHigh, l.contrastHigh), o.uniform1f(r.uVerticalReduction, l.verticalReduction), o.uniform1f(r.uDofStart, l.dofStart), o.uniform1f(r.uDofStrength, l.dofStrength), o.uniform2f(r.uImageTexelSize, 1 / a, 1 / h), o.uniform1i(r.uDisplacementCurve, 3), o.uniform1i(r.uBlurCurve, 4), o.uniform1i(r.uCurvesEnabled, 0), o.uniform1f(r.uBlurRadius, l.blurRadius), o.uniform1f(r.uFocalBandOffset, 0), o.uniform1i(r.uGlowCurve, 5), o.uniform1i(r.uGlowEnabled, 0), o.uniform3f(r.uGlowColor, l.glowColor[0], l.glowColor[1], l.glowColor[2]), o.uniform1f(r.uGlowRadius, l.glowRadius), o.uniform1f(r.uGlowSoftness, l.glowSoftness), o.uniform1i(r.uGlowBlurred, 8), o.uniform1i(r.uColorShiftCurve, 6), o.uniform1i(r.uColorShiftEnabled, 0), o.uniform1f(r.uColorShiftHue, 0), o.uniform1f(r.uColorShiftSaturation, 1), o.uniform1f(r.uColorShiftBrightness, 1), o.uniform1f(r.uColorShiftTintStrength, 0), o.uniform3f(r.uColorShiftTintColor, 0.7, 0.8, 0.9), o.uniform1i(r.uTiltEnabled, l.tiltEnabled ? 1 : 0), o.uniform1f(r.uTiltHalfTanFov, l.tiltHalfTanFov), o.uniform1f(r.uTiltTransitionWidth, l.tiltTransitionWidth), o.uniform1f(r.uTiltPeakIntensity, l.tiltPeakIntensity), o.uniform3f(r.uTiltPlaneNormal, 0, 0, 1), o.uniform1f(r.uTiltPlaneD, 2.75);
|
|
1230
1249
|
},
|
|
1231
1250
|
updateUvTransform(o, l, a) {
|
|
1232
|
-
o.useProgram(
|
|
1251
|
+
o.useProgram(n), o.uniform2f(r.uUvOffset, l[0], l[1]), o.uniform2f(r.uUvScale, a[0], a[1]);
|
|
1233
1252
|
},
|
|
1234
1253
|
dispose(o) {
|
|
1235
|
-
o.deleteProgram(
|
|
1254
|
+
o.deleteProgram(n);
|
|
1236
1255
|
}
|
|
1237
1256
|
};
|
|
1238
1257
|
}
|
|
@@ -1288,14 +1307,14 @@ class ye extends gt {
|
|
|
1288
1307
|
tiltTransitionWidth: e.tiltTransitionWidth ?? B.tiltTransitionWidth,
|
|
1289
1308
|
tiltPeakIntensity: e.tiltPeakIntensity ?? B.tiltPeakIntensity
|
|
1290
1309
|
};
|
|
1291
|
-
const
|
|
1310
|
+
const i = this.canvas.getContext("webgl2", {
|
|
1292
1311
|
antialias: !1,
|
|
1293
1312
|
alpha: !1,
|
|
1294
1313
|
desynchronized: !0,
|
|
1295
1314
|
powerPreference: "high-performance"
|
|
1296
1315
|
});
|
|
1297
|
-
if (!
|
|
1298
|
-
this.gl =
|
|
1316
|
+
if (!i) throw new Error("WebGL 2 is not supported.");
|
|
1317
|
+
this.gl = i, this.qualityParams = Xt(i, e.quality), "drawingBufferColorSpace" in i && (i.drawingBufferColorSpace = "srgb"), i.clearColor(0, 0, 0, 1), i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
|
|
1299
1318
|
}
|
|
1300
1319
|
/**
|
|
1301
1320
|
* Set up the scene: create video texture, depth textures + FBO, and
|
|
@@ -1308,14 +1327,14 @@ class ye extends gt {
|
|
|
1308
1327
|
* @param depthWidth - Width of the precomputed depth map (e.g. 512).
|
|
1309
1328
|
* @param depthHeight - Height of the precomputed depth map (e.g. 512).
|
|
1310
1329
|
*/
|
|
1311
|
-
initialize(t, e,
|
|
1312
|
-
const
|
|
1313
|
-
if (
|
|
1314
|
-
if (this.disposeTextures(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.clampDepthDimensions(e,
|
|
1330
|
+
initialize(t, e, i) {
|
|
1331
|
+
const n = this.gl;
|
|
1332
|
+
if (n) {
|
|
1333
|
+
if (this.disposeTextures(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.clampDepthDimensions(e, i, this.qualityParams.depthMaxDim), this.videoSlot.texture = n.createTexture(), n.activeTexture(n.TEXTURE0 + this.videoSlot.unit), n.bindTexture(n.TEXTURE_2D, this.videoSlot.texture), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), this.rawDepthSlot.texture = n.createTexture(), n.activeTexture(n.TEXTURE0 + this.rawDepthSlot.unit), n.bindTexture(n.TEXTURE_2D, this.rawDepthSlot.texture), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), n.texStorage2D(n.TEXTURE_2D, 1, n.R8, e, i), this.filteredDepthSlot.texture = n.createTexture(), n.activeTexture(n.TEXTURE0 + this.filteredDepthSlot.unit), n.bindTexture(n.TEXTURE_2D, this.filteredDepthSlot.texture), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), n.texStorage2D(n.TEXTURE_2D, 1, n.R8, e, i), this.bilateralPass && this.filteredDepthSlot.texture && this.bilateralPass.initFBO(n, this.filteredDepthSlot.texture, e, i), this.glowBlurHPass && this.glowBlurVPass) {
|
|
1315
1334
|
const r = this.depthWidth, o = this.depthHeight;
|
|
1316
|
-
this.glowBlurHPass.resize(
|
|
1335
|
+
this.glowBlurHPass.resize(n, r, o), this.glowBlurVPass.resize(n, r, o), this.glowBlurHorizSlot.texture = this.glowBlurHPass.outputs[0].texture, this.glowBlurResultSlot.texture = this.glowBlurVPass.outputs[0].texture, n.useProgram(this.glowBlurHPass.program), n.uniform1i(this.glowBlurHPass.uniforms.uDepth, this.filteredDepthSlot.unit), n.uniform1i(this.glowBlurHPass.uniforms.uGlowCurve, this.glowLutSlot.unit), n.uniform2f(this.glowBlurHPass.uniforms.uBlurDir, 1, 0), n.uniform2f(this.glowBlurHPass.uniforms.uTexelSize, 1 / r, 1 / o), n.uniform1f(this.glowBlurHPass.uniforms.uGlowRadius, this.config.glowRadius), n.useProgram(this.glowBlurVPass.program), n.uniform1i(this.glowBlurVPass.uniforms.uHorizResult, this.glowBlurHorizSlot.unit), n.uniform2f(this.glowBlurVPass.uniforms.uBlurDir, 0, 1), n.uniform2f(this.glowBlurVPass.uniforms.uTexelSize, 1 / r, 1 / o), n.uniform1f(this.glowBlurVPass.uniforms.uGlowRadius, this.config.glowRadius);
|
|
1317
1336
|
}
|
|
1318
|
-
this.effectPass && this.effectPass.setStaticUniforms(
|
|
1337
|
+
this.effectPass && this.effectPass.setStaticUniforms(n, this.config, t.width, t.height), this.recalculateViewportLayout();
|
|
1319
1338
|
}
|
|
1320
1339
|
}
|
|
1321
1340
|
/**
|
|
@@ -1330,18 +1349,18 @@ class ye extends gt {
|
|
|
1330
1349
|
const e = this.gl;
|
|
1331
1350
|
if (!e || !this.effectPass) return;
|
|
1332
1351
|
t.parallaxStrength !== void 0 && (this.config.parallaxStrength = t.parallaxStrength), t.pomEnabled !== void 0 && (this.config.pomEnabled = t.pomEnabled), t.pomSteps !== void 0 && (this.config.pomSteps = t.pomSteps), t.overscanPadding !== void 0 && (this.config.overscanPadding = t.overscanPadding), t.contrastLow !== void 0 && (this.config.contrastLow = t.contrastLow), t.contrastHigh !== void 0 && (this.config.contrastHigh = t.contrastHigh), t.verticalReduction !== void 0 && (this.config.verticalReduction = t.verticalReduction), t.dofStart !== void 0 && (this.config.dofStart = t.dofStart), t.dofStrength !== void 0 && (this.config.dofStrength = t.dofStrength), t.blurRadius !== void 0 && (this.config.blurRadius = t.blurRadius), t.glowColor !== void 0 && (this.config.glowColor = t.glowColor), t.glowRadius !== void 0 && (this.config.glowRadius = t.glowRadius), t.glowSoftness !== void 0 && (this.config.glowSoftness = t.glowSoftness), t.tiltEnabled !== void 0 && (this.config.tiltEnabled = t.tiltEnabled), t.tiltHalfTanFov !== void 0 && (this.config.tiltHalfTanFov = t.tiltHalfTanFov), t.tiltTransitionWidth !== void 0 && (this.config.tiltTransitionWidth = t.tiltTransitionWidth), t.tiltPeakIntensity !== void 0 && (this.config.tiltPeakIntensity = t.tiltPeakIntensity);
|
|
1333
|
-
const { uniforms:
|
|
1334
|
-
e.useProgram(
|
|
1352
|
+
const { uniforms: i, program: n } = this.effectPass;
|
|
1353
|
+
e.useProgram(n), e.uniform1f(i.uStrength, this.config.parallaxStrength), e.uniform1i(i.uPomEnabled, this.config.pomEnabled ? 1 : 0), e.uniform1i(i.uPomSteps, this.config.pomSteps), e.uniform1f(i.uContrastLow, this.config.contrastLow), e.uniform1f(i.uContrastHigh, this.config.contrastHigh), e.uniform1f(i.uVerticalReduction, this.config.verticalReduction), e.uniform1f(i.uDofStart, this.config.dofStart), e.uniform1f(i.uDofStrength, this.config.dofStrength), e.uniform1f(i.uBlurRadius, this.config.blurRadius), e.uniform3f(i.uGlowColor, this.config.glowColor[0], this.config.glowColor[1], this.config.glowColor[2]), e.uniform1f(i.uGlowRadius, this.config.glowRadius), e.uniform1f(i.uGlowSoftness, this.config.glowSoftness), e.uniform1i(i.uTiltEnabled, this.config.tiltEnabled ? 1 : 0), e.uniform1f(i.uTiltHalfTanFov, this.config.tiltHalfTanFov), e.uniform1f(i.uTiltTransitionWidth, this.config.tiltTransitionWidth), e.uniform1f(i.uTiltPeakIntensity, this.config.tiltPeakIntensity), t.glowRadius !== void 0 && (this.glowBlurHPass && (e.useProgram(this.glowBlurHPass.program), e.uniform1f(this.glowBlurHPass.uniforms.uGlowRadius, this.config.glowRadius)), this.glowBlurVPass && (e.useProgram(this.glowBlurVPass.program), e.uniform1f(this.glowBlurVPass.uniforms.uGlowRadius, this.config.glowRadius)), this.refreshGlowBlur()), (t.parallaxStrength !== void 0 || t.overscanPadding !== void 0) && this.recalculateViewportLayout();
|
|
1335
1354
|
}
|
|
1336
1355
|
/**
|
|
1337
1356
|
* Upload new curve LUT data to the GPU.
|
|
1338
1357
|
* Call this whenever the curve editor changes.
|
|
1339
1358
|
*/
|
|
1340
|
-
updateCurveLUTs(t, e,
|
|
1359
|
+
updateCurveLUTs(t, e, i, n, r) {
|
|
1341
1360
|
const o = this.gl;
|
|
1342
1361
|
if (!o || !this.effectPass) return;
|
|
1343
|
-
const l = !!(t || e), a = !!
|
|
1344
|
-
t && this.uploadLUT(this.displacementLutSlot, t), e && this.uploadLUT(this.blurLutSlot, e),
|
|
1362
|
+
const l = !!(t || e), a = !!i, h = !!n;
|
|
1363
|
+
t && this.uploadLUT(this.displacementLutSlot, t), e && this.uploadLUT(this.blurLutSlot, e), i && this.uploadLUT(this.glowLutSlot, i), n && this.uploadLUT(this.colorShiftLutSlot, n), o.useProgram(this.effectPass.program), o.uniform1i(
|
|
1345
1364
|
this.effectPass.uniforms.uCurvesEnabled,
|
|
1346
1365
|
l ? 1 : 0
|
|
1347
1366
|
), o.uniform1i(
|
|
@@ -1352,7 +1371,7 @@ class ye extends gt {
|
|
|
1352
1371
|
h ? 1 : 0
|
|
1353
1372
|
);
|
|
1354
1373
|
const c = this.glowEnabled !== a;
|
|
1355
|
-
if (this.glowEnabled = a, a && (c ||
|
|
1374
|
+
if (this.glowEnabled = a, a && (c || i) && this.refreshGlowBlur(), h && r) {
|
|
1356
1375
|
const f = this.effectPass.uniforms;
|
|
1357
1376
|
o.uniform1f(f.uColorShiftHue, r.hueShift * (Math.PI / 180)), o.uniform1f(f.uColorShiftSaturation, r.saturation), o.uniform1f(f.uColorShiftBrightness, r.brightness), o.uniform1f(f.uColorShiftTintStrength, r.tintStrength), o.uniform3f(
|
|
1358
1377
|
f.uColorShiftTintColor,
|
|
@@ -1379,7 +1398,7 @@ class ye extends gt {
|
|
|
1379
1398
|
"#version 300 es",
|
|
1380
1399
|
`#version 300 es
|
|
1381
1400
|
#define PASS_HORIZONTAL`
|
|
1382
|
-
),
|
|
1401
|
+
), i = [
|
|
1383
1402
|
"uDepth",
|
|
1384
1403
|
"uGlowCurve",
|
|
1385
1404
|
"uHorizResult",
|
|
@@ -1392,7 +1411,7 @@ class ye extends gt {
|
|
|
1392
1411
|
"glow-blur-h",
|
|
1393
1412
|
bt,
|
|
1394
1413
|
e,
|
|
1395
|
-
|
|
1414
|
+
i,
|
|
1396
1415
|
{
|
|
1397
1416
|
internalFormat: t.R8,
|
|
1398
1417
|
format: t.RED,
|
|
@@ -1406,7 +1425,7 @@ class ye extends gt {
|
|
|
1406
1425
|
"glow-blur-v",
|
|
1407
1426
|
bt,
|
|
1408
1427
|
Ft,
|
|
1409
|
-
|
|
1428
|
+
i,
|
|
1410
1429
|
{
|
|
1411
1430
|
internalFormat: t.R8,
|
|
1412
1431
|
format: t.RED,
|
|
@@ -1425,8 +1444,8 @@ class ye extends gt {
|
|
|
1425
1444
|
* Creates the texture on first call, updates via texSubImage2D thereafter.
|
|
1426
1445
|
*/
|
|
1427
1446
|
uploadLUT(t, e) {
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1447
|
+
const i = this.gl;
|
|
1448
|
+
i && (i.activeTexture(i.TEXTURE0 + t.unit), t.texture ? i.bindTexture(i.TEXTURE_2D, t.texture) : (t.texture = i.createTexture(), i.bindTexture(i.TEXTURE_2D, t.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texStorage2D(i.TEXTURE_2D, 1, i.R8, 256, 1)), i.texSubImage2D(i.TEXTURE_2D, 0, 0, 0, 256, 1, i.RED, i.UNSIGNED_BYTE, e));
|
|
1430
1449
|
}
|
|
1431
1450
|
// -----------------------------------------------------------------------
|
|
1432
1451
|
// Abstract method implementations
|
|
@@ -1446,16 +1465,16 @@ class ye extends gt {
|
|
|
1446
1465
|
const t = this.gl, e = this.mediaSource;
|
|
1447
1466
|
if (!t || !this.effectPass || !this.quadVao)
|
|
1448
1467
|
return;
|
|
1449
|
-
const
|
|
1450
|
-
if (
|
|
1451
|
-
if (!this.rvfcSupported && e.isLive && this.onDepthUpdate(e.currentTime), t.useProgram(this.effectPass.program), t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE,
|
|
1452
|
-
const
|
|
1453
|
-
t.uniform2f(this.effectPass.uniforms.uOffset, -
|
|
1468
|
+
const i = e?.getImageSource();
|
|
1469
|
+
if (i) {
|
|
1470
|
+
if (!this.rvfcSupported && e.isLive && this.onDepthUpdate(e.currentTime), t.useProgram(this.effectPass.program), t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, i), this.readInput) {
|
|
1471
|
+
const n = this.readInput();
|
|
1472
|
+
t.uniform2f(this.effectPass.uniforms.uOffset, -n.x, n.y), n.focalBandOffset !== void 0 && t.uniform1f(this.effectPass.uniforms.uFocalBandOffset, n.focalBandOffset), n.tiltPlaneNormal !== void 0 && t.uniform3f(
|
|
1454
1473
|
this.effectPass.uniforms.uTiltPlaneNormal,
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
),
|
|
1474
|
+
n.tiltPlaneNormal[0],
|
|
1475
|
+
n.tiltPlaneNormal[1],
|
|
1476
|
+
n.tiltPlaneNormal[2]
|
|
1477
|
+
), n.tiltPlaneD !== void 0 && t.uniform1f(this.effectPass.uniforms.uTiltPlaneD, n.tiltPlaneD);
|
|
1459
1478
|
}
|
|
1460
1479
|
t.bindVertexArray(this.quadVao), t.drawArrays(t.TRIANGLE_STRIP, 0, 4);
|
|
1461
1480
|
}
|
|
@@ -1471,12 +1490,12 @@ class ye extends gt {
|
|
|
1471
1490
|
onDepthUpdate(t) {
|
|
1472
1491
|
const e = this.gl;
|
|
1473
1492
|
if (!e || !this.readDepth || !this.rawDepthSlot.texture || !this.bilateralPass) return;
|
|
1474
|
-
const
|
|
1493
|
+
const i = this.subsampleDepth(this.readDepth(t));
|
|
1475
1494
|
this.bilateralPass.execute(
|
|
1476
1495
|
e,
|
|
1477
1496
|
this.quadVao,
|
|
1478
1497
|
this.rawDepthSlot.texture,
|
|
1479
|
-
|
|
1498
|
+
i,
|
|
1480
1499
|
this.depthWidth,
|
|
1481
1500
|
this.depthHeight,
|
|
1482
1501
|
this.canvas.width,
|
|
@@ -1489,8 +1508,8 @@ class ye extends gt {
|
|
|
1489
1508
|
*/
|
|
1490
1509
|
executeGlowBlur(t) {
|
|
1491
1510
|
if (!this.glowBlurHPass?.fbo || !this.glowBlurVPass?.fbo || !this.quadVao) return;
|
|
1492
|
-
const e = this.depthWidth,
|
|
1493
|
-
t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurHPass.fbo), t.viewport(0, 0, e,
|
|
1511
|
+
const e = this.depthWidth, i = this.depthHeight;
|
|
1512
|
+
t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurHPass.fbo), t.viewport(0, 0, e, i), t.useProgram(this.glowBlurHPass.program), t.bindVertexArray(this.quadVao), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurVPass.fbo), t.useProgram(this.glowBlurVPass.program), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, null), t.viewport(0, 0, this.canvas.width, this.canvas.height);
|
|
1494
1513
|
}
|
|
1495
1514
|
/**
|
|
1496
1515
|
* Re-execute glow blur on demand (when glow LUT or radius changes).
|
|
@@ -1510,7 +1529,7 @@ class ye extends gt {
|
|
|
1510
1529
|
recalculateViewportLayout() {
|
|
1511
1530
|
const t = this.gl;
|
|
1512
1531
|
if (!t) return;
|
|
1513
|
-
const { width: e, height:
|
|
1532
|
+
const { width: e, height: i } = this.getViewportSize(), n = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * n), o = Math.round(i * n);
|
|
1514
1533
|
(this.canvas.width !== r || this.canvas.height !== o) && (this.canvas.width = r, this.canvas.height = o, t.viewport(0, 0, r, o)), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.effectPass && this.effectPass.updateUvTransform(t, this.uvOffset, this.uvScale);
|
|
1515
1534
|
}
|
|
1516
1535
|
/** Release all GPU resources. */
|
|
@@ -1539,10 +1558,10 @@ class ye extends gt {
|
|
|
1539
1558
|
async function ht(s, t = {}) {
|
|
1540
1559
|
const {
|
|
1541
1560
|
parent: e = document.body,
|
|
1542
|
-
loop:
|
|
1543
|
-
muted:
|
|
1561
|
+
loop: i = !0,
|
|
1562
|
+
muted: n = !0
|
|
1544
1563
|
} = t, r = document.createElement("video");
|
|
1545
|
-
return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted =
|
|
1564
|
+
return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted = n, r.defaultMuted = n, n && r.setAttribute("muted", ""), r.loop = i, r.preload = "auto", r.style.display = "none", r.src = s, e.appendChild(r), await Gt(r), new we(r);
|
|
1546
1565
|
}
|
|
1547
1566
|
class we {
|
|
1548
1567
|
constructor(t) {
|
|
@@ -1592,12 +1611,12 @@ class we {
|
|
|
1592
1611
|
}
|
|
1593
1612
|
async function ft(s, t = {}) {
|
|
1594
1613
|
const e = new Image();
|
|
1595
|
-
return e.crossOrigin = "anonymous", e.src = s, await new Promise((
|
|
1614
|
+
return e.crossOrigin = "anonymous", e.src = s, await new Promise((i, n) => {
|
|
1596
1615
|
if (e.complete && e.naturalWidth > 0) {
|
|
1597
|
-
|
|
1616
|
+
i();
|
|
1598
1617
|
return;
|
|
1599
1618
|
}
|
|
1600
|
-
e.addEventListener("load", () =>
|
|
1619
|
+
e.addEventListener("load", () => i(), { once: !0 }), e.addEventListener("error", () => n(new Error(`Failed to load image: ${s}`)), { once: !0 });
|
|
1601
1620
|
}), new Re(e);
|
|
1602
1621
|
}
|
|
1603
1622
|
class Re {
|
|
@@ -1623,8 +1642,8 @@ class Re {
|
|
|
1623
1642
|
}
|
|
1624
1643
|
}
|
|
1625
1644
|
async function Nt(s = { video: !0 }, t = {}) {
|
|
1626
|
-
const { parent: e = document.body } = t,
|
|
1627
|
-
return
|
|
1645
|
+
const { parent: e = document.body } = t, i = await navigator.mediaDevices.getUserMedia(s), n = document.createElement("video");
|
|
1646
|
+
return n.playsInline = !0, n.setAttribute("playsinline", ""), n.muted = !0, n.defaultMuted = !0, n.style.display = "none", n.srcObject = i, e.appendChild(n), await Gt(n), await n.play(), new Ae(n, i);
|
|
1628
1647
|
}
|
|
1629
1648
|
class Ae {
|
|
1630
1649
|
constructor(t, e) {
|
|
@@ -1674,14 +1693,14 @@ class Ae {
|
|
|
1674
1693
|
}
|
|
1675
1694
|
async function Gt(s) {
|
|
1676
1695
|
s.readyState >= HTMLMediaElement.HAVE_METADATA || await new Promise((t, e) => {
|
|
1677
|
-
const
|
|
1696
|
+
const i = () => {
|
|
1678
1697
|
r(), t();
|
|
1679
|
-
},
|
|
1698
|
+
}, n = () => {
|
|
1680
1699
|
r(), e(new Error("Failed to load video metadata."));
|
|
1681
1700
|
}, r = () => {
|
|
1682
|
-
s.removeEventListener("loadedmetadata",
|
|
1701
|
+
s.removeEventListener("loadedmetadata", i), s.removeEventListener("error", n);
|
|
1683
1702
|
};
|
|
1684
|
-
s.addEventListener("loadedmetadata",
|
|
1703
|
+
s.addEventListener("loadedmetadata", i), s.addEventListener("error", n), s.load();
|
|
1685
1704
|
});
|
|
1686
1705
|
}
|
|
1687
1706
|
const Z = 518;
|
|
@@ -1691,9 +1710,9 @@ async function Pe() {
|
|
|
1691
1710
|
class De {
|
|
1692
1711
|
constructor(t, e) {
|
|
1693
1712
|
this.depthWidth = t, this.depthHeight = e;
|
|
1694
|
-
const
|
|
1695
|
-
this.frontBuffer = new Uint8Array(
|
|
1696
|
-
this.readyResolve =
|
|
1713
|
+
const i = t * e;
|
|
1714
|
+
this.frontBuffer = new Uint8Array(i), this.frontBuffer.fill(128), this.backBuffer = new Uint8Array(i), this.backBuffer.fill(128), this.readyPromise = new Promise((n) => {
|
|
1715
|
+
this.readyResolve = n;
|
|
1697
1716
|
});
|
|
1698
1717
|
}
|
|
1699
1718
|
// ONNX session + module (set after init)
|
|
@@ -1727,21 +1746,21 @@ class De {
|
|
|
1727
1746
|
* (GPU-accelerated on main thread), falls back to WASM EP.
|
|
1728
1747
|
*/
|
|
1729
1748
|
async init(t, e) {
|
|
1730
|
-
const
|
|
1731
|
-
if (this.ort =
|
|
1749
|
+
const i = await Pe();
|
|
1750
|
+
if (this.ort = i, this.captureCanvas = document.createElement("canvas"), this.captureCanvas.width = Z, this.captureCanvas.height = Z, this.captureCtx = this.captureCanvas.getContext("2d", {
|
|
1732
1751
|
willReadFrequently: !0
|
|
1733
1752
|
}), !this.captureCtx)
|
|
1734
1753
|
throw new Error("[DepthEstimator] Failed to create 2D canvas context.");
|
|
1735
1754
|
e?.({ receivedBytes: 0, totalBytes: null, fraction: 0, label: "Downloading depth model…" });
|
|
1736
|
-
const
|
|
1737
|
-
e?.({ receivedBytes:
|
|
1755
|
+
const n = await Fe(t, e);
|
|
1756
|
+
e?.({ receivedBytes: n.byteLength, totalBytes: n.byteLength, fraction: 1, label: "Initialising depth model…" });
|
|
1738
1757
|
let r;
|
|
1739
1758
|
try {
|
|
1740
|
-
r = await
|
|
1759
|
+
r = await i.InferenceSession.create(n, {
|
|
1741
1760
|
executionProviders: ["webgpu"]
|
|
1742
1761
|
}), console.log("[DepthEstimator] Using WebGPU execution provider");
|
|
1743
1762
|
} catch (o) {
|
|
1744
|
-
console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:", o),
|
|
1763
|
+
console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:", o), i.env.wasm.proxy = !0, r = await i.InferenceSession.create(n, {
|
|
1745
1764
|
executionProviders: ["wasm"]
|
|
1746
1765
|
}), console.log("[DepthEstimator] Using WASM execution provider (proxy worker)");
|
|
1747
1766
|
}
|
|
@@ -1810,7 +1829,7 @@ class De {
|
|
|
1810
1829
|
0,
|
|
1811
1830
|
Z,
|
|
1812
1831
|
Z
|
|
1813
|
-
),
|
|
1832
|
+
), i = await this.workerPreprocess(e.data.buffer, e.width, e.height), n = new this.ort.Tensor("float32", new Float32Array(i), [1, 3, e.height, e.width]), o = (await this.session.run({ [this.inputName]: n }))[this.outputName], l = o.data, a = o.dims, h = a.length === 3 ? a[1] : a[2], c = a.length === 3 ? a[2] : a[3], f = await this.workerPostprocess(l.slice(0).buffer, c, h);
|
|
1814
1833
|
this.backBuffer.set(new Uint8Array(f));
|
|
1815
1834
|
const u = this.frontBuffer;
|
|
1816
1835
|
this.frontBuffer = this.backBuffer, this.backBuffer = u;
|
|
@@ -1820,50 +1839,50 @@ class De {
|
|
|
1820
1839
|
this.inferenceInFlight = !1;
|
|
1821
1840
|
}
|
|
1822
1841
|
}
|
|
1823
|
-
workerPreprocess(t, e,
|
|
1824
|
-
return new Promise((
|
|
1842
|
+
workerPreprocess(t, e, i) {
|
|
1843
|
+
return new Promise((n, r) => {
|
|
1825
1844
|
if (!this.preprocessWorker) {
|
|
1826
1845
|
r(new Error("Worker not ready"));
|
|
1827
1846
|
return;
|
|
1828
1847
|
}
|
|
1829
1848
|
const o = (a) => {
|
|
1830
|
-
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "preprocessed" ?
|
|
1849
|
+
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "preprocessed" ? n(a.data.float32) : a.data.type === "error" && r(new Error(a.data.message));
|
|
1831
1850
|
};
|
|
1832
1851
|
this.preprocessWorker.addEventListener("message", o);
|
|
1833
1852
|
const l = t.slice(0);
|
|
1834
1853
|
this.preprocessWorker.postMessage(
|
|
1835
|
-
{ type: "preprocess", pixels: l, width: e, height:
|
|
1854
|
+
{ type: "preprocess", pixels: l, width: e, height: i },
|
|
1836
1855
|
[l]
|
|
1837
1856
|
);
|
|
1838
1857
|
});
|
|
1839
1858
|
}
|
|
1840
|
-
workerPostprocess(t, e,
|
|
1841
|
-
return new Promise((
|
|
1859
|
+
workerPostprocess(t, e, i) {
|
|
1860
|
+
return new Promise((n, r) => {
|
|
1842
1861
|
if (!this.preprocessWorker) {
|
|
1843
1862
|
r(new Error("Worker not ready"));
|
|
1844
1863
|
return;
|
|
1845
1864
|
}
|
|
1846
1865
|
const o = (a) => {
|
|
1847
|
-
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "postprocessed" ?
|
|
1866
|
+
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "postprocessed" ? n(a.data.depth) : a.data.type === "error" && r(new Error(a.data.message));
|
|
1848
1867
|
};
|
|
1849
1868
|
this.preprocessWorker.addEventListener("message", o);
|
|
1850
1869
|
const l = t.slice(0);
|
|
1851
1870
|
this.preprocessWorker.postMessage(
|
|
1852
|
-
{ type: "postprocess", depthFloat: l, srcW: e, srcH:
|
|
1871
|
+
{ type: "postprocess", depthFloat: l, srcW: e, srcH: i, dstW: this.depthWidth, dstH: this.depthHeight },
|
|
1853
1872
|
[l]
|
|
1854
1873
|
);
|
|
1855
1874
|
});
|
|
1856
1875
|
}
|
|
1857
1876
|
}
|
|
1858
|
-
async function dt(s, t, e,
|
|
1859
|
-
const
|
|
1860
|
-
return await
|
|
1877
|
+
async function dt(s, t, e, i) {
|
|
1878
|
+
const n = new De(t, e);
|
|
1879
|
+
return await n.init(s, i), n;
|
|
1861
1880
|
}
|
|
1862
1881
|
async function Fe(s, t) {
|
|
1863
1882
|
const e = await fetch(s);
|
|
1864
1883
|
if (!e.ok)
|
|
1865
1884
|
throw new Error(`[DepthEstimator] Failed to fetch model (${e.status} ${e.statusText}).`);
|
|
1866
|
-
const
|
|
1885
|
+
const i = e.headers.get("content-length"), n = i ? Number(i) : null, r = e.body;
|
|
1867
1886
|
if (!r) {
|
|
1868
1887
|
const f = await e.arrayBuffer();
|
|
1869
1888
|
return t?.({
|
|
@@ -1881,8 +1900,8 @@ async function Fe(s, t) {
|
|
|
1881
1900
|
if (f) break;
|
|
1882
1901
|
u && (o.push(u), l += u.byteLength, t?.({
|
|
1883
1902
|
receivedBytes: l,
|
|
1884
|
-
totalBytes:
|
|
1885
|
-
fraction:
|
|
1903
|
+
totalBytes: n,
|
|
1904
|
+
fraction: n ? Math.min(l / n, 1) : 0,
|
|
1886
1905
|
label: "Downloading depth model…"
|
|
1887
1906
|
}));
|
|
1888
1907
|
}
|
|
@@ -1902,27 +1921,27 @@ function St(s, t) {
|
|
|
1902
1921
|
if (e.length === 0) return 0;
|
|
1903
1922
|
if (e.length === 1 || t <= e[0].x) return e[0].y;
|
|
1904
1923
|
if (t >= e[e.length - 1].x) return e[e.length - 1].y;
|
|
1905
|
-
let
|
|
1906
|
-
for (;
|
|
1907
|
-
const
|
|
1924
|
+
let i = 0;
|
|
1925
|
+
for (; i < e.length - 1 && e[i + 1].x < t; ) i++;
|
|
1926
|
+
const n = e[i], r = e[i + 1], o = (t - n.x) / (r.x - n.x);
|
|
1908
1927
|
switch (s.interpolation) {
|
|
1909
1928
|
case "step":
|
|
1910
|
-
return
|
|
1929
|
+
return n.y;
|
|
1911
1930
|
case "linear":
|
|
1912
|
-
return
|
|
1931
|
+
return n.y + (r.y - n.y) * o;
|
|
1913
1932
|
case "smooth": {
|
|
1914
1933
|
const l = o * o * (3 - 2 * o);
|
|
1915
|
-
return
|
|
1934
|
+
return n.y + (r.y - n.y) * l;
|
|
1916
1935
|
}
|
|
1917
1936
|
default:
|
|
1918
|
-
return
|
|
1937
|
+
return n.y + (r.y - n.y) * o;
|
|
1919
1938
|
}
|
|
1920
1939
|
}
|
|
1921
1940
|
function lt(s, t = 256) {
|
|
1922
1941
|
const e = new Uint8Array(t);
|
|
1923
|
-
for (let
|
|
1924
|
-
const
|
|
1925
|
-
e[
|
|
1942
|
+
for (let i = 0; i < t; i++) {
|
|
1943
|
+
const n = i / (t - 1);
|
|
1944
|
+
e[i] = Math.round(St(s, n) * 255);
|
|
1926
1945
|
}
|
|
1927
1946
|
return e;
|
|
1928
1947
|
}
|
|
@@ -1930,10 +1949,10 @@ function q(s, t) {
|
|
|
1930
1949
|
return s.find((e) => e.channel === t && e.enabled);
|
|
1931
1950
|
}
|
|
1932
1951
|
function Ut(s, t) {
|
|
1933
|
-
const e = q(s, "displacement"),
|
|
1952
|
+
const e = q(s, "displacement"), i = q(s, "blur"), n = q(s, "glow"), r = e?.params;
|
|
1934
1953
|
let o = 0.6, l = 0;
|
|
1935
|
-
if (
|
|
1936
|
-
const a =
|
|
1954
|
+
if (i) {
|
|
1955
|
+
const a = i.curve;
|
|
1937
1956
|
for (let h = 0; h <= 1; h += 0.01)
|
|
1938
1957
|
if (St(a, h) > 0.01) {
|
|
1939
1958
|
o = h;
|
|
@@ -1950,23 +1969,23 @@ function Ut(s, t) {
|
|
|
1950
1969
|
verticalReduction: t.verticalReduction,
|
|
1951
1970
|
dofStart: o,
|
|
1952
1971
|
dofStrength: l,
|
|
1953
|
-
blurRadius:
|
|
1954
|
-
glowColor:
|
|
1955
|
-
glowRadius:
|
|
1956
|
-
glowSoftness:
|
|
1957
|
-
tiltEnabled:
|
|
1958
|
-
tiltHalfTanFov: Math.tan((
|
|
1959
|
-
tiltTransitionWidth: (
|
|
1960
|
-
tiltPeakIntensity:
|
|
1972
|
+
blurRadius: i?.params?.maxRadius ?? 0.01,
|
|
1973
|
+
glowColor: n?.params?.color ?? [1, 0.95, 0.85],
|
|
1974
|
+
glowRadius: n?.params?.radius ?? 0.02,
|
|
1975
|
+
glowSoftness: n?.params?.softness ?? 0.6,
|
|
1976
|
+
tiltEnabled: i?.params?.tiltEnabled ?? !1,
|
|
1977
|
+
tiltHalfTanFov: Math.tan((i?.params?.tiltFov ?? 50) * Math.PI / 360),
|
|
1978
|
+
tiltTransitionWidth: (i?.params?.focalWidth ?? 0.3) * 4.5,
|
|
1979
|
+
tiltPeakIntensity: i?.params?.peakIntensity ?? 0.8
|
|
1961
1980
|
};
|
|
1962
1981
|
}
|
|
1963
1982
|
function Lt(s) {
|
|
1964
|
-
const t = q(s, "displacement"), e = q(s, "blur"),
|
|
1983
|
+
const t = q(s, "displacement"), e = q(s, "blur"), i = q(s, "glow"), n = q(s, "color-shift"), r = n?.params;
|
|
1965
1984
|
return {
|
|
1966
1985
|
displacementLUT: t ? lt(t.curve) : null,
|
|
1967
1986
|
blurLUT: e ? lt(e.curve) : null,
|
|
1968
|
-
glowLUT:
|
|
1969
|
-
colorShiftLUT:
|
|
1987
|
+
glowLUT: i ? lt(i.curve) : null,
|
|
1988
|
+
colorShiftLUT: n ? lt(n.curve) : null,
|
|
1970
1989
|
colorShiftParams: r ? {
|
|
1971
1990
|
hueShift: r.hueShift ?? 0,
|
|
1972
1991
|
saturation: r.saturation ?? 1,
|
|
@@ -1991,8 +2010,8 @@ class Wt {
|
|
|
1991
2010
|
onDisconnected() {
|
|
1992
2011
|
this.cancelInit(), this.element.doDispose(), this.initialized = !1;
|
|
1993
2012
|
}
|
|
1994
|
-
onAttributeChanged(t, e,
|
|
1995
|
-
this.element.reinitAttributes.includes(t) && e !==
|
|
2013
|
+
onAttributeChanged(t, e, i) {
|
|
2014
|
+
this.element.reinitAttributes.includes(t) && e !== i && (this.initialized ? (this.cancelInit(), this.element.doDispose(), this.initialized = !1, this.element.setupShadowDOM(), this.tryInit()) : this.initializing || this.tryInit());
|
|
1996
2015
|
}
|
|
1997
2016
|
get isInitialized() {
|
|
1998
2017
|
return this.initialized;
|
|
@@ -2008,8 +2027,8 @@ class Wt {
|
|
|
2008
2027
|
if (t.canInit) {
|
|
2009
2028
|
if (!t.canInit()) return;
|
|
2010
2029
|
} else
|
|
2011
|
-
for (const
|
|
2012
|
-
if (!t.getAttribute(
|
|
2030
|
+
for (const i of t.reinitAttributes)
|
|
2031
|
+
if (!t.getAttribute(i)) return;
|
|
2013
2032
|
this.cancelInit();
|
|
2014
2033
|
const e = new AbortController();
|
|
2015
2034
|
this.abortController = e, this.initializing = !0;
|
|
@@ -2040,10 +2059,10 @@ class xt extends HTMLElement {
|
|
|
2040
2059
|
static get observedAttributes() {
|
|
2041
2060
|
return [
|
|
2042
2061
|
"src",
|
|
2043
|
-
"
|
|
2044
|
-
"
|
|
2045
|
-
"
|
|
2046
|
-
"
|
|
2062
|
+
"map-src",
|
|
2063
|
+
"map-width",
|
|
2064
|
+
"map-height",
|
|
2065
|
+
"map-fps",
|
|
2047
2066
|
"depth-model",
|
|
2048
2067
|
"source-type",
|
|
2049
2068
|
"config",
|
|
@@ -2059,11 +2078,11 @@ class xt extends HTMLElement {
|
|
|
2059
2078
|
"muted"
|
|
2060
2079
|
];
|
|
2061
2080
|
}
|
|
2062
|
-
reinitAttributes = ["src", "
|
|
2081
|
+
reinitAttributes = ["src", "map-src", "map-width", "map-height", "map-fps", "depth-model", "source-type", "config"];
|
|
2063
2082
|
canInit() {
|
|
2064
2083
|
if (this.sourceType === "camera") return !0;
|
|
2065
|
-
const t = !!this.getAttribute("src"), e = !!this.getAttribute("
|
|
2066
|
-
return t && (e ||
|
|
2084
|
+
const t = !!this.getAttribute("src"), e = !!this.getAttribute("map-src"), i = !!this.getAttribute("depth-model");
|
|
2085
|
+
return t && (e || i);
|
|
2067
2086
|
}
|
|
2068
2087
|
shadow;
|
|
2069
2088
|
container = null;
|
|
@@ -2091,15 +2110,15 @@ class xt extends HTMLElement {
|
|
|
2091
2110
|
}
|
|
2092
2111
|
// --- Attribute helpers ---
|
|
2093
2112
|
getAttrFloat(t, e) {
|
|
2094
|
-
const
|
|
2095
|
-
if (
|
|
2096
|
-
const
|
|
2097
|
-
return Number.isFinite(
|
|
2113
|
+
const i = this.getAttribute(t);
|
|
2114
|
+
if (i === null) return e;
|
|
2115
|
+
const n = parseFloat(i);
|
|
2116
|
+
return Number.isFinite(n) ? n : e;
|
|
2098
2117
|
}
|
|
2099
2118
|
getAttrBool(t, e) {
|
|
2100
2119
|
if (!this.hasAttribute(t)) return e;
|
|
2101
|
-
const
|
|
2102
|
-
return !(
|
|
2120
|
+
const i = this.getAttribute(t);
|
|
2121
|
+
return !(i === "false" || i === "0");
|
|
2103
2122
|
}
|
|
2104
2123
|
get parallaxX() {
|
|
2105
2124
|
return this.getAttrFloat("parallax-x", z.parallaxX);
|
|
@@ -2178,8 +2197,8 @@ class xt extends HTMLElement {
|
|
|
2178
2197
|
disconnectedCallback() {
|
|
2179
2198
|
this.lifecycle.onDisconnected();
|
|
2180
2199
|
}
|
|
2181
|
-
attributeChangedCallback(t, e,
|
|
2182
|
-
this.lifecycle.onAttributeChanged(t, e,
|
|
2200
|
+
attributeChangedCallback(t, e, i) {
|
|
2201
|
+
this.lifecycle.onAttributeChanged(t, e, i);
|
|
2183
2202
|
}
|
|
2184
2203
|
// --- Shadow DOM setup ---
|
|
2185
2204
|
setupShadowDOM() {
|
|
@@ -2216,27 +2235,27 @@ class xt extends HTMLElement {
|
|
|
2216
2235
|
const e = this.getAttribute("config");
|
|
2217
2236
|
if (!e) return null;
|
|
2218
2237
|
try {
|
|
2219
|
-
const
|
|
2220
|
-
if (!
|
|
2221
|
-
return console.warn(`<layershift-effect>: Failed to fetch config from "${e}" (${
|
|
2222
|
-
const
|
|
2238
|
+
const i = await fetch(e, { signal: t });
|
|
2239
|
+
if (!i.ok)
|
|
2240
|
+
return console.warn(`<layershift-effect>: Failed to fetch config from "${e}" (${i.status})`), null;
|
|
2241
|
+
const n = await i.json();
|
|
2223
2242
|
return {
|
|
2224
|
-
channels:
|
|
2225
|
-
motion:
|
|
2226
|
-
overscanPadding:
|
|
2227
|
-
quality:
|
|
2243
|
+
channels: n.channels ?? [],
|
|
2244
|
+
motion: n.motion ?? Ct,
|
|
2245
|
+
overscanPadding: n.overscanPadding ?? 0.05,
|
|
2246
|
+
quality: n.quality ?? "auto"
|
|
2228
2247
|
};
|
|
2229
|
-
} catch (
|
|
2230
|
-
return
|
|
2248
|
+
} catch (i) {
|
|
2249
|
+
return i.name === "AbortError" || console.warn("<layershift-effect>: Failed to parse config.", i), null;
|
|
2231
2250
|
}
|
|
2232
2251
|
}
|
|
2233
2252
|
/**
|
|
2234
2253
|
* Build renderer config from HTML attributes (legacy parallax-only path).
|
|
2235
2254
|
*/
|
|
2236
2255
|
buildLegacyConfig(t, e) {
|
|
2237
|
-
const
|
|
2256
|
+
const i = this.container?.clientWidth || e, n = this.hasAttribute("parallax-max") ? this.parallaxMax / Math.max(i, 1) : t.parallaxStrength, r = this.hasAttribute("overscan") ? this.overscan : t.overscanPadding;
|
|
2238
2257
|
return {
|
|
2239
|
-
parallaxStrength:
|
|
2258
|
+
parallaxStrength: n,
|
|
2240
2259
|
pomEnabled: !0,
|
|
2241
2260
|
pomSteps: t.pomSteps,
|
|
2242
2261
|
overscanPadding: r,
|
|
@@ -2251,30 +2270,30 @@ class xt extends HTMLElement {
|
|
|
2251
2270
|
// --- Initialization ---
|
|
2252
2271
|
async doInit(t) {
|
|
2253
2272
|
if (!this.container) return;
|
|
2254
|
-
const e = this.sourceType === "camera",
|
|
2273
|
+
const e = this.sourceType === "camera", i = this.depthModel;
|
|
2255
2274
|
try {
|
|
2256
|
-
let
|
|
2275
|
+
let n, r, o = null;
|
|
2257
2276
|
const l = (m) => {
|
|
2258
2277
|
this.emit("layershift-effect:model-progress", m);
|
|
2259
2278
|
};
|
|
2260
2279
|
if (e) {
|
|
2261
|
-
if (
|
|
2280
|
+
if (n = await Nt(
|
|
2262
2281
|
{ video: { facingMode: "user" } },
|
|
2263
2282
|
{ parent: this.shadow }
|
|
2264
2283
|
), t.aborted) {
|
|
2265
|
-
|
|
2284
|
+
n.dispose();
|
|
2266
2285
|
return;
|
|
2267
2286
|
}
|
|
2268
|
-
if (
|
|
2269
|
-
if (o = await dt(
|
|
2270
|
-
o.dispose(),
|
|
2287
|
+
if (i) {
|
|
2288
|
+
if (o = await dt(i, $, K, l), t.aborted) {
|
|
2289
|
+
o.dispose(), n.dispose();
|
|
2271
2290
|
return;
|
|
2272
2291
|
}
|
|
2273
2292
|
r = X($, K);
|
|
2274
2293
|
} else
|
|
2275
|
-
r = X(
|
|
2294
|
+
r = X(n.width, n.height);
|
|
2276
2295
|
} else {
|
|
2277
|
-
const m = this.getAttribute("src"), T = this.getAttribute("
|
|
2296
|
+
const m = this.getAttribute("src"), T = this.getAttribute("map-src"), w = !!T, A = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(m);
|
|
2278
2297
|
if (w) {
|
|
2279
2298
|
const [P, F] = await Promise.all([
|
|
2280
2299
|
A ? ft(m) : ht(m, {
|
|
@@ -2284,31 +2303,31 @@ class xt extends HTMLElement {
|
|
|
2284
2303
|
}),
|
|
2285
2304
|
kt(
|
|
2286
2305
|
T,
|
|
2287
|
-
this.getAttrFloat("
|
|
2288
|
-
this.getAttrFloat("
|
|
2289
|
-
this.getAttrFloat("
|
|
2306
|
+
this.getAttrFloat("map-width", 512),
|
|
2307
|
+
this.getAttrFloat("map-height", 512),
|
|
2308
|
+
this.getAttrFloat("map-fps", 5)
|
|
2290
2309
|
)
|
|
2291
2310
|
]);
|
|
2292
2311
|
if (t.aborted) {
|
|
2293
2312
|
P.dispose();
|
|
2294
2313
|
return;
|
|
2295
2314
|
}
|
|
2296
|
-
|
|
2297
|
-
} else if (
|
|
2315
|
+
n = P, r = F;
|
|
2316
|
+
} else if (i) {
|
|
2298
2317
|
const [P, F] = await Promise.all([
|
|
2299
2318
|
A ? ft(m) : ht(m, {
|
|
2300
2319
|
parent: this.shadow,
|
|
2301
2320
|
loop: this.shouldLoop,
|
|
2302
2321
|
muted: this.shouldMute
|
|
2303
2322
|
}),
|
|
2304
|
-
dt(
|
|
2323
|
+
dt(i, $, K, l)
|
|
2305
2324
|
]);
|
|
2306
2325
|
if (t.aborted) {
|
|
2307
2326
|
P.dispose(), F.dispose();
|
|
2308
2327
|
return;
|
|
2309
2328
|
}
|
|
2310
|
-
if (
|
|
2311
|
-
const _ =
|
|
2329
|
+
if (n = P, o = F, A || !n.isLive) {
|
|
2330
|
+
const _ = n.getImageSource();
|
|
2312
2331
|
if (_) {
|
|
2313
2332
|
const I = await o.submitFrameAndWait(_);
|
|
2314
2333
|
r = {
|
|
@@ -2323,9 +2342,9 @@ class xt extends HTMLElement {
|
|
|
2323
2342
|
} else
|
|
2324
2343
|
r = X($, K);
|
|
2325
2344
|
} else
|
|
2326
|
-
throw new Error("Either
|
|
2345
|
+
throw new Error("Either map-src or depth-model must be provided.");
|
|
2327
2346
|
}
|
|
2328
|
-
this.source =
|
|
2347
|
+
this.source = n, this.depthEstimator = o, this.loopCount = 0, this.attachSourceEventListeners(n);
|
|
2329
2348
|
const a = re(
|
|
2330
2349
|
r.frames,
|
|
2331
2350
|
r.width,
|
|
@@ -2374,8 +2393,8 @@ class xt extends HTMLElement {
|
|
|
2374
2393
|
tiltPeakIntensity: m.tiltPeakIntensity
|
|
2375
2394
|
}, u = Lt(p.channels), x = p.motion;
|
|
2376
2395
|
} else
|
|
2377
|
-
f = this.buildLegacyConfig(h,
|
|
2378
|
-
this.renderer = new ye(this.container, f), this.renderer.initialize(
|
|
2396
|
+
f = this.buildLegacyConfig(h, n.width);
|
|
2397
|
+
this.renderer = new ye(this.container, f), this.renderer.initialize(n, r.width, r.height), u && this.renderer.updateCurveLUTs(
|
|
2379
2398
|
u.displacementLUT,
|
|
2380
2399
|
u.blurLUT,
|
|
2381
2400
|
u.glowLUT,
|
|
@@ -2384,7 +2403,7 @@ class xt extends HTMLElement {
|
|
|
2384
2403
|
);
|
|
2385
2404
|
const d = x.tiltPlaneInput ?? !1, y = x.tiltPitchSensitivity ?? 0.35, b = x.tiltYawSensitivity ?? 0.15, g = p?.channels.find((m) => m.channel === "blur" && m.enabled)?.params?.focalCenter ?? 0.5, v = o;
|
|
2386
2405
|
if (this.renderer.start(
|
|
2387
|
-
|
|
2406
|
+
n,
|
|
2388
2407
|
c,
|
|
2389
2408
|
() => {
|
|
2390
2409
|
const m = this._input;
|
|
@@ -2401,7 +2420,7 @@ class xt extends HTMLElement {
|
|
|
2401
2420
|
},
|
|
2402
2421
|
(m, T) => {
|
|
2403
2422
|
if (v) {
|
|
2404
|
-
const w =
|
|
2423
|
+
const w = n.getImageSource();
|
|
2405
2424
|
w && v.submitFrame(w);
|
|
2406
2425
|
}
|
|
2407
2426
|
this.emit("layershift-effect:frame", {
|
|
@@ -2409,23 +2428,53 @@ class xt extends HTMLElement {
|
|
|
2409
2428
|
frameNumber: T
|
|
2410
2429
|
});
|
|
2411
2430
|
}
|
|
2412
|
-
), !e &&
|
|
2431
|
+
), !e && n.isLive && this.shouldAutoplay && n.play)
|
|
2413
2432
|
try {
|
|
2414
|
-
await
|
|
2433
|
+
await n.play();
|
|
2415
2434
|
} catch {
|
|
2416
2435
|
}
|
|
2417
2436
|
if (t.aborted) return;
|
|
2418
2437
|
this.lifecycle.markInitialized(), this.emit("layershift-effect:ready", {
|
|
2419
|
-
videoWidth:
|
|
2420
|
-
videoHeight:
|
|
2421
|
-
duration:
|
|
2438
|
+
videoWidth: n.width,
|
|
2439
|
+
videoHeight: n.height,
|
|
2440
|
+
duration: n.duration,
|
|
2422
2441
|
depthProfile: a,
|
|
2423
2442
|
derivedParams: h,
|
|
2424
2443
|
motionConfig: x
|
|
2425
2444
|
});
|
|
2426
|
-
} catch (
|
|
2427
|
-
const r =
|
|
2428
|
-
console.error("<layershift-effect>: Failed to initialize.",
|
|
2445
|
+
} catch (n) {
|
|
2446
|
+
const r = n instanceof Error ? n.message : "Failed to initialize.";
|
|
2447
|
+
console.error("<layershift-effect>: Failed to initialize.", n), this.emit("layershift-effect:error", { message: r });
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
// --- Playback control ---
|
|
2451
|
+
/** Whether the effect is currently paused. */
|
|
2452
|
+
get paused() {
|
|
2453
|
+
return this.renderer ? this.renderer.isPaused : this.source?.paused ?? !0;
|
|
2454
|
+
}
|
|
2455
|
+
/**
|
|
2456
|
+
* Pause the effect: stops the renderer animation loop and pauses the
|
|
2457
|
+
* underlying media source. Dispatches a `layershift-effect:pause` event.
|
|
2458
|
+
*/
|
|
2459
|
+
pause() {
|
|
2460
|
+
!this.renderer || this.paused || (this.renderer.pause(), this.source?.pause?.(), this.emit("layershift-effect:pause", {
|
|
2461
|
+
currentTime: this.source?.currentTime ?? 0
|
|
2462
|
+
}));
|
|
2463
|
+
}
|
|
2464
|
+
/**
|
|
2465
|
+
* Resume the effect: restarts the renderer animation loop and plays the
|
|
2466
|
+
* underlying media source. Dispatches a `layershift-effect:play` event.
|
|
2467
|
+
*/
|
|
2468
|
+
async play() {
|
|
2469
|
+
if (!(!this.renderer || !this.paused)) {
|
|
2470
|
+
if (this.renderer.resume(), this.source?.play)
|
|
2471
|
+
try {
|
|
2472
|
+
await this.source.play();
|
|
2473
|
+
} catch {
|
|
2474
|
+
}
|
|
2475
|
+
this.emit("layershift-effect:play", {
|
|
2476
|
+
currentTime: this.source?.currentTime ?? 0
|
|
2477
|
+
});
|
|
2429
2478
|
}
|
|
2430
2479
|
}
|
|
2431
2480
|
// --- Live config updates ---
|
|
@@ -2444,15 +2493,15 @@ class xt extends HTMLElement {
|
|
|
2444
2493
|
contrastLow: 0.05,
|
|
2445
2494
|
contrastHigh: 0.95,
|
|
2446
2495
|
verticalReduction: 0.5
|
|
2447
|
-
},
|
|
2448
|
-
this.renderer.updateConfig(
|
|
2449
|
-
const
|
|
2496
|
+
}, i = Ut(t, e);
|
|
2497
|
+
this.renderer.updateConfig(i);
|
|
2498
|
+
const n = Lt(t);
|
|
2450
2499
|
this.renderer.updateCurveLUTs(
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2500
|
+
n.displacementLUT,
|
|
2501
|
+
n.blurLUT,
|
|
2502
|
+
n.glowLUT,
|
|
2503
|
+
n.colorShiftLUT,
|
|
2504
|
+
n.colorShiftParams ?? void 0
|
|
2456
2505
|
);
|
|
2457
2506
|
}
|
|
2458
2507
|
// --- Cleanup ---
|
|
@@ -2505,18 +2554,18 @@ class Rt {
|
|
|
2505
2554
|
* Create (or recreate) all JFA FBO/texture resources at the given canvas
|
|
2506
2555
|
* dimensions, divided by the quality tier's JFA divisor.
|
|
2507
2556
|
*/
|
|
2508
|
-
createResources(t, e,
|
|
2509
|
-
const
|
|
2557
|
+
createResources(t, e, i) {
|
|
2558
|
+
const n = this.gl;
|
|
2510
2559
|
this.dispose();
|
|
2511
|
-
const r = Math.max(1, Math.round(t /
|
|
2560
|
+
const r = Math.max(1, Math.round(t / i)), o = Math.max(1, Math.round(e / i));
|
|
2512
2561
|
this._width = r, this._height = o;
|
|
2513
2562
|
const l = (h, c, f, u) => {
|
|
2514
|
-
const x =
|
|
2515
|
-
return
|
|
2563
|
+
const x = n.createFramebuffer();
|
|
2564
|
+
return n.bindFramebuffer(n.FRAMEBUFFER, x), n.bindTexture(n.TEXTURE_2D, h), n.texStorage2D(n.TEXTURE_2D, 1, c, f, u), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, h, 0), n.bindFramebuffer(n.FRAMEBUFFER, null), x;
|
|
2516
2565
|
};
|
|
2517
|
-
this.maskTex =
|
|
2518
|
-
const a = this.hasColorBufferFloat ?
|
|
2519
|
-
this.pingTex =
|
|
2566
|
+
this.maskTex = n.createTexture(), this.maskFbo = l(this.maskTex, n.R8, r, o);
|
|
2567
|
+
const a = this.hasColorBufferFloat ? n.RG16F : n.RGBA8;
|
|
2568
|
+
this.pingTex = n.createTexture(), this.pingFbo = l(this.pingTex, a, r, o), this.pongTex = n.createTexture(), this.pongFbo = l(this.pongTex, a, r, o), this.distTex = n.createTexture(), this.distFbo = l(this.distTex, n.RGBA8, r, o), this._dirty = !0;
|
|
2520
2569
|
}
|
|
2521
2570
|
// -----------------------------------------------------------------------
|
|
2522
2571
|
// Distance field computation
|
|
@@ -2532,14 +2581,14 @@ class Rt {
|
|
|
2532
2581
|
compute(t) {
|
|
2533
2582
|
const e = this.gl;
|
|
2534
2583
|
if (!this.maskFbo || !this.pingFbo || !this.pongFbo || !this.distFbo) return;
|
|
2535
|
-
const
|
|
2536
|
-
if (
|
|
2537
|
-
e.viewport(0, 0,
|
|
2538
|
-
const r = Rt.computeFloodIterations(
|
|
2584
|
+
const i = this._width, n = this._height;
|
|
2585
|
+
if (i === 0 || n === 0) return;
|
|
2586
|
+
e.viewport(0, 0, i, n), e.disable(e.STENCIL_TEST), e.disable(e.BLEND), e.bindFramebuffer(e.FRAMEBUFFER, this.maskFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.maskPass.program), e.uniform2f(t.maskPass.uniforms.uMeshScale, t.meshScaleX, t.meshScaleY), e.bindVertexArray(t.maskVao), e.drawElements(e.TRIANGLES, t.stencilIndexCount, e.UNSIGNED_SHORT, 0), e.bindFramebuffer(e.FRAMEBUFFER, this.pingFbo), e.clearColor(-1, -1, 0, 0), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.seedPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, this.maskTex), e.uniform1i(t.seedPass.uniforms.uMask, 5), e.uniform2f(t.seedPass.uniforms.uTexelSize, 1 / i, 1 / n), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
|
|
2587
|
+
const r = Rt.computeFloodIterations(i, n);
|
|
2539
2588
|
e.useProgram(t.floodPass.program);
|
|
2540
2589
|
let o = this.pingTex, l = this.pongFbo, a = this.pongTex;
|
|
2541
2590
|
for (let h = 0; h < r.length; h++) {
|
|
2542
|
-
const c = r[h] / Math.max(
|
|
2591
|
+
const c = r[h] / Math.max(i, n);
|
|
2543
2592
|
e.bindFramebuffer(e.FRAMEBUFFER, l), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, o), e.uniform1i(t.floodPass.uniforms.uSeedTex, 5), e.uniform1f(t.floodPass.uniforms.uStepSize, c), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
|
|
2544
2593
|
const f = o, u = l;
|
|
2545
2594
|
o = a, l = u === this.pongFbo ? this.pingFbo : this.pongFbo, a = f;
|
|
@@ -2554,11 +2603,11 @@ class Rt {
|
|
|
2554
2603
|
* Steps halve from ceil(maxDim/2) down to 1.
|
|
2555
2604
|
*/
|
|
2556
2605
|
static computeFloodIterations(t, e) {
|
|
2557
|
-
const
|
|
2558
|
-
let r = Math.ceil(
|
|
2606
|
+
const i = Math.max(t, e), n = [];
|
|
2607
|
+
let r = Math.ceil(i / 2);
|
|
2559
2608
|
for (; r >= 1; )
|
|
2560
|
-
|
|
2561
|
-
return
|
|
2609
|
+
n.push(r), r = Math.floor(r / 2);
|
|
2610
|
+
return n;
|
|
2562
2611
|
}
|
|
2563
2612
|
// -----------------------------------------------------------------------
|
|
2564
2613
|
// Cleanup
|
|
@@ -3080,16 +3129,16 @@ void main() {
|
|
|
3080
3129
|
function je(s) {
|
|
3081
3130
|
const t = [];
|
|
3082
3131
|
let e = 0;
|
|
3083
|
-
for (let
|
|
3084
|
-
const
|
|
3132
|
+
for (let i = 0; i < s.length - 2; i += 2) {
|
|
3133
|
+
const n = s[i], r = s[i + 1], o = s[i + 2], l = s[i + 3], a = o - n, h = l - r, c = Math.sqrt(a * a + h * h);
|
|
3085
3134
|
if (c < 1e-6) continue;
|
|
3086
3135
|
const f = -h / c, u = a / c;
|
|
3087
3136
|
t.push(
|
|
3088
|
-
|
|
3137
|
+
n,
|
|
3089
3138
|
r,
|
|
3090
3139
|
f,
|
|
3091
3140
|
u,
|
|
3092
|
-
|
|
3141
|
+
n,
|
|
3093
3142
|
r,
|
|
3094
3143
|
-f,
|
|
3095
3144
|
-u,
|
|
@@ -3101,7 +3150,7 @@ function je(s) {
|
|
|
3101
3150
|
l,
|
|
3102
3151
|
f,
|
|
3103
3152
|
u,
|
|
3104
|
-
|
|
3153
|
+
n,
|
|
3105
3154
|
r,
|
|
3106
3155
|
-f,
|
|
3107
3156
|
-u,
|
|
@@ -3116,10 +3165,10 @@ function je(s) {
|
|
|
3116
3165
|
count: e
|
|
3117
3166
|
};
|
|
3118
3167
|
}
|
|
3119
|
-
function Ze(s, t, e,
|
|
3120
|
-
if (
|
|
3168
|
+
function Ze(s, t, e, i, n) {
|
|
3169
|
+
if (i <= 0)
|
|
3121
3170
|
return { vertices: new Float32Array(0), count: 0 };
|
|
3122
|
-
const r =
|
|
3171
|
+
const r = n * Math.PI / 180, o = -Math.cos(r), l = Math.sin(r), a = [];
|
|
3123
3172
|
let h = 0;
|
|
3124
3173
|
for (let c = 0; c < t.length; c++) {
|
|
3125
3174
|
const f = t[c], p = ((c + 1 < t.length ? t[c + 1] : s.length) - f) / 2;
|
|
@@ -3143,7 +3192,7 @@ function Ze(s, t, e, n, i) {
|
|
|
3143
3192
|
F > 1e-8 ? (A /= F, P /= F) : (A = E[T], P = g[T]), v.push(A), m.push(P);
|
|
3144
3193
|
}
|
|
3145
3194
|
for (let T = 0; T < d; T++) {
|
|
3146
|
-
const w = T, A = (T + 1) % d, P = f + T * 2, F = f + (T + 1) % d * 2, _ = s[P], I = s[P + 1], C = s[F], S = s[F + 1], D = v[w] * l, U = m[w] * l, M = o, k = v[A] * l, j = m[A] * l, et = o, at = _ + v[w] *
|
|
3195
|
+
const w = T, A = (T + 1) % d, P = f + T * 2, F = f + (T + 1) % d * 2, _ = s[P], I = s[P + 1], C = s[F], S = s[F + 1], D = v[w] * l, U = m[w] * l, M = o, k = v[A] * l, j = m[A] * l, et = o, at = _ + v[w] * i, At = I + m[w] * i, Jt = C + v[A] * i, Qt = S + m[A] * i;
|
|
3147
3196
|
a.push(_, I, D, U, M, 0), a.push(at, At, D, U, M, 1), a.push(C, S, k, j, et, 0), a.push(C, S, k, j, et, 0), a.push(at, At, D, U, M, 1), a.push(Jt, Qt, k, j, et, 1), h += 6;
|
|
3148
3197
|
}
|
|
3149
3198
|
}
|
|
@@ -3197,10 +3246,10 @@ class $e extends gt {
|
|
|
3197
3246
|
config;
|
|
3198
3247
|
constructor(t, e) {
|
|
3199
3248
|
super(t), this.config = { ...e }, this.videoSlot = this.textures.register("video"), this.depthSlot = this.textures.register("depth");
|
|
3200
|
-
const
|
|
3201
|
-
this.lightDirX = Math.cos(
|
|
3202
|
-
const
|
|
3203
|
-
r > 1e-6 && (this.lightDir3 = [
|
|
3249
|
+
const i = this.config.bevelLightAngle * Math.PI / 180;
|
|
3250
|
+
this.lightDirX = Math.cos(i), this.lightDirY = Math.sin(i);
|
|
3251
|
+
const n = this.config.lightDirection, r = Math.sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
|
|
3252
|
+
r > 1e-6 && (this.lightDir3 = [n[0] / r, n[1] / r, n[2] / r]);
|
|
3204
3253
|
const o = this.canvas.getContext("webgl2", {
|
|
3205
3254
|
antialias: !0,
|
|
3206
3255
|
alpha: !0,
|
|
@@ -3212,9 +3261,9 @@ class $e extends gt {
|
|
|
3212
3261
|
if (!o) throw new Error("WebGL 2 is not supported.");
|
|
3213
3262
|
this.gl = o, this.qualityParams = Xt(o, e.quality), "drawingBufferColorSpace" in o && (o.drawingBufferColorSpace = "srgb"), this.hasColorBufferFloat = !!o.getExtension("EXT_color_buffer_float"), o.clearColor(0, 0, 0, 0), o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
|
|
3214
3263
|
}
|
|
3215
|
-
initialize(t, e,
|
|
3264
|
+
initialize(t, e, i, n) {
|
|
3216
3265
|
const r = this.gl;
|
|
3217
|
-
r && (this.disposeTextures(), this.disposeFBO(), this.jfa && (this.jfa.dispose(), this.jfa = null), this.disposeStencilGeometry(), this.disposeBoundaryGeometry(), this.disposeChamferGeometry(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.meshAspect =
|
|
3266
|
+
r && (this.disposeTextures(), this.disposeFBO(), this.jfa && (this.jfa.dispose(), this.jfa = null), this.disposeStencilGeometry(), this.disposeBoundaryGeometry(), this.disposeChamferGeometry(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.meshAspect = n.aspect, this.clampDepthDimensions(e, i, this.qualityParams.depthMaxDim), this.videoSlot.texture = r.createTexture(), r.activeTexture(r.TEXTURE0 + this.videoSlot.unit), r.bindTexture(r.TEXTURE_2D, this.videoSlot.texture), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MIN_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MAG_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_S, r.CLAMP_TO_EDGE), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_T, r.CLAMP_TO_EDGE), this.depthSlot.texture = r.createTexture(), r.activeTexture(r.TEXTURE0 + this.depthSlot.unit), r.bindTexture(r.TEXTURE_2D, this.depthSlot.texture), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MIN_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MAG_FILTER, r.LINEAR), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_S, r.CLAMP_TO_EDGE), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_T, r.CLAMP_TO_EDGE), r.texStorage2D(r.TEXTURE_2D, 1, r.R8, this.depthWidth, this.depthHeight), this.uploadStencilMesh(n), this.uploadMaskMesh(n), this.uploadBoundaryMesh(n), this.uploadChamferMesh(n), this.interiorPass && (r.useProgram(this.interiorPass.program), r.uniform1i(this.interiorPass.uniforms.uImage, 0), r.uniform1i(this.interiorPass.uniforms.uDepth, 1), r.uniform1f(this.interiorPass.uniforms.uStrength, this.config.parallaxStrength), r.uniform1i(this.interiorPass.uniforms.uPomSteps, this.config.pomSteps), r.uniform1f(this.interiorPass.uniforms.uDepthPower, this.config.depthPower), r.uniform1f(this.interiorPass.uniforms.uDepthScale, this.config.depthScale), r.uniform1f(this.interiorPass.uniforms.uDepthBias, this.config.depthBias), r.uniform1f(this.interiorPass.uniforms.uContrastLow, this.config.contrastLow), r.uniform1f(this.interiorPass.uniforms.uContrastHigh, this.config.contrastHigh), r.uniform1f(this.interiorPass.uniforms.uVerticalReduction, this.config.verticalReduction), r.uniform1f(this.interiorPass.uniforms.uDofStart, this.config.dofStart), r.uniform1f(this.interiorPass.uniforms.uDofStrength, this.config.dofStrength), r.uniform2f(this.interiorPass.uniforms.uImageTexelSize, 1 / t.width, 1 / t.height), r.uniform1f(this.interiorPass.uniforms.uFogDensity, this.config.fogDensity), r.uniform3f(this.interiorPass.uniforms.uFogColor, ...this.config.fogColor), r.uniform1f(this.interiorPass.uniforms.uColorShift, this.config.colorShift), r.uniform1f(this.interiorPass.uniforms.uBrightnessBias, this.config.brightnessBias)), this.compositePass && (r.useProgram(this.compositePass.program), r.uniform1i(this.compositePass.uniforms.uInteriorColor, 2), r.uniform1i(this.compositePass.uniforms.uDistField, 4), r.uniform1f(this.compositePass.uniforms.uEdgeOcclusionWidth, this.config.edgeOcclusionWidth), r.uniform1f(this.compositePass.uniforms.uEdgeOcclusionStrength, this.config.edgeOcclusionStrength)), this.chamferPass && (r.useProgram(this.chamferPass.program), r.uniform3f(this.chamferPass.uniforms.uLightDir3, ...this.lightDir3), r.uniform3f(this.chamferPass.uniforms.uChamferColor, ...this.config.chamferColor), r.uniform1f(this.chamferPass.uniforms.uChamferAmbient, this.config.chamferAmbient), r.uniform1f(this.chamferPass.uniforms.uChamferSpecular, this.config.chamferSpecular), r.uniform1f(this.chamferPass.uniforms.uChamferShininess, this.config.chamferShininess), r.uniform1i(this.chamferPass.uniforms.uInteriorColor, 2)), this.boundaryPass && (r.useProgram(this.boundaryPass.program), r.uniform1i(this.boundaryPass.uniforms.uInteriorColor, 2), r.uniform1i(this.boundaryPass.uniforms.uInteriorDepth, 3), r.uniform1i(this.boundaryPass.uniforms.uDistField, 4), r.uniform1f(this.boundaryPass.uniforms.uRimIntensity, this.config.rimLightIntensity), r.uniform3f(this.boundaryPass.uniforms.uRimColor, ...this.config.rimLightColor), r.uniform1f(this.boundaryPass.uniforms.uRefractionStrength, this.config.refractionStrength), r.uniform1f(this.boundaryPass.uniforms.uChromaticStrength, this.config.chromaticStrength), r.uniform1f(this.boundaryPass.uniforms.uOcclusionIntensity, this.config.occlusionIntensity), r.uniform1f(this.boundaryPass.uniforms.uEdgeThickness, this.config.edgeThickness), r.uniform1f(this.boundaryPass.uniforms.uEdgeSpecular, this.config.edgeSpecular), r.uniform3f(this.boundaryPass.uniforms.uEdgeColor, ...this.config.edgeColor), r.uniform2f(this.boundaryPass.uniforms.uLightDir, this.lightDirX, this.lightDirY), r.uniform1f(this.boundaryPass.uniforms.uBevelIntensity, this.config.bevelIntensity)), this.recalculateViewportLayout());
|
|
3218
3267
|
}
|
|
3219
3268
|
// -----------------------------------------------------------------------
|
|
3220
3269
|
// Geometry upload
|
|
@@ -3223,10 +3272,10 @@ class $e extends gt {
|
|
|
3223
3272
|
const e = this.gl;
|
|
3224
3273
|
if (!e || !this.stencilPass) return;
|
|
3225
3274
|
this.stencilVao = e.createVertexArray(), e.bindVertexArray(this.stencilVao);
|
|
3226
|
-
const
|
|
3227
|
-
e.bindBuffer(e.ARRAY_BUFFER,
|
|
3228
|
-
const
|
|
3229
|
-
e.enableVertexAttribArray(
|
|
3275
|
+
const i = e.createBuffer();
|
|
3276
|
+
e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, t.vertices, e.STATIC_DRAW);
|
|
3277
|
+
const n = e.getAttribLocation(this.stencilPass.program, "aPosition");
|
|
3278
|
+
e.enableVertexAttribArray(n), e.vertexAttribPointer(n, 2, e.FLOAT, !1, 0, 0);
|
|
3230
3279
|
const r = e.createBuffer();
|
|
3231
3280
|
e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, r), e.bufferData(e.ELEMENT_ARRAY_BUFFER, t.indices, e.STATIC_DRAW), this.stencilIndexCount = t.indices.length, e.bindVertexArray(null);
|
|
3232
3281
|
}
|
|
@@ -3234,46 +3283,46 @@ class $e extends gt {
|
|
|
3234
3283
|
const e = this.gl;
|
|
3235
3284
|
if (!e || !this.maskPass) return;
|
|
3236
3285
|
this.maskVao = e.createVertexArray(), e.bindVertexArray(this.maskVao);
|
|
3237
|
-
const
|
|
3238
|
-
e.bindBuffer(e.ARRAY_BUFFER,
|
|
3239
|
-
const
|
|
3240
|
-
e.enableVertexAttribArray(
|
|
3286
|
+
const i = e.createBuffer();
|
|
3287
|
+
e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, t.vertices, e.STATIC_DRAW);
|
|
3288
|
+
const n = e.getAttribLocation(this.maskPass.program, "aPosition");
|
|
3289
|
+
e.enableVertexAttribArray(n), e.vertexAttribPointer(n, 2, e.FLOAT, !1, 0, 0);
|
|
3241
3290
|
const r = e.createBuffer();
|
|
3242
3291
|
e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, r), e.bufferData(e.ELEMENT_ARRAY_BUFFER, t.indices, e.STATIC_DRAW), e.bindVertexArray(null);
|
|
3243
3292
|
}
|
|
3244
3293
|
uploadBoundaryMesh(t) {
|
|
3245
3294
|
const e = this.gl;
|
|
3246
3295
|
if (!e || !this.boundaryPass) return;
|
|
3247
|
-
const
|
|
3248
|
-
if (
|
|
3296
|
+
const i = je(t.edgeVertices);
|
|
3297
|
+
if (i.count === 0) return;
|
|
3249
3298
|
this.boundaryVao = e.createVertexArray(), e.bindVertexArray(this.boundaryVao);
|
|
3250
|
-
const
|
|
3251
|
-
e.bindBuffer(e.ARRAY_BUFFER,
|
|
3299
|
+
const n = e.createBuffer();
|
|
3300
|
+
e.bindBuffer(e.ARRAY_BUFFER, n), e.bufferData(e.ARRAY_BUFFER, i.vertices, e.STATIC_DRAW);
|
|
3252
3301
|
const r = 16, o = e.getAttribLocation(this.boundaryPass.program, "aPosition");
|
|
3253
3302
|
e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
|
|
3254
3303
|
const l = e.getAttribLocation(this.boundaryPass.program, "aNormal");
|
|
3255
|
-
l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 2, e.FLOAT, !1, r, 8)), this.boundaryVertexCount =
|
|
3304
|
+
l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 2, e.FLOAT, !1, r, 8)), this.boundaryVertexCount = i.count, e.bindVertexArray(null);
|
|
3256
3305
|
}
|
|
3257
3306
|
uploadChamferMesh(t) {
|
|
3258
3307
|
const e = this.gl;
|
|
3259
3308
|
if (!e || !this.chamferPass || this.config.chamferWidth <= 0) return;
|
|
3260
|
-
const
|
|
3309
|
+
const i = Ze(
|
|
3261
3310
|
t.edgeVertices,
|
|
3262
3311
|
t.contourOffsets,
|
|
3263
3312
|
t.contourIsHole,
|
|
3264
3313
|
this.config.chamferWidth,
|
|
3265
3314
|
this.config.chamferAngle
|
|
3266
3315
|
);
|
|
3267
|
-
if (
|
|
3316
|
+
if (i.count === 0) return;
|
|
3268
3317
|
this.chamferVao = e.createVertexArray(), e.bindVertexArray(this.chamferVao);
|
|
3269
|
-
const
|
|
3270
|
-
e.bindBuffer(e.ARRAY_BUFFER,
|
|
3318
|
+
const n = e.createBuffer();
|
|
3319
|
+
e.bindBuffer(e.ARRAY_BUFFER, n), e.bufferData(e.ARRAY_BUFFER, i.vertices, e.STATIC_DRAW);
|
|
3271
3320
|
const r = 24, o = e.getAttribLocation(this.chamferPass.program, "aPosition");
|
|
3272
3321
|
e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
|
|
3273
3322
|
const l = e.getAttribLocation(this.chamferPass.program, "aNormal3");
|
|
3274
3323
|
l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 3, e.FLOAT, !1, r, 8));
|
|
3275
3324
|
const a = e.getAttribLocation(this.chamferPass.program, "aLerpT");
|
|
3276
|
-
a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 1, e.FLOAT, !1, r, 20)), this.chamferVertexCount =
|
|
3325
|
+
a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 1, e.FLOAT, !1, r, 20)), this.chamferVertexCount = i.count, e.bindVertexArray(null);
|
|
3277
3326
|
}
|
|
3278
3327
|
disposeChamferGeometry() {
|
|
3279
3328
|
const t = this.gl;
|
|
@@ -3283,18 +3332,18 @@ class $e extends gt {
|
|
|
3283
3332
|
// FBO management
|
|
3284
3333
|
// -----------------------------------------------------------------------
|
|
3285
3334
|
createFBO(t, e) {
|
|
3286
|
-
const
|
|
3287
|
-
if (!
|
|
3288
|
-
this.disposeFBO(), this.fboWidth = t, this.fboHeight = e, this.interiorFbo =
|
|
3289
|
-
const
|
|
3290
|
-
|
|
3335
|
+
const i = this.gl;
|
|
3336
|
+
if (!i) return;
|
|
3337
|
+
this.disposeFBO(), this.fboWidth = t, this.fboHeight = e, this.interiorFbo = i.createFramebuffer(), i.bindFramebuffer(i.FRAMEBUFFER, this.interiorFbo), this.interiorColorTex = i.createTexture(), i.activeTexture(i.TEXTURE2), i.bindTexture(i.TEXTURE_2D, this.interiorColorTex), i.texStorage2D(i.TEXTURE_2D, 1, i.RGBA8, t, e), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, this.interiorColorTex, 0), this.interiorDepthTex = i.createTexture(), i.activeTexture(i.TEXTURE3), i.bindTexture(i.TEXTURE_2D, this.interiorDepthTex), i.texStorage2D(i.TEXTURE_2D, 1, i.RGBA8, t, e), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT1, i.TEXTURE_2D, this.interiorDepthTex, 0), i.drawBuffers([i.COLOR_ATTACHMENT0, i.COLOR_ATTACHMENT1]);
|
|
3338
|
+
const n = i.checkFramebufferStatus(i.FRAMEBUFFER);
|
|
3339
|
+
n !== i.FRAMEBUFFER_COMPLETE && console.error("Interior FBO incomplete:", n), i.bindFramebuffer(i.FRAMEBUFFER, null);
|
|
3291
3340
|
}
|
|
3292
3341
|
// -----------------------------------------------------------------------
|
|
3293
3342
|
// JFA Distance Field
|
|
3294
3343
|
// -----------------------------------------------------------------------
|
|
3295
3344
|
createJFAResources(t, e) {
|
|
3296
|
-
const
|
|
3297
|
-
|
|
3345
|
+
const i = this.gl;
|
|
3346
|
+
i && (this.jfa || (this.jfa = new Rt(i, this.hasColorBufferFloat)), this.jfa.createResources(t, e, this.qualityParams.jfaDivisor));
|
|
3298
3347
|
}
|
|
3299
3348
|
computeDistanceField() {
|
|
3300
3349
|
!this.jfa || !this.maskPass || !this.jfaSeedPass || !this.jfaFloodPass || !this.jfaDistPass || !this.maskVao || !this.quadVao || this.jfa.compute({
|
|
@@ -3381,23 +3430,23 @@ class $e extends gt {
|
|
|
3381
3430
|
onRenderFrame() {
|
|
3382
3431
|
const t = this.gl, e = this.mediaSource;
|
|
3383
3432
|
if (!t || !this.interiorPass || !this.quadVao) return;
|
|
3384
|
-
const
|
|
3385
|
-
if (!
|
|
3433
|
+
const i = e?.getImageSource();
|
|
3434
|
+
if (!i || !this.interiorFbo || !this.interiorColorTex || !this.interiorDepthTex) return;
|
|
3386
3435
|
if (this.jfa?.isDirty && this.maskVao) {
|
|
3387
3436
|
const o = this.qualityParams.jfaDivisor, l = Math.max(1, Math.round(this.canvas.width / o)), a = Math.max(1, Math.round(this.canvas.height / o));
|
|
3388
3437
|
(this.jfa.width !== l || this.jfa.height !== a) && this.createJFAResources(this.canvas.width, this.canvas.height), this.computeDistanceField(), t.viewport(0, 0, this.canvas.width, this.canvas.height);
|
|
3389
3438
|
}
|
|
3390
|
-
t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE,
|
|
3391
|
-
let
|
|
3439
|
+
t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, i), this.rvfcSupported || this.onDepthUpdate(e.currentTime);
|
|
3440
|
+
let n = 0, r = 0;
|
|
3392
3441
|
if (this.readInput) {
|
|
3393
3442
|
const o = this.readInput();
|
|
3394
|
-
|
|
3443
|
+
n = -o.x, r = o.y;
|
|
3395
3444
|
}
|
|
3396
3445
|
if (t.bindFramebuffer(t.FRAMEBUFFER, this.interiorFbo), t.checkFramebufferStatus(t.FRAMEBUFFER) !== t.FRAMEBUFFER_COMPLETE) {
|
|
3397
3446
|
t.bindFramebuffer(t.FRAMEBUFFER, null);
|
|
3398
3447
|
return;
|
|
3399
3448
|
}
|
|
3400
|
-
t.viewport(0, 0, this.fboWidth, this.fboHeight), t.clearColor(0, 0, 0, 1), t.clear(t.COLOR_BUFFER_BIT), t.useProgram(this.interiorPass.program), t.uniform2f(this.interiorPass.uniforms.uOffset,
|
|
3449
|
+
t.viewport(0, 0, this.fboWidth, this.fboHeight), t.clearColor(0, 0, 0, 1), t.clear(t.COLOR_BUFFER_BIT), t.useProgram(this.interiorPass.program), t.uniform2f(this.interiorPass.uniforms.uOffset, n, r), t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.activeTexture(t.TEXTURE0 + this.depthSlot.unit), t.bindTexture(t.TEXTURE_2D, this.depthSlot.texture), t.bindVertexArray(this.quadVao), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, null), t.clearColor(0, 0, 0, 0), t.viewport(0, 0, this.canvas.width, this.canvas.height), t.clear(t.COLOR_BUFFER_BIT | t.STENCIL_BUFFER_BIT), this.stencilVao && this.stencilPass && this.stencilIndexCount > 0 && (t.enable(t.STENCIL_TEST), t.stencilFunc(t.ALWAYS, 1, 255), t.stencilOp(t.KEEP, t.KEEP, t.REPLACE), t.stencilMask(255), t.colorMask(!1, !1, !1, !1), t.useProgram(this.stencilPass.program), t.bindVertexArray(this.stencilVao), t.drawElements(t.TRIANGLES, this.stencilIndexCount, t.UNSIGNED_SHORT, 0), t.colorMask(!0, !0, !0, !0)), t.stencilFunc(t.EQUAL, 1, 255), t.stencilMask(0), t.activeTexture(t.TEXTURE2), t.bindTexture(t.TEXTURE_2D, this.interiorColorTex), t.activeTexture(t.TEXTURE3), t.bindTexture(t.TEXTURE_2D, this.interiorDepthTex), t.activeTexture(t.TEXTURE4), t.bindTexture(t.TEXTURE_2D, this.jfa?.distanceTexture ?? null), t.useProgram(this.compositePass.program), t.bindVertexArray(this.quadVao), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.disable(t.STENCIL_TEST), this.chamferVao && this.chamferPass && this.chamferVertexCount > 0 && (t.useProgram(this.chamferPass.program), t.uniform2f(this.chamferPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY), t.uniform2f(this.chamferPass.uniforms.uTexelSize, 1 / this.canvas.width, 1 / this.canvas.height), t.bindVertexArray(this.chamferVao), t.drawArrays(t.TRIANGLES, 0, this.chamferVertexCount)), this.boundaryVao && this.boundaryPass && this.boundaryVertexCount > 0 && this.config.rimLightIntensity > 0 && (t.enable(t.BLEND), t.blendFunc(t.SRC_ALPHA, t.ONE_MINUS_SRC_ALPHA), t.useProgram(this.boundaryPass.program), t.bindVertexArray(this.boundaryVao), t.drawArrays(t.TRIANGLES, 0, this.boundaryVertexCount), t.disable(t.BLEND));
|
|
3401
3450
|
}
|
|
3402
3451
|
/**
|
|
3403
3452
|
* Upload depth data to the GPU texture.
|
|
@@ -3406,7 +3455,7 @@ class $e extends gt {
|
|
|
3406
3455
|
onDepthUpdate(t) {
|
|
3407
3456
|
const e = this.gl;
|
|
3408
3457
|
if (!e || !this.readDepth || !this.depthSlot.texture) return;
|
|
3409
|
-
const
|
|
3458
|
+
const i = this.subsampleDepth(this.readDepth(t));
|
|
3410
3459
|
e.activeTexture(e.TEXTURE0 + this.depthSlot.unit), e.bindTexture(e.TEXTURE_2D, this.depthSlot.texture), e.texSubImage2D(
|
|
3411
3460
|
e.TEXTURE_2D,
|
|
3412
3461
|
0,
|
|
@@ -3416,7 +3465,7 @@ class $e extends gt {
|
|
|
3416
3465
|
this.depthHeight,
|
|
3417
3466
|
e.RED,
|
|
3418
3467
|
e.UNSIGNED_BYTE,
|
|
3419
|
-
|
|
3468
|
+
i
|
|
3420
3469
|
), this.jfa && this.jfa.markDirty();
|
|
3421
3470
|
}
|
|
3422
3471
|
// -----------------------------------------------------------------------
|
|
@@ -3425,9 +3474,9 @@ class $e extends gt {
|
|
|
3425
3474
|
recalculateViewportLayout() {
|
|
3426
3475
|
const t = this.gl;
|
|
3427
3476
|
if (!t) return;
|
|
3428
|
-
const { width: e, height:
|
|
3477
|
+
const { width: e, height: i } = this.getViewportSize(), n = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * n), o = Math.round(i * n);
|
|
3429
3478
|
(this.canvas.width !== r || this.canvas.height !== o) && (this.canvas.width = r, this.canvas.height = o, t.viewport(0, 0, r, o)), (this.fboWidth !== r || this.fboHeight !== o) && this.createFBO(r, o), this.jfa || this.createJFAResources(r, o), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.interiorPass && (t.useProgram(this.interiorPass.program), t.uniform2f(this.interiorPass.uniforms.uUvOffset, this.uvOffset[0], this.uvOffset[1]), t.uniform2f(this.interiorPass.uniforms.uUvScale, this.uvScale[0], this.uvScale[1]));
|
|
3430
|
-
const l = e /
|
|
3479
|
+
const l = e / i, a = 0.65;
|
|
3431
3480
|
this.meshScaleX = a, this.meshScaleY = a, l > this.meshAspect ? this.meshScaleX = a * (this.meshAspect / l) : this.meshScaleY = a * (l / this.meshAspect), this.stencilPass && (t.useProgram(this.stencilPass.program), t.uniform2f(this.stencilPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY)), this.boundaryPass && (t.useProgram(this.boundaryPass.program), t.uniform2f(this.boundaryPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY), t.uniform1f(this.boundaryPass.uniforms.uRimWidth, this.config.rimLightWidth), t.uniform2f(this.boundaryPass.uniforms.uTexelSize, 1 / r, 1 / o)), this.chamferPass && (t.useProgram(this.chamferPass.program), t.uniform2f(this.chamferPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY));
|
|
3432
3481
|
}
|
|
3433
3482
|
// -----------------------------------------------------------------------
|
|
@@ -3481,8 +3530,8 @@ class $e extends gt {
|
|
|
3481
3530
|
this.boundaryPass,
|
|
3482
3531
|
this.chamferPass
|
|
3483
3532
|
];
|
|
3484
|
-
for (const
|
|
3485
|
-
|
|
3533
|
+
for (const i of e)
|
|
3534
|
+
i && i.dispose(t);
|
|
3486
3535
|
this.stencilPass = null, this.maskPass = null, this.jfaSeedPass = null, this.jfaFloodPass = null, this.jfaDistPass = null, this.interiorPass = null, this.compositePass = null, this.boundaryPass = null, this.chamferPass = null, this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null);
|
|
3487
3536
|
}
|
|
3488
3537
|
}
|
|
@@ -3494,24 +3543,24 @@ async function Tt(s) {
|
|
|
3494
3543
|
return Ke(e);
|
|
3495
3544
|
}
|
|
3496
3545
|
function Ke(s) {
|
|
3497
|
-
const
|
|
3498
|
-
if (!
|
|
3546
|
+
const i = new DOMParser().parseFromString(s, "image/svg+xml").querySelector("svg");
|
|
3547
|
+
if (!i)
|
|
3499
3548
|
throw new Error("No <svg> element found in document.");
|
|
3500
|
-
const
|
|
3501
|
-
if (
|
|
3549
|
+
const n = Je(i);
|
|
3550
|
+
if (n.length === 0)
|
|
3502
3551
|
throw new Error("No path data found in SVG.");
|
|
3503
3552
|
let r = 1 / 0, o = 1 / 0, l = -1 / 0, a = -1 / 0;
|
|
3504
|
-
for (const C of
|
|
3553
|
+
for (const C of n)
|
|
3505
3554
|
for (let S = 0; S < C.length; S += 2)
|
|
3506
3555
|
r = Math.min(r, C[S]), l = Math.max(l, C[S]), o = Math.min(o, C[S + 1]), a = Math.max(a, C[S + 1]);
|
|
3507
|
-
const h = l - r, c = a - o, f = (r + l) / 2, u = (o + a) / 2, x = 2 / Math.max(h, c), p = h / c, d =
|
|
3556
|
+
const h = l - r, c = a - o, f = (r + l) / 2, u = (o + a) / 2, x = 2 / Math.max(h, c), p = h / c, d = n.map((C) => {
|
|
3508
3557
|
const S = [];
|
|
3509
3558
|
for (let D = 0; D < C.length; D += 2)
|
|
3510
3559
|
S.push((C[D] - f) * x), S.push(-((C[D + 1] - u) * x));
|
|
3511
3560
|
return S;
|
|
3512
|
-
}), y =
|
|
3561
|
+
}), y = oi(d), b = [], E = [];
|
|
3513
3562
|
for (const C of y) {
|
|
3514
|
-
const { flatCoords: S, holeIndices: D } =
|
|
3563
|
+
const { flatCoords: S, holeIndices: D } = si(C), U = ai(S, D), M = b.length / 2;
|
|
3515
3564
|
for (const k of U)
|
|
3516
3565
|
E.push(k + M);
|
|
3517
3566
|
for (const k of S)
|
|
@@ -3543,7 +3592,7 @@ function Je(s) {
|
|
|
3543
3592
|
return s.querySelectorAll("path").forEach((a) => {
|
|
3544
3593
|
const h = a.getAttribute("d");
|
|
3545
3594
|
if (!h) return;
|
|
3546
|
-
const c =
|
|
3595
|
+
const c = ei(h);
|
|
3547
3596
|
t.push(...c);
|
|
3548
3597
|
}), s.querySelectorAll("polygon").forEach((a) => {
|
|
3549
3598
|
const h = a.getAttribute("points");
|
|
@@ -3563,37 +3612,37 @@ function Je(s) {
|
|
|
3563
3612
|
f > 0 && t.push(Qe(h, c, f));
|
|
3564
3613
|
}), s.querySelectorAll("ellipse").forEach((a) => {
|
|
3565
3614
|
const h = parseFloat(a.getAttribute("cx") || "0"), c = parseFloat(a.getAttribute("cy") || "0"), f = parseFloat(a.getAttribute("rx") || "0"), u = parseFloat(a.getAttribute("ry") || "0");
|
|
3566
|
-
f > 0 && u > 0 && t.push(
|
|
3615
|
+
f > 0 && u > 0 && t.push(ti(h, c, f, u));
|
|
3567
3616
|
}), t;
|
|
3568
3617
|
}
|
|
3569
3618
|
function _t(s) {
|
|
3570
3619
|
const t = [], e = s.trim().split(/[\s,]+/);
|
|
3571
|
-
for (let
|
|
3572
|
-
const
|
|
3573
|
-
Number.isFinite(
|
|
3620
|
+
for (let i = 0; i < e.length - 1; i += 2) {
|
|
3621
|
+
const n = parseFloat(e[i]), r = parseFloat(e[i + 1]);
|
|
3622
|
+
Number.isFinite(n) && Number.isFinite(r) && t.push(n, r);
|
|
3574
3623
|
}
|
|
3575
3624
|
return t;
|
|
3576
3625
|
}
|
|
3577
|
-
function Qe(s, t, e,
|
|
3578
|
-
const
|
|
3579
|
-
for (let r = 0; r <
|
|
3580
|
-
const o = 2 * Math.PI * r /
|
|
3581
|
-
|
|
3626
|
+
function Qe(s, t, e, i = 64) {
|
|
3627
|
+
const n = [];
|
|
3628
|
+
for (let r = 0; r < i; r++) {
|
|
3629
|
+
const o = 2 * Math.PI * r / i;
|
|
3630
|
+
n.push(s + e * Math.cos(o), t + e * Math.sin(o));
|
|
3582
3631
|
}
|
|
3583
|
-
return
|
|
3632
|
+
return n;
|
|
3584
3633
|
}
|
|
3585
|
-
function
|
|
3634
|
+
function ti(s, t, e, i, n = 64) {
|
|
3586
3635
|
const r = [];
|
|
3587
|
-
for (let o = 0; o <
|
|
3588
|
-
const l = 2 * Math.PI * o /
|
|
3589
|
-
r.push(s + e * Math.cos(l), t +
|
|
3636
|
+
for (let o = 0; o < n; o++) {
|
|
3637
|
+
const l = 2 * Math.PI * o / n;
|
|
3638
|
+
r.push(s + e * Math.cos(l), t + i * Math.sin(l));
|
|
3590
3639
|
}
|
|
3591
3640
|
return r;
|
|
3592
3641
|
}
|
|
3593
|
-
function
|
|
3642
|
+
function ei(s) {
|
|
3594
3643
|
const t = [];
|
|
3595
|
-
let e = [],
|
|
3596
|
-
const c =
|
|
3644
|
+
let e = [], i = 0, n = 0, r = 0, o = 0, l = 0, a = 0, h = "";
|
|
3645
|
+
const c = ii(s);
|
|
3597
3646
|
let f = 0;
|
|
3598
3647
|
function u() {
|
|
3599
3648
|
return f >= c.length ? 0 : parseFloat(c[f++]);
|
|
@@ -3606,49 +3655,49 @@ function en(s) {
|
|
|
3606
3655
|
switch (p.toUpperCase()) {
|
|
3607
3656
|
case "M": {
|
|
3608
3657
|
e.length > 0 && t.push(e), e = [];
|
|
3609
|
-
const b = u() + (d ?
|
|
3610
|
-
|
|
3658
|
+
const b = u() + (d ? i : 0), E = u() + (d ? n : 0);
|
|
3659
|
+
i = b, n = E, r = b, o = E, e.push(i, n), l = i, a = n;
|
|
3611
3660
|
break;
|
|
3612
3661
|
}
|
|
3613
3662
|
case "L": {
|
|
3614
|
-
|
|
3663
|
+
i = u() + (d ? i : 0), n = u() + (d ? n : 0), e.push(i, n), l = i, a = n;
|
|
3615
3664
|
break;
|
|
3616
3665
|
}
|
|
3617
3666
|
case "H": {
|
|
3618
|
-
|
|
3667
|
+
i = u() + (d ? i : 0), e.push(i, n), l = i, a = n;
|
|
3619
3668
|
break;
|
|
3620
3669
|
}
|
|
3621
3670
|
case "V": {
|
|
3622
|
-
|
|
3671
|
+
n = u() + (d ? n : 0), e.push(i, n), l = i, a = n;
|
|
3623
3672
|
break;
|
|
3624
3673
|
}
|
|
3625
3674
|
case "C": {
|
|
3626
|
-
const b = u() + (d ?
|
|
3627
|
-
|
|
3675
|
+
const b = u() + (d ? i : 0), E = u() + (d ? n : 0), g = u() + (d ? i : 0), v = u() + (d ? n : 0), m = u() + (d ? i : 0), T = u() + (d ? n : 0);
|
|
3676
|
+
nt(e, i, n, b, E, g, v, m, T), i = m, n = T, l = g, a = v;
|
|
3628
3677
|
break;
|
|
3629
3678
|
}
|
|
3630
3679
|
case "S": {
|
|
3631
|
-
const b = 2 *
|
|
3632
|
-
|
|
3680
|
+
const b = 2 * i - l, E = 2 * n - a, g = u() + (d ? i : 0), v = u() + (d ? n : 0), m = u() + (d ? i : 0), T = u() + (d ? n : 0);
|
|
3681
|
+
nt(e, i, n, b, E, g, v, m, T), i = m, n = T, l = g, a = v;
|
|
3633
3682
|
break;
|
|
3634
3683
|
}
|
|
3635
3684
|
case "Q": {
|
|
3636
|
-
const b = u() + (d ?
|
|
3637
|
-
It(e,
|
|
3685
|
+
const b = u() + (d ? i : 0), E = u() + (d ? n : 0), g = u() + (d ? i : 0), v = u() + (d ? n : 0);
|
|
3686
|
+
It(e, i, n, b, E, g, v), i = g, n = v, l = b, a = E;
|
|
3638
3687
|
break;
|
|
3639
3688
|
}
|
|
3640
3689
|
case "T": {
|
|
3641
|
-
const b = 2 *
|
|
3642
|
-
It(e,
|
|
3690
|
+
const b = 2 * i - l, E = 2 * n - a, g = u() + (d ? i : 0), v = u() + (d ? n : 0);
|
|
3691
|
+
It(e, i, n, b, E, g, v), i = g, n = v, l = b, a = E;
|
|
3643
3692
|
break;
|
|
3644
3693
|
}
|
|
3645
3694
|
case "A": {
|
|
3646
|
-
const b = u(), E = u(), g = u(), v = u(), m = u(), T = u() + (d ?
|
|
3647
|
-
|
|
3695
|
+
const b = u(), E = u(), g = u(), v = u(), m = u(), T = u() + (d ? i : 0), w = u() + (d ? n : 0);
|
|
3696
|
+
ri(e, i, n, b, E, g, !!v, !!m, T, w), i = T, n = w, l = i, a = n;
|
|
3648
3697
|
break;
|
|
3649
3698
|
}
|
|
3650
3699
|
case "Z": {
|
|
3651
|
-
|
|
3700
|
+
i = r, n = o, e.length > 0 && t.push(e), e = [], l = i, a = n;
|
|
3652
3701
|
break;
|
|
3653
3702
|
}
|
|
3654
3703
|
default:
|
|
@@ -3659,15 +3708,15 @@ function en(s) {
|
|
|
3659
3708
|
}
|
|
3660
3709
|
return e.length >= 6 && t.push(e), t;
|
|
3661
3710
|
}
|
|
3662
|
-
function
|
|
3711
|
+
function ii(s) {
|
|
3663
3712
|
const t = [], e = /([a-zA-Z])|([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/g;
|
|
3664
|
-
let
|
|
3665
|
-
for (; (
|
|
3666
|
-
t.push(
|
|
3713
|
+
let i;
|
|
3714
|
+
for (; (i = e.exec(s)) !== null; )
|
|
3715
|
+
t.push(i[0]);
|
|
3667
3716
|
return t;
|
|
3668
3717
|
}
|
|
3669
|
-
const
|
|
3670
|
-
function
|
|
3718
|
+
const ni = 0.5;
|
|
3719
|
+
function nt(s, t, e, i, n, r, o, l, a, h = 0) {
|
|
3671
3720
|
if (h > 12) {
|
|
3672
3721
|
s.push(l, a);
|
|
3673
3722
|
return;
|
|
@@ -3677,24 +3726,24 @@ function it(s, t, e, n, i, r, o, l, a, h = 0) {
|
|
|
3677
3726
|
s.push(l, a);
|
|
3678
3727
|
return;
|
|
3679
3728
|
}
|
|
3680
|
-
const x = Math.abs((
|
|
3681
|
-
if (x + p <
|
|
3729
|
+
const x = Math.abs((i - l) * f - (n - a) * c) / u, p = Math.abs((r - l) * f - (o - a) * c) / u;
|
|
3730
|
+
if (x + p < ni) {
|
|
3682
3731
|
s.push(l, a);
|
|
3683
3732
|
return;
|
|
3684
3733
|
}
|
|
3685
|
-
const d = (t +
|
|
3686
|
-
|
|
3734
|
+
const d = (t + i) / 2, y = (e + n) / 2, b = (i + r) / 2, E = (n + o) / 2, g = (r + l) / 2, v = (o + a) / 2, m = (d + b) / 2, T = (y + E) / 2, w = (b + g) / 2, A = (E + v) / 2, P = (m + w) / 2, F = (T + A) / 2;
|
|
3735
|
+
nt(s, t, e, d, y, m, T, P, F, h + 1), nt(s, P, F, w, A, g, v, l, a, h + 1);
|
|
3687
3736
|
}
|
|
3688
|
-
function It(s, t, e,
|
|
3689
|
-
const l = t + 0.6666666666666666 * (
|
|
3690
|
-
|
|
3737
|
+
function It(s, t, e, i, n, r, o) {
|
|
3738
|
+
const l = t + 0.6666666666666666 * (i - t), a = e + 2 / 3 * (n - e), h = r + 2 / 3 * (i - r), c = o + 2 / 3 * (n - o);
|
|
3739
|
+
nt(s, t, e, l, a, h, c, r, o);
|
|
3691
3740
|
}
|
|
3692
|
-
function
|
|
3693
|
-
if (
|
|
3741
|
+
function ri(s, t, e, i, n, r, o, l, a, h) {
|
|
3742
|
+
if (i === 0 || n === 0) {
|
|
3694
3743
|
s.push(a, h);
|
|
3695
3744
|
return;
|
|
3696
3745
|
}
|
|
3697
|
-
let c = Math.abs(
|
|
3746
|
+
let c = Math.abs(i), f = Math.abs(n);
|
|
3698
3747
|
const u = r * Math.PI / 180, x = Math.cos(u), p = Math.sin(u), d = (t - a) / 2, y = (e - h) / 2, b = x * d + p * y, E = -p * d + x * y;
|
|
3699
3748
|
let g = b * b / (c * c) + E * E / (f * f);
|
|
3700
3749
|
if (g > 1) {
|
|
@@ -3718,49 +3767,49 @@ function sn(s, t, e, n, i, r, o, l, a, h) {
|
|
|
3718
3767
|
s.push(et, at);
|
|
3719
3768
|
}
|
|
3720
3769
|
}
|
|
3721
|
-
function Mt(s, t, e,
|
|
3722
|
-
const
|
|
3723
|
-
return
|
|
3770
|
+
function Mt(s, t, e, i) {
|
|
3771
|
+
const n = s * i - t * e < 0 ? -1 : 1, r = s * e + t * i, o = Math.sqrt(s * s + t * t), l = Math.sqrt(e * e + i * i), a = r / (o * l);
|
|
3772
|
+
return n * Math.acos(Math.max(-1, Math.min(1, a)));
|
|
3724
3773
|
}
|
|
3725
|
-
function
|
|
3774
|
+
function si(s) {
|
|
3726
3775
|
const t = [], e = [];
|
|
3727
|
-
for (let
|
|
3728
|
-
|
|
3729
|
-
for (const
|
|
3730
|
-
t.push(
|
|
3776
|
+
for (let i = 0; i < s.length; i++) {
|
|
3777
|
+
i > 0 && e.push(t.length / 2);
|
|
3778
|
+
for (const n of s[i])
|
|
3779
|
+
t.push(n);
|
|
3731
3780
|
}
|
|
3732
3781
|
return { flatCoords: t, holeIndices: e };
|
|
3733
3782
|
}
|
|
3734
3783
|
function zt(s) {
|
|
3735
|
-
const t = s.length, e = s.map((
|
|
3736
|
-
for (let
|
|
3784
|
+
const t = s.length, e = s.map((n) => Math.abs(qt(n))), i = new Array(t).fill(!1);
|
|
3785
|
+
for (let n = 0; n < t; n++) {
|
|
3737
3786
|
let r = 0;
|
|
3738
|
-
const o = s[
|
|
3787
|
+
const o = s[n][0], l = s[n][1];
|
|
3739
3788
|
for (let a = 0; a < t; a++)
|
|
3740
|
-
|
|
3741
|
-
n
|
|
3789
|
+
n !== a && e[a] > e[n] && Yt(o, l, s[a]) && r++;
|
|
3790
|
+
i[n] = r % 2 === 1;
|
|
3742
3791
|
}
|
|
3743
|
-
return
|
|
3792
|
+
return i;
|
|
3744
3793
|
}
|
|
3745
|
-
function
|
|
3794
|
+
function oi(s) {
|
|
3746
3795
|
if (s.length <= 1)
|
|
3747
3796
|
return [s];
|
|
3748
3797
|
const t = zt(s), e = s.map((o, l) => {
|
|
3749
3798
|
const a = qt(o);
|
|
3750
3799
|
return { index: l, contour: o, area: a, isOuter: !t[l] };
|
|
3751
|
-
}),
|
|
3752
|
-
if (
|
|
3800
|
+
}), i = e.filter((o) => o.isOuter), n = e.filter((o) => !o.isOuter);
|
|
3801
|
+
if (i.length === 0)
|
|
3753
3802
|
return s.map((o) => [o]);
|
|
3754
|
-
const r =
|
|
3803
|
+
const r = i.map((o) => ({
|
|
3755
3804
|
outer: o.contour,
|
|
3756
3805
|
holes: []
|
|
3757
3806
|
}));
|
|
3758
|
-
for (const o of
|
|
3807
|
+
for (const o of n) {
|
|
3759
3808
|
const l = o.contour[0], a = o.contour[1];
|
|
3760
3809
|
let h = -1, c = 1 / 0;
|
|
3761
|
-
for (let f = 0; f <
|
|
3762
|
-
if (Yt(l, a,
|
|
3763
|
-
const u = Math.abs(
|
|
3810
|
+
for (let f = 0; f < i.length; f++)
|
|
3811
|
+
if (Yt(l, a, i[f].contour)) {
|
|
3812
|
+
const u = Math.abs(i[f].area);
|
|
3764
3813
|
u < c && (c = u, h = f);
|
|
3765
3814
|
}
|
|
3766
3815
|
h >= 0 ? r[h].holes.push(o.contour) : r.push({ outer: o.contour, holes: [] });
|
|
@@ -3770,30 +3819,30 @@ function an(s) {
|
|
|
3770
3819
|
function qt(s) {
|
|
3771
3820
|
let t = 0;
|
|
3772
3821
|
const e = s.length;
|
|
3773
|
-
for (let
|
|
3774
|
-
const
|
|
3775
|
-
t +=
|
|
3822
|
+
for (let i = 0; i < e; i += 2) {
|
|
3823
|
+
const n = s[i], r = s[i + 1], o = s[(i + 2) % e], l = s[(i + 3) % e];
|
|
3824
|
+
t += n * l - o * r;
|
|
3776
3825
|
}
|
|
3777
3826
|
return t / 2;
|
|
3778
3827
|
}
|
|
3779
3828
|
function Yt(s, t, e) {
|
|
3780
|
-
let
|
|
3781
|
-
const
|
|
3782
|
-
for (let r = 0, o =
|
|
3829
|
+
let i = !1;
|
|
3830
|
+
const n = e.length;
|
|
3831
|
+
for (let r = 0, o = n - 2; r < n; o = r, r += 2) {
|
|
3783
3832
|
const l = e[r], a = e[r + 1], h = e[o], c = e[o + 1];
|
|
3784
|
-
a > t != c > t && s < (h - l) * (t - a) / (c - a) + l && (
|
|
3833
|
+
a > t != c > t && s < (h - l) * (t - a) / (c - a) + l && (i = !i);
|
|
3785
3834
|
}
|
|
3786
|
-
return
|
|
3835
|
+
return i;
|
|
3787
3836
|
}
|
|
3788
|
-
function
|
|
3789
|
-
const
|
|
3790
|
-
let r = jt(s, 0,
|
|
3837
|
+
function ai(s, t, e = 2) {
|
|
3838
|
+
const i = t && t.length > 0, n = i ? t[0] * e : s.length;
|
|
3839
|
+
let r = jt(s, 0, n, e, !0);
|
|
3791
3840
|
const o = [];
|
|
3792
3841
|
if (!r || r.next === r.prev) return o;
|
|
3793
|
-
|
|
3842
|
+
i && (r = fi(s, t, r, e));
|
|
3794
3843
|
let l = 1 / 0, a = 1 / 0, h = -1 / 0, c = -1 / 0, f = 0;
|
|
3795
3844
|
if (s.length > 80 * e) {
|
|
3796
|
-
for (let u = 0; u <
|
|
3845
|
+
for (let u = 0; u < n; u += e) {
|
|
3797
3846
|
const x = s[u], p = s[u + 1];
|
|
3798
3847
|
x < l && (l = x), p < a && (a = p), x > h && (h = x), p > c && (c = p);
|
|
3799
3848
|
}
|
|
@@ -3801,90 +3850,90 @@ function ln(s, t, e = 2) {
|
|
|
3801
3850
|
}
|
|
3802
3851
|
return rt(r, o, e, l, a, f, 0), o;
|
|
3803
3852
|
}
|
|
3804
|
-
function jt(s, t, e,
|
|
3853
|
+
function jt(s, t, e, i, n) {
|
|
3805
3854
|
let r = null;
|
|
3806
|
-
if (
|
|
3807
|
-
for (let o = t; o < e; o +=
|
|
3855
|
+
if (n === Si(s, t, e, i) > 0)
|
|
3856
|
+
for (let o = t; o < e; o += i)
|
|
3808
3857
|
r = Bt(o, s[o], s[o + 1], r);
|
|
3809
3858
|
else
|
|
3810
|
-
for (let o = e -
|
|
3859
|
+
for (let o = e - i; o >= t; o -= i)
|
|
3811
3860
|
r = Bt(o, s[o], s[o + 1], r);
|
|
3812
3861
|
return r && vt(r, r.next) && (ot(r), r = r.next), r ? (r.next.prev = r, r.prev.next = r, r.next) : null;
|
|
3813
3862
|
}
|
|
3814
3863
|
function Y(s, t) {
|
|
3815
3864
|
t || (t = s);
|
|
3816
|
-
let e = s,
|
|
3865
|
+
let e = s, i;
|
|
3817
3866
|
do
|
|
3818
|
-
if (
|
|
3867
|
+
if (i = !1, !e.steiner && (vt(e, e.next) || L(e.prev, e, e.next) === 0)) {
|
|
3819
3868
|
if (ot(e), e = t = e.prev, e === e.next) break;
|
|
3820
|
-
|
|
3869
|
+
i = !0;
|
|
3821
3870
|
} else
|
|
3822
3871
|
e = e.next;
|
|
3823
|
-
while (
|
|
3872
|
+
while (i || e !== t);
|
|
3824
3873
|
return t;
|
|
3825
3874
|
}
|
|
3826
|
-
function rt(s, t, e,
|
|
3875
|
+
function rt(s, t, e, i, n, r, o) {
|
|
3827
3876
|
if (!s) return;
|
|
3828
|
-
!o && r &&
|
|
3877
|
+
!o && r && gi(s, i, n, r);
|
|
3829
3878
|
let l = s, a, h;
|
|
3830
3879
|
for (; s.prev !== s.next; ) {
|
|
3831
|
-
if (a = s.prev, h = s.next, r ?
|
|
3880
|
+
if (a = s.prev, h = s.next, r ? ui(s, i, n, r) : li(s)) {
|
|
3832
3881
|
t.push(a.i / e, s.i / e, h.i / e), ot(s), s = h.next, l = h.next;
|
|
3833
3882
|
continue;
|
|
3834
3883
|
}
|
|
3835
3884
|
if (s = h, s === l) {
|
|
3836
|
-
o ? o === 1 ? (s =
|
|
3885
|
+
o ? o === 1 ? (s = ci(Y(s), t, e), rt(s, t, e, i, n, r, 2)) : o === 2 && hi(s, t, e, i, n, r) : rt(Y(s), t, e, i, n, r, 1);
|
|
3837
3886
|
break;
|
|
3838
3887
|
}
|
|
3839
3888
|
}
|
|
3840
3889
|
}
|
|
3841
|
-
function
|
|
3842
|
-
const t = s.prev, e = s,
|
|
3843
|
-
if (L(t, e,
|
|
3844
|
-
const
|
|
3845
|
-
let p =
|
|
3890
|
+
function li(s) {
|
|
3891
|
+
const t = s.prev, e = s, i = s.next;
|
|
3892
|
+
if (L(t, e, i) >= 0) return !1;
|
|
3893
|
+
const n = t.x, r = e.x, o = i.x, l = t.y, a = e.y, h = i.y, c = n < r ? n < o ? n : o : r < o ? r : o, f = l < a ? l < h ? l : h : a < h ? a : h, u = n > r ? n > o ? n : o : r > o ? r : o, x = l > a ? l > h ? l : h : a > h ? a : h;
|
|
3894
|
+
let p = i.next;
|
|
3846
3895
|
for (; p !== t; ) {
|
|
3847
|
-
if (p.x >= c && p.x <= u && p.y >= f && p.y <= x && tt(
|
|
3896
|
+
if (p.x >= c && p.x <= u && p.y >= f && p.y <= x && tt(n, l, r, a, o, h, p.x, p.y) && L(p.prev, p, p.next) >= 0)
|
|
3848
3897
|
return !1;
|
|
3849
3898
|
p = p.next;
|
|
3850
3899
|
}
|
|
3851
3900
|
return !0;
|
|
3852
3901
|
}
|
|
3853
|
-
function
|
|
3854
|
-
const
|
|
3855
|
-
if (L(
|
|
3856
|
-
const l =
|
|
3902
|
+
function ui(s, t, e, i) {
|
|
3903
|
+
const n = s.prev, r = s, o = s.next;
|
|
3904
|
+
if (L(n, r, o) >= 0) return !1;
|
|
3905
|
+
const l = n.x, a = r.x, h = o.x, c = n.y, f = r.y, u = o.y, x = l < a ? l < h ? l : h : a < h ? a : h, p = c < f ? c < u ? c : u : f < u ? f : u, d = l > a ? l > h ? l : h : a > h ? a : h, y = c > f ? c > u ? c : u : f > u ? f : u, b = yt(x, p, t, e, i), E = yt(d, y, t, e, i);
|
|
3857
3906
|
let g = s.prevZ, v = s.nextZ;
|
|
3858
3907
|
for (; g && g.z >= b && v && v.z <= E; ) {
|
|
3859
|
-
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !==
|
|
3908
|
+
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== n && g !== o && tt(l, c, a, f, h, u, g.x, g.y) && L(g.prev, g, g.next) >= 0 || (g = g.prevZ, v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !== n && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0)) return !1;
|
|
3860
3909
|
v = v.nextZ;
|
|
3861
3910
|
}
|
|
3862
3911
|
for (; g && g.z >= b; ) {
|
|
3863
|
-
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !==
|
|
3912
|
+
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== n && g !== o && tt(l, c, a, f, h, u, g.x, g.y) && L(g.prev, g, g.next) >= 0) return !1;
|
|
3864
3913
|
g = g.prevZ;
|
|
3865
3914
|
}
|
|
3866
3915
|
for (; v && v.z <= E; ) {
|
|
3867
|
-
if (v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !==
|
|
3916
|
+
if (v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !== n && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0) return !1;
|
|
3868
3917
|
v = v.nextZ;
|
|
3869
3918
|
}
|
|
3870
3919
|
return !0;
|
|
3871
3920
|
}
|
|
3872
|
-
function
|
|
3873
|
-
let
|
|
3921
|
+
function ci(s, t, e) {
|
|
3922
|
+
let i = s;
|
|
3874
3923
|
do {
|
|
3875
|
-
const
|
|
3876
|
-
!vt(
|
|
3877
|
-
} while (
|
|
3878
|
-
return Y(
|
|
3924
|
+
const n = i.prev, r = i.next.next;
|
|
3925
|
+
!vt(n, r) && Zt(n, i, i.next, r) && st(n, r) && st(r, n) && (t.push(n.i / e, i.i / e, r.i / e), ot(i), ot(i.next), i = s = r), i = i.next;
|
|
3926
|
+
} while (i !== s);
|
|
3927
|
+
return Y(i);
|
|
3879
3928
|
}
|
|
3880
|
-
function
|
|
3929
|
+
function hi(s, t, e, i, n, r) {
|
|
3881
3930
|
let o = s;
|
|
3882
3931
|
do {
|
|
3883
3932
|
let l = o.next.next;
|
|
3884
3933
|
for (; l !== o.prev; ) {
|
|
3885
|
-
if (o.i !== l.i &&
|
|
3934
|
+
if (o.i !== l.i && Ti(o, l)) {
|
|
3886
3935
|
let a = $t(o, l);
|
|
3887
|
-
o = Y(o, o.next), a = Y(a, a.next), rt(o, t, e,
|
|
3936
|
+
o = Y(o, o.next), a = Y(a, a.next), rt(o, t, e, i, n, r, 0), rt(a, t, e, i, n, r, 0);
|
|
3888
3937
|
return;
|
|
3889
3938
|
}
|
|
3890
3939
|
l = l.next;
|
|
@@ -3892,31 +3941,31 @@ function fn(s, t, e, n, i, r) {
|
|
|
3892
3941
|
o = o.next;
|
|
3893
3942
|
} while (o !== s);
|
|
3894
3943
|
}
|
|
3895
|
-
function
|
|
3896
|
-
const
|
|
3944
|
+
function fi(s, t, e, i) {
|
|
3945
|
+
const n = [];
|
|
3897
3946
|
for (let r = 0; r < t.length; r++) {
|
|
3898
|
-
const o = t[r] *
|
|
3899
|
-
a && (a === a.next && (a.steiner = !0),
|
|
3947
|
+
const o = t[r] * i, l = r < t.length - 1 ? t[r + 1] * i : s.length, a = jt(s, o, l, i, !1);
|
|
3948
|
+
a && (a === a.next && (a.steiner = !0), n.push(xi(a)));
|
|
3900
3949
|
}
|
|
3901
|
-
|
|
3902
|
-
for (const r of
|
|
3903
|
-
e =
|
|
3950
|
+
n.sort((r, o) => r.x - o.x);
|
|
3951
|
+
for (const r of n)
|
|
3952
|
+
e = di(r, e);
|
|
3904
3953
|
return e;
|
|
3905
3954
|
}
|
|
3906
|
-
function
|
|
3907
|
-
const e =
|
|
3955
|
+
function di(s, t) {
|
|
3956
|
+
const e = mi(s, t);
|
|
3908
3957
|
if (!e) return t;
|
|
3909
|
-
const
|
|
3910
|
-
return Y(
|
|
3958
|
+
const i = $t(e, s);
|
|
3959
|
+
return Y(i, i.next), Y(e, e.next);
|
|
3911
3960
|
}
|
|
3912
|
-
function
|
|
3961
|
+
function mi(s, t) {
|
|
3913
3962
|
let e = t;
|
|
3914
|
-
const
|
|
3963
|
+
const i = s.x, n = s.y;
|
|
3915
3964
|
let r = -1 / 0, o = null;
|
|
3916
3965
|
do {
|
|
3917
|
-
if (
|
|
3918
|
-
const f = e.x + (
|
|
3919
|
-
if (f <=
|
|
3966
|
+
if (n <= e.y && n >= e.next.y && e.next.y !== e.y) {
|
|
3967
|
+
const f = e.x + (n - e.y) / (e.next.y - e.y) * (e.next.x - e.x);
|
|
3968
|
+
if (f <= i && f > r && (r = f, o = e.x < e.next.x ? e : e.next, f === i))
|
|
3920
3969
|
return o;
|
|
3921
3970
|
}
|
|
3922
3971
|
e = e.next;
|
|
@@ -3926,62 +3975,62 @@ function pn(s, t) {
|
|
|
3926
3975
|
let c = 1 / 0;
|
|
3927
3976
|
e = o;
|
|
3928
3977
|
do {
|
|
3929
|
-
if (
|
|
3930
|
-
const f = Math.abs(
|
|
3931
|
-
st(e, s) && (f < c || f === c && (e.x > o.x ||
|
|
3978
|
+
if (i >= e.x && e.x >= a && i !== e.x && tt(n < h ? i : r, n, a, h, n < h ? r : i, n, e.x, e.y)) {
|
|
3979
|
+
const f = Math.abs(n - e.y) / (i - e.x);
|
|
3980
|
+
st(e, s) && (f < c || f === c && (e.x > o.x || pi(o, e))) && (o = e, c = f);
|
|
3932
3981
|
}
|
|
3933
3982
|
e = e.next;
|
|
3934
3983
|
} while (e !== l);
|
|
3935
3984
|
return o;
|
|
3936
3985
|
}
|
|
3937
|
-
function
|
|
3986
|
+
function pi(s, t) {
|
|
3938
3987
|
return L(s.prev, s, t.prev) < 0 && L(t.next, s, s.next) < 0;
|
|
3939
3988
|
}
|
|
3940
|
-
function
|
|
3941
|
-
let
|
|
3989
|
+
function gi(s, t, e, i) {
|
|
3990
|
+
let n = s;
|
|
3942
3991
|
do
|
|
3943
|
-
|
|
3944
|
-
while (
|
|
3945
|
-
|
|
3992
|
+
n.z === 0 && (n.z = yt(n.x, n.y, t, e, i)), n.prevZ = n.prev, n.nextZ = n.next, n = n.next;
|
|
3993
|
+
while (n !== s);
|
|
3994
|
+
n.prevZ.nextZ = null, n.prevZ = null, vi(n);
|
|
3946
3995
|
}
|
|
3947
|
-
function
|
|
3996
|
+
function vi(s) {
|
|
3948
3997
|
let t = 1, e;
|
|
3949
3998
|
do {
|
|
3950
|
-
let
|
|
3999
|
+
let i = s;
|
|
3951
4000
|
s = null;
|
|
3952
|
-
let
|
|
3953
|
-
for (e = 0;
|
|
4001
|
+
let n = null;
|
|
4002
|
+
for (e = 0; i; ) {
|
|
3954
4003
|
e++;
|
|
3955
|
-
let r =
|
|
4004
|
+
let r = i, o = 0;
|
|
3956
4005
|
for (let a = 0; a < t && (o++, r = r.nextZ, !!r); a++)
|
|
3957
4006
|
;
|
|
3958
4007
|
let l = t;
|
|
3959
4008
|
for (; o > 0 || l > 0 && r; ) {
|
|
3960
4009
|
let a;
|
|
3961
|
-
o !== 0 && (l === 0 || !r ||
|
|
4010
|
+
o !== 0 && (l === 0 || !r || i.z <= r.z) ? (a = i, i = i.nextZ, o--) : (a = r, r = r.nextZ, l--), n ? n.nextZ = a : s = a, a.prevZ = n, n = a;
|
|
3962
4011
|
}
|
|
3963
|
-
|
|
4012
|
+
i = r;
|
|
3964
4013
|
}
|
|
3965
|
-
|
|
4014
|
+
n.nextZ = null, t *= 2;
|
|
3966
4015
|
} while (e > 1);
|
|
3967
4016
|
return s;
|
|
3968
4017
|
}
|
|
3969
|
-
function yt(s, t, e,
|
|
3970
|
-
let r = (s - e) *
|
|
4018
|
+
function yt(s, t, e, i, n) {
|
|
4019
|
+
let r = (s - e) * n | 0, o = (t - i) * n | 0;
|
|
3971
4020
|
return r = (r | r << 8) & 16711935, r = (r | r << 4) & 252645135, r = (r | r << 2) & 858993459, r = (r | r << 1) & 1431655765, o = (o | o << 8) & 16711935, o = (o | o << 4) & 252645135, o = (o | o << 2) & 858993459, o = (o | o << 1) & 1431655765, r | o << 1;
|
|
3972
4021
|
}
|
|
3973
|
-
function
|
|
4022
|
+
function xi(s) {
|
|
3974
4023
|
let t = s, e = s;
|
|
3975
4024
|
do
|
|
3976
4025
|
(t.x < e.x || t.x === e.x && t.y < e.y) && (e = t), t = t.next;
|
|
3977
4026
|
while (t !== s);
|
|
3978
4027
|
return e;
|
|
3979
4028
|
}
|
|
3980
|
-
function tt(s, t, e,
|
|
3981
|
-
return (
|
|
4029
|
+
function tt(s, t, e, i, n, r, o, l) {
|
|
4030
|
+
return (n - o) * (t - l) - (s - o) * (r - l) >= 0 && (s - o) * (i - l) - (e - o) * (t - l) >= 0 && (e - o) * (r - l) - (n - o) * (i - l) >= 0;
|
|
3982
4031
|
}
|
|
3983
|
-
function
|
|
3984
|
-
return s.next.i !== t.i && s.prev.i !== t.i && !
|
|
4032
|
+
function Ti(s, t) {
|
|
4033
|
+
return s.next.i !== t.i && s.prev.i !== t.i && !Ei(s, t) && (st(s, t) && st(t, s) && bi(s, t) && (L(s.prev, s, t.prev) !== 0 || L(s, t.prev, t) !== 0) || vt(s, t) && L(s.prev, s, s.next) > 0 && L(t.prev, t, t.next) > 0);
|
|
3985
4034
|
}
|
|
3986
4035
|
function L(s, t, e) {
|
|
3987
4036
|
return (t.y - s.y) * (e.x - t.x) - (t.x - s.x) * (e.y - t.y);
|
|
@@ -3989,9 +4038,9 @@ function L(s, t, e) {
|
|
|
3989
4038
|
function vt(s, t) {
|
|
3990
4039
|
return s.x === t.x && s.y === t.y;
|
|
3991
4040
|
}
|
|
3992
|
-
function Zt(s, t, e,
|
|
3993
|
-
const
|
|
3994
|
-
return !!(
|
|
4041
|
+
function Zt(s, t, e, i) {
|
|
4042
|
+
const n = ct(L(s, t, e)), r = ct(L(s, t, i)), o = ct(L(e, i, s)), l = ct(L(e, i, t));
|
|
4043
|
+
return !!(n !== r && o !== l || n === 0 && ut(s, e, t) || r === 0 && ut(s, i, t) || o === 0 && ut(e, s, i) || l === 0 && ut(e, t, i));
|
|
3995
4044
|
}
|
|
3996
4045
|
function ut(s, t, e) {
|
|
3997
4046
|
return t.x <= Math.max(s.x, e.x) && t.x >= Math.min(s.x, e.x) && t.y <= Math.max(s.y, e.y) && t.y >= Math.min(s.y, e.y);
|
|
@@ -3999,7 +4048,7 @@ function ut(s, t, e) {
|
|
|
3999
4048
|
function ct(s) {
|
|
4000
4049
|
return s > 0 ? 1 : s < 0 ? -1 : 0;
|
|
4001
4050
|
}
|
|
4002
|
-
function
|
|
4051
|
+
function Ei(s, t) {
|
|
4003
4052
|
let e = s;
|
|
4004
4053
|
do {
|
|
4005
4054
|
if (e.i !== s.i && e.next.i !== s.i && e.i !== t.i && e.next.i !== t.i && Zt(e, e.next, s, t)) return !0;
|
|
@@ -4010,21 +4059,21 @@ function bn(s, t) {
|
|
|
4010
4059
|
function st(s, t) {
|
|
4011
4060
|
return L(s.prev, s, s.next) < 0 ? L(s, t, s.next) >= 0 && L(s, s.prev, t) >= 0 : L(s, t, s.prev) < 0 || L(s, s.next, t) < 0;
|
|
4012
4061
|
}
|
|
4013
|
-
function
|
|
4014
|
-
let e = s,
|
|
4015
|
-
const
|
|
4062
|
+
function bi(s, t) {
|
|
4063
|
+
let e = s, i = !1;
|
|
4064
|
+
const n = (s.x + t.x) / 2, r = (s.y + t.y) / 2;
|
|
4016
4065
|
do
|
|
4017
|
-
e.y > r != e.next.y > r && e.next.y !== e.y &&
|
|
4066
|
+
e.y > r != e.next.y > r && e.next.y !== e.y && n < (e.next.x - e.x) * (r - e.y) / (e.next.y - e.y) + e.x && (i = !i), e = e.next;
|
|
4018
4067
|
while (e !== s);
|
|
4019
|
-
return
|
|
4068
|
+
return i;
|
|
4020
4069
|
}
|
|
4021
4070
|
function $t(s, t) {
|
|
4022
|
-
const e = wt(s.i, s.x, s.y),
|
|
4023
|
-
return s.next = t, t.prev = s, e.next =
|
|
4071
|
+
const e = wt(s.i, s.x, s.y), i = wt(t.i, t.x, t.y), n = s.next, r = t.prev;
|
|
4072
|
+
return s.next = t, t.prev = s, e.next = n, n.prev = e, i.next = e, e.prev = i, r.next = i, i.prev = r, i;
|
|
4024
4073
|
}
|
|
4025
|
-
function Bt(s, t, e,
|
|
4026
|
-
const
|
|
4027
|
-
return
|
|
4074
|
+
function Bt(s, t, e, i) {
|
|
4075
|
+
const n = wt(s, t, e);
|
|
4076
|
+
return i ? (n.next = i.next, n.prev = i, i.next.prev = n, i.next = n) : (n.prev = n, n.next = n), n;
|
|
4028
4077
|
}
|
|
4029
4078
|
function ot(s) {
|
|
4030
4079
|
s.next.prev = s.prev, s.prev.next = s.next, s.prevZ && (s.prevZ.nextZ = s.nextZ), s.nextZ && (s.nextZ.prevZ = s.prevZ);
|
|
@@ -4042,11 +4091,11 @@ function wt(s, t, e) {
|
|
|
4042
4091
|
steiner: !1
|
|
4043
4092
|
};
|
|
4044
4093
|
}
|
|
4045
|
-
function
|
|
4046
|
-
let
|
|
4047
|
-
for (let r = t, o = e -
|
|
4048
|
-
|
|
4049
|
-
return
|
|
4094
|
+
function Si(s, t, e, i) {
|
|
4095
|
+
let n = 0;
|
|
4096
|
+
for (let r = t, o = e - i; r < e; r += i)
|
|
4097
|
+
n += (s[o] - s[r]) * (s[r + 1] + s[o + 1]), o = r;
|
|
4098
|
+
return n;
|
|
4050
4099
|
}
|
|
4051
4100
|
const R = {
|
|
4052
4101
|
parallaxX: 0.4,
|
|
@@ -4109,10 +4158,10 @@ class Et extends HTMLElement {
|
|
|
4109
4158
|
static get observedAttributes() {
|
|
4110
4159
|
return [
|
|
4111
4160
|
"src",
|
|
4112
|
-
"
|
|
4113
|
-
"
|
|
4114
|
-
"
|
|
4115
|
-
"
|
|
4161
|
+
"map-src",
|
|
4162
|
+
"map-width",
|
|
4163
|
+
"map-height",
|
|
4164
|
+
"map-fps",
|
|
4116
4165
|
"depth-model",
|
|
4117
4166
|
"logo-src",
|
|
4118
4167
|
"source-type",
|
|
@@ -4163,12 +4212,12 @@ class Et extends HTMLElement {
|
|
|
4163
4212
|
"muted"
|
|
4164
4213
|
];
|
|
4165
4214
|
}
|
|
4166
|
-
reinitAttributes = ["src", "
|
|
4215
|
+
reinitAttributes = ["src", "map-src", "map-width", "map-height", "map-fps", "depth-model", "logo-src", "source-type"];
|
|
4167
4216
|
canInit() {
|
|
4168
4217
|
const t = !!this.getAttribute("logo-src");
|
|
4169
4218
|
if (this.sourceType === "camera") return t;
|
|
4170
|
-
const e = !!this.getAttribute("src"),
|
|
4171
|
-
return e && t && (
|
|
4219
|
+
const e = !!this.getAttribute("src"), i = !!this.getAttribute("map-src"), n = !!this.getAttribute("depth-model");
|
|
4220
|
+
return e && t && (i || n);
|
|
4172
4221
|
}
|
|
4173
4222
|
_input = { x: 0, y: 0 };
|
|
4174
4223
|
/** The current input offset. Set this externally to drive the effect. */
|
|
@@ -4191,24 +4240,24 @@ class Et extends HTMLElement {
|
|
|
4191
4240
|
}
|
|
4192
4241
|
// --- Attribute helpers ---
|
|
4193
4242
|
getAttrFloat(t, e) {
|
|
4194
|
-
const
|
|
4195
|
-
if (
|
|
4196
|
-
const
|
|
4197
|
-
return Number.isFinite(
|
|
4243
|
+
const i = this.getAttribute(t);
|
|
4244
|
+
if (i === null) return e;
|
|
4245
|
+
const n = parseFloat(i);
|
|
4246
|
+
return Number.isFinite(n) ? n : e;
|
|
4198
4247
|
}
|
|
4199
4248
|
getAttrBool(t, e) {
|
|
4200
4249
|
if (!this.hasAttribute(t)) return e;
|
|
4201
|
-
const
|
|
4202
|
-
return !(
|
|
4250
|
+
const i = this.getAttribute(t);
|
|
4251
|
+
return !(i === "false" || i === "0");
|
|
4203
4252
|
}
|
|
4204
4253
|
getAttrColor(t, e) {
|
|
4205
|
-
const
|
|
4206
|
-
return
|
|
4254
|
+
const i = this.getAttribute(t) ?? e;
|
|
4255
|
+
return yi(i);
|
|
4207
4256
|
}
|
|
4208
4257
|
getAttrVec3(t, e) {
|
|
4209
|
-
const
|
|
4210
|
-
if (
|
|
4211
|
-
return [
|
|
4258
|
+
const n = (this.getAttribute(t) ?? e).split(",").map((o) => parseFloat(o.trim()));
|
|
4259
|
+
if (n.length >= 3 && n.every(Number.isFinite))
|
|
4260
|
+
return [n[0], n[1], n[2]];
|
|
4212
4261
|
const r = e.split(",").map((o) => parseFloat(o.trim()));
|
|
4213
4262
|
return [r[0], r[1], r[2]];
|
|
4214
4263
|
}
|
|
@@ -4398,8 +4447,8 @@ class Et extends HTMLElement {
|
|
|
4398
4447
|
disconnectedCallback() {
|
|
4399
4448
|
this.lifecycle.onDisconnected();
|
|
4400
4449
|
}
|
|
4401
|
-
attributeChangedCallback(t, e,
|
|
4402
|
-
this.lifecycle.onAttributeChanged(t, e,
|
|
4450
|
+
attributeChangedCallback(t, e, i) {
|
|
4451
|
+
this.lifecycle.onAttributeChanged(t, e, i);
|
|
4403
4452
|
}
|
|
4404
4453
|
// --- Shadow DOM setup ---
|
|
4405
4454
|
setupShadowDOM() {
|
|
@@ -4431,13 +4480,13 @@ class Et extends HTMLElement {
|
|
|
4431
4480
|
async doInit(t) {
|
|
4432
4481
|
const e = this.getAttribute("logo-src");
|
|
4433
4482
|
if (!this.container) return;
|
|
4434
|
-
const
|
|
4483
|
+
const i = this.sourceType === "camera", n = this.depthModel;
|
|
4435
4484
|
try {
|
|
4436
4485
|
let r, o, l, a = null;
|
|
4437
4486
|
const h = (d) => {
|
|
4438
4487
|
this.emit("layershift-portal:model-progress", d);
|
|
4439
4488
|
};
|
|
4440
|
-
if (
|
|
4489
|
+
if (i) {
|
|
4441
4490
|
const [d, y] = await Promise.all([
|
|
4442
4491
|
Nt(
|
|
4443
4492
|
{ video: { facingMode: "user" } },
|
|
@@ -4449,8 +4498,8 @@ class Et extends HTMLElement {
|
|
|
4449
4498
|
d.dispose();
|
|
4450
4499
|
return;
|
|
4451
4500
|
}
|
|
4452
|
-
if (r = d, l = y,
|
|
4453
|
-
if (a = await dt(
|
|
4501
|
+
if (r = d, l = y, n) {
|
|
4502
|
+
if (a = await dt(n, J, Q, h), t.aborted) {
|
|
4454
4503
|
a.dispose(), r.dispose();
|
|
4455
4504
|
return;
|
|
4456
4505
|
}
|
|
@@ -4458,7 +4507,7 @@ class Et extends HTMLElement {
|
|
|
4458
4507
|
} else
|
|
4459
4508
|
o = X(r.width, r.height);
|
|
4460
4509
|
} else {
|
|
4461
|
-
const d = this.getAttribute("src"), y = this.getAttribute("
|
|
4510
|
+
const d = this.getAttribute("src"), y = this.getAttribute("map-src"), b = !!y, E = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(d);
|
|
4462
4511
|
if (b) {
|
|
4463
4512
|
const [g, v, m] = await Promise.all([
|
|
4464
4513
|
E ? ft(d) : ht(d, {
|
|
@@ -4468,9 +4517,9 @@ class Et extends HTMLElement {
|
|
|
4468
4517
|
}),
|
|
4469
4518
|
kt(
|
|
4470
4519
|
y,
|
|
4471
|
-
this.getAttrFloat("
|
|
4472
|
-
this.getAttrFloat("
|
|
4473
|
-
this.getAttrFloat("
|
|
4520
|
+
this.getAttrFloat("map-width", 512),
|
|
4521
|
+
this.getAttrFloat("map-height", 512),
|
|
4522
|
+
this.getAttrFloat("map-fps", 5)
|
|
4474
4523
|
),
|
|
4475
4524
|
Tt(e)
|
|
4476
4525
|
]);
|
|
@@ -4479,14 +4528,14 @@ class Et extends HTMLElement {
|
|
|
4479
4528
|
return;
|
|
4480
4529
|
}
|
|
4481
4530
|
r = g, o = v, l = m;
|
|
4482
|
-
} else if (
|
|
4531
|
+
} else if (n) {
|
|
4483
4532
|
const [g, v, m] = await Promise.all([
|
|
4484
4533
|
E ? ft(d) : ht(d, {
|
|
4485
4534
|
parent: this.shadow,
|
|
4486
4535
|
loop: this.shouldLoop,
|
|
4487
4536
|
muted: this.shouldMute
|
|
4488
4537
|
}),
|
|
4489
|
-
dt(
|
|
4538
|
+
dt(n, J, Q, h),
|
|
4490
4539
|
Tt(e)
|
|
4491
4540
|
]);
|
|
4492
4541
|
if (t.aborted) {
|
|
@@ -4509,7 +4558,7 @@ class Et extends HTMLElement {
|
|
|
4509
4558
|
} else
|
|
4510
4559
|
o = X(J, Q);
|
|
4511
4560
|
} else
|
|
4512
|
-
throw new Error("Either
|
|
4561
|
+
throw new Error("Either map-src or depth-model must be provided.");
|
|
4513
4562
|
}
|
|
4514
4563
|
this.source = r, this.depthEstimator = a, this.mesh = l, this.loopCount = 0, this.attachSourceEventListeners(r);
|
|
4515
4564
|
const c = this.container?.clientWidth || r.width, f = this.parallaxMax / Math.max(c, 1);
|
|
@@ -4578,7 +4627,7 @@ class Et extends HTMLElement {
|
|
|
4578
4627
|
frameNumber: y
|
|
4579
4628
|
});
|
|
4580
4629
|
}
|
|
4581
|
-
), !
|
|
4630
|
+
), !i && r.isLive && this.shouldAutoplay && r.play)
|
|
4582
4631
|
try {
|
|
4583
4632
|
await r.play();
|
|
4584
4633
|
} catch {
|
|
@@ -4599,15 +4648,15 @@ class Et extends HTMLElement {
|
|
|
4599
4648
|
this.renderer?.dispose(), this.renderer = null, this.depthEstimator?.dispose(), this.depthEstimator = null, this.source?.dispose(), this.source = null, this.mesh = null, this.loopCount = 0, this.container = null;
|
|
4600
4649
|
}
|
|
4601
4650
|
}
|
|
4602
|
-
function
|
|
4651
|
+
function yi(s) {
|
|
4603
4652
|
const t = s.replace("#", "");
|
|
4604
4653
|
if (t.length === 3) {
|
|
4605
|
-
const e = parseInt(t[0] + t[0], 16) / 255,
|
|
4606
|
-
return [e,
|
|
4654
|
+
const e = parseInt(t[0] + t[0], 16) / 255, i = parseInt(t[1] + t[1], 16) / 255, n = parseInt(t[2] + t[2], 16) / 255;
|
|
4655
|
+
return [e, i, n];
|
|
4607
4656
|
}
|
|
4608
4657
|
if (t.length === 6) {
|
|
4609
|
-
const e = parseInt(t.substring(0, 2), 16) / 255,
|
|
4610
|
-
return [e,
|
|
4658
|
+
const e = parseInt(t.substring(0, 2), 16) / 255, i = parseInt(t.substring(2, 4), 16) / 255, n = parseInt(t.substring(4, 6), 16) / 255;
|
|
4659
|
+
return [e, i, n];
|
|
4611
4660
|
}
|
|
4612
4661
|
return [0, 0, 0];
|
|
4613
4662
|
}
|
|
@@ -4618,8 +4667,8 @@ function W(s, t, e) {
|
|
|
4618
4667
|
return s + (t - s) * e;
|
|
4619
4668
|
}
|
|
4620
4669
|
const N = 100, Kt = 0.06;
|
|
4621
|
-
function
|
|
4622
|
-
const e = t?.sensitivityX ?? 1,
|
|
4670
|
+
function wi(s, t) {
|
|
4671
|
+
const e = t?.sensitivityX ?? 1, i = t?.sensitivityY ?? 1, n = t?.lerpFactor ?? 0.08;
|
|
4623
4672
|
let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0;
|
|
4624
4673
|
const f = (p) => {
|
|
4625
4674
|
const d = s.getBoundingClientRect(), y = (p.clientX - d.left) / d.width * 2 - 1, b = (p.clientY - d.top) / d.height * 2 - 1;
|
|
@@ -4627,14 +4676,14 @@ function Rn(s, t) {
|
|
|
4627
4676
|
}, u = () => {
|
|
4628
4677
|
r = 0, o = 0;
|
|
4629
4678
|
}, x = () => {
|
|
4630
|
-
c && (l = W(l, r,
|
|
4679
|
+
c && (l = W(l, r, n), a = W(a, o, n), s.input = { x: l * e, y: a * i }, h = requestAnimationFrame(x));
|
|
4631
4680
|
};
|
|
4632
4681
|
return s.addEventListener("mousemove", f), s.addEventListener("mouseleave", u), h = requestAnimationFrame(x), () => {
|
|
4633
4682
|
c = !1, cancelAnimationFrame(h), s.removeEventListener("mousemove", f), s.removeEventListener("mouseleave", u);
|
|
4634
4683
|
};
|
|
4635
4684
|
}
|
|
4636
|
-
function
|
|
4637
|
-
const e = t?.sensitivityX ?? 1,
|
|
4685
|
+
function Ri(s, t) {
|
|
4686
|
+
const e = t?.sensitivityX ?? 1, i = t?.sensitivityY ?? 1, n = t?.lerpFactor ?? 0.08;
|
|
4638
4687
|
let r = 0, o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = !0;
|
|
4639
4688
|
const x = (b) => {
|
|
4640
4689
|
const E = b.touches[0];
|
|
@@ -4647,19 +4696,19 @@ function An(s, t) {
|
|
|
4647
4696
|
}, d = () => {
|
|
4648
4697
|
r = 0, o = 0;
|
|
4649
4698
|
}, y = () => {
|
|
4650
|
-
u && (l = W(l, r,
|
|
4699
|
+
u && (l = W(l, r, n), a = W(a, o, n), s.input = { x: l * e, y: a * i }, f = requestAnimationFrame(y));
|
|
4651
4700
|
};
|
|
4652
4701
|
return s.addEventListener("touchstart", x, { passive: !0 }), s.addEventListener("touchmove", p, { passive: !0 }), s.addEventListener("touchend", d, { passive: !0 }), s.addEventListener("touchcancel", d, { passive: !0 }), f = requestAnimationFrame(y), () => {
|
|
4653
4702
|
u = !1, cancelAnimationFrame(f), s.removeEventListener("touchstart", x), s.removeEventListener("touchmove", p), s.removeEventListener("touchend", d), s.removeEventListener("touchcancel", d);
|
|
4654
4703
|
};
|
|
4655
4704
|
}
|
|
4656
|
-
function
|
|
4657
|
-
const e = t?.sensitivityX ?? 1,
|
|
4705
|
+
function Ai(s, t) {
|
|
4706
|
+
const e = t?.sensitivityX ?? 1, i = t?.sensitivityY ?? 1, n = t?.lerpFactor ?? Kt;
|
|
4658
4707
|
let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0, f = !1;
|
|
4659
4708
|
const u = (y) => {
|
|
4660
4709
|
r = V((y.gamma ?? 0) / 45, -1, 1), o = V((y.beta ?? 0) / 45, -1, 1);
|
|
4661
4710
|
}, x = () => {
|
|
4662
|
-
c && (l = W(l, r,
|
|
4711
|
+
c && (l = W(l, r, n), a = W(a, o, n), s.input = { x: l * e, y: a * i }, h = requestAnimationFrame(x));
|
|
4663
4712
|
}, p = () => {
|
|
4664
4713
|
c && !f && (window.addEventListener("deviceorientation", u), f = !0);
|
|
4665
4714
|
}, d = DeviceOrientationEvent;
|
|
@@ -4670,8 +4719,8 @@ function Pn(s, t) {
|
|
|
4670
4719
|
c = !1, cancelAnimationFrame(h), f && (window.removeEventListener("deviceorientation", u), f = !1);
|
|
4671
4720
|
};
|
|
4672
4721
|
}
|
|
4673
|
-
function
|
|
4674
|
-
const e = t?.sensitivityX ?? 1,
|
|
4722
|
+
function Pi(s, t) {
|
|
4723
|
+
const e = t?.sensitivityX ?? 1, i = t?.sensitivityY ?? 1, n = t?.lerpFactor ?? 0.08, r = t?.lerpFactor ?? Kt;
|
|
4675
4724
|
let o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = 0, x = 0, p = !1, d = !1, y = !1, b = 0, E = 0, g = 0, v = !0;
|
|
4676
4725
|
const m = (S) => {
|
|
4677
4726
|
const D = s.getBoundingClientRect(), U = (S.clientX - D.left) / D.width * 2 - 1, M = (S.clientY - D.top) / D.height * 2 - 1;
|
|
@@ -4702,7 +4751,7 @@ function Dn(s, t) {
|
|
|
4702
4751
|
}, C = () => {
|
|
4703
4752
|
if (!v) return;
|
|
4704
4753
|
let S, D, U;
|
|
4705
|
-
p ? (S = a, D = h, U =
|
|
4754
|
+
p ? (S = a, D = h, U = n) : d ? (S = c, D = f, U = r) : (S = o, D = l, U = n), u = W(u, S, U), x = W(x, D, U), s.input = { x: u * e, y: x * i }, g = requestAnimationFrame(C);
|
|
4706
4755
|
};
|
|
4707
4756
|
return s.addEventListener("mousemove", m), s.addEventListener("mouseleave", T), s.addEventListener("touchstart", w, { passive: !0 }), s.addEventListener("touchmove", A, { passive: !0 }), s.addEventListener("touchend", P, { passive: !0 }), s.addEventListener("touchcancel", P, { passive: !0 }), g = requestAnimationFrame(C), () => {
|
|
4708
4757
|
v = !1, cancelAnimationFrame(g), s.removeEventListener("mousemove", m), s.removeEventListener("mouseleave", T), s.removeEventListener("touchstart", w), s.removeEventListener("touchmove", A), s.removeEventListener("touchend", P), s.removeEventListener("touchcancel", P), y && (window.removeEventListener("deviceorientation", F), y = !1);
|
|
@@ -4713,8 +4762,8 @@ customElements.get(Et.TAG_NAME) || customElements.define(Et.TAG_NAME, Et);
|
|
|
4713
4762
|
export {
|
|
4714
4763
|
xt as LayershiftElement,
|
|
4715
4764
|
Et as LayershiftPortalElement,
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4765
|
+
Ai as connectGyro,
|
|
4766
|
+
wi as connectMouse,
|
|
4767
|
+
Pi as connectPointer,
|
|
4768
|
+
Ri as connectTouch
|
|
4720
4769
|
};
|