layershift 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/layershift.js +87 -45
- package/dist/npm/layershift.es.js +1074 -910
- package/dist/types/components/layershift/index.d.ts +2 -2
- package/dist/types/components/layershift/index.d.ts.map +1 -1
- package/dist/types/components/layershift/layershift-element.d.ts +1 -1
- package/dist/types/components/layershift/layershift-element.d.ts.map +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 +2 -2
- package/dist/types/components/layershift/types.d.ts.map +1 -1
- package/dist/types/depth/depth-analysis.d.ts.map +1 -0
- package/dist/types/{depth-estimator.d.ts → depth/depth-estimator.d.ts} +4 -15
- package/dist/types/depth/depth-estimator.d.ts.map +1 -0
- package/dist/types/depth/depth-preprocess.d.ts +26 -0
- package/dist/types/depth/depth-preprocess.d.ts.map +1 -0
- package/dist/types/depth/precomputed-depth.d.ts.map +1 -0
- package/dist/types/depth/workers/preprocess-worker.d.ts +36 -0
- package/dist/types/depth/workers/preprocess-worker.d.ts.map +1 -0
- package/dist/types/{quality.d.ts → gpu/quality.d.ts} +4 -4
- package/dist/types/gpu/quality.d.ts.map +1 -0
- package/dist/types/gpu/webgl-utils.d.ts.map +1 -0
- package/dist/types/media/input-handler.d.ts.map +1 -0
- package/dist/types/media/input-helpers.d.ts.map +1 -0
- package/dist/types/media/media-source.d.ts.map +1 -0
- package/dist/types/{depth-effect-renderer.d.ts → renderers/depth-effect-renderer.d.ts} +21 -4
- package/dist/types/renderers/depth-effect-renderer.d.ts.map +1 -0
- package/dist/types/renderers/jfa-distance-field.d.ts.map +1 -0
- package/dist/types/{portal-renderer.d.ts → renderers/portal-renderer.d.ts} +4 -3
- package/dist/types/renderers/portal-renderer.d.ts.map +1 -0
- package/dist/types/renderers/render-pass.d.ts.map +1 -0
- package/dist/types/{renderer-base.d.ts → renderers/renderer-base.d.ts} +3 -3
- package/dist/types/renderers/renderer-base.d.ts.map +1 -0
- package/dist/types/renderers/shape-generator.d.ts.map +1 -0
- package/package.json +8 -2
- package/dist/types/depth-analysis.d.ts.map +0 -1
- package/dist/types/depth-effect-renderer.d.ts.map +0 -1
- package/dist/types/depth-estimator.d.ts.map +0 -1
- package/dist/types/input-handler.d.ts.map +0 -1
- package/dist/types/input-helpers.d.ts.map +0 -1
- package/dist/types/jfa-distance-field.d.ts.map +0 -1
- package/dist/types/media-source.d.ts.map +0 -1
- package/dist/types/portal-renderer.d.ts.map +0 -1
- package/dist/types/precomputed-depth.d.ts.map +0 -1
- package/dist/types/quality.d.ts.map +0 -1
- package/dist/types/render-pass.d.ts.map +0 -1
- package/dist/types/renderer-base.d.ts.map +0 -1
- package/dist/types/shape-generator.d.ts.map +0 -1
- package/dist/types/video-source.d.ts +0 -22
- package/dist/types/video-source.d.ts.map +0 -1
- package/dist/types/webgl-utils.d.ts.map +0 -1
- /package/dist/types/{depth-analysis.d.ts → depth/depth-analysis.d.ts} +0 -0
- /package/dist/types/{precomputed-depth.d.ts → depth/precomputed-depth.d.ts} +0 -0
- /package/dist/types/{webgl-utils.d.ts → gpu/webgl-utils.d.ts} +0 -0
- /package/dist/types/{input-handler.d.ts → media/input-handler.d.ts} +0 -0
- /package/dist/types/{input-helpers.d.ts → media/input-helpers.d.ts} +0 -0
- /package/dist/types/{media-source.d.ts → media/media-source.d.ts} +0 -0
- /package/dist/types/{jfa-distance-field.d.ts → renderers/jfa-distance-field.d.ts} +0 -0
- /package/dist/types/{render-pass.d.ts → renderers/render-pass.d.ts} +0 -0
- /package/dist/types/{shape-generator.d.ts → renderers/shape-generator.d.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Vt {
|
|
2
2
|
constructor(t) {
|
|
3
3
|
this.depthData = t;
|
|
4
4
|
const e = t.meta.width * t.meta.height;
|
|
@@ -10,29 +10,29 @@ class Bt {
|
|
|
10
10
|
lastNextFrameIndex = -1;
|
|
11
11
|
lastLerpFactor = -1;
|
|
12
12
|
sample(t) {
|
|
13
|
-
const e =
|
|
14
|
-
if (!
|
|
13
|
+
const e = re(t * this.depthData.meta.fps, 0, this.depthData.meta.frameCount - 1), n = Math.floor(e), i = Math.min(n + 1, this.depthData.meta.frameCount - 1), r = e - n, o = n !== this.lastFrameIndex || i !== this.lastNextFrameIndex, l = Math.abs(r - this.lastLerpFactor) > 1e-3;
|
|
14
|
+
if (!o && !l)
|
|
15
15
|
return this.uint8Output;
|
|
16
16
|
this.lastFrameIndex = n, this.lastNextFrameIndex = i, this.lastLerpFactor = r;
|
|
17
|
-
const
|
|
17
|
+
const a = 1 - r, h = this.depthData.frames[n], c = this.depthData.frames[i];
|
|
18
18
|
for (let f = 0; f < this.uint8Output.length; f += 1)
|
|
19
|
-
this.uint8Output[f] =
|
|
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
|
|
23
|
+
async function kt(s, t, e) {
|
|
24
24
|
const [n, i] = await Promise.all([
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
te(t),
|
|
26
|
+
ee(s)
|
|
27
27
|
]);
|
|
28
|
-
return
|
|
28
|
+
return ne(i, n);
|
|
29
29
|
}
|
|
30
|
-
async function
|
|
31
|
-
const t = await fetch(
|
|
30
|
+
async function te(s) {
|
|
31
|
+
const t = await fetch(s);
|
|
32
32
|
if (!t.ok)
|
|
33
33
|
throw new Error(`Failed to fetch depth metadata (${t.status} ${t.statusText}).`);
|
|
34
34
|
const e = await t.json();
|
|
35
|
-
return
|
|
35
|
+
return ie(e), {
|
|
36
36
|
frameCount: e.frameCount,
|
|
37
37
|
fps: e.fps,
|
|
38
38
|
width: e.width,
|
|
@@ -40,8 +40,8 @@ async function Qt(o) {
|
|
|
40
40
|
sourceFps: e.sourceFps
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
async function
|
|
44
|
-
const e = await fetch(
|
|
43
|
+
async function ee(s, t) {
|
|
44
|
+
const e = await fetch(s);
|
|
45
45
|
if (!e.ok)
|
|
46
46
|
throw new Error(`Failed to fetch depth data (${e.status} ${e.statusText}).`);
|
|
47
47
|
e.headers.get("content-length");
|
|
@@ -50,55 +50,55 @@ async function te(o, t) {
|
|
|
50
50
|
return new Uint8Array(await e.arrayBuffer());
|
|
51
51
|
const i = [];
|
|
52
52
|
let r = 0;
|
|
53
|
-
const
|
|
53
|
+
const o = n.getReader();
|
|
54
54
|
for (; ; ) {
|
|
55
|
-
const { done:
|
|
56
|
-
if (
|
|
55
|
+
const { done: h, value: c } = await o.read();
|
|
56
|
+
if (h)
|
|
57
57
|
break;
|
|
58
|
-
|
|
58
|
+
c && (i.push(c), r += c.byteLength);
|
|
59
59
|
}
|
|
60
|
-
const
|
|
61
|
-
let
|
|
62
|
-
for (const
|
|
63
|
-
|
|
64
|
-
return
|
|
60
|
+
const l = new Uint8Array(r);
|
|
61
|
+
let a = 0;
|
|
62
|
+
for (const h of i)
|
|
63
|
+
l.set(h, a), a += h.byteLength;
|
|
64
|
+
return l;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
if (
|
|
66
|
+
function ne(s, t) {
|
|
67
|
+
if (s.byteLength < 4)
|
|
68
68
|
throw new Error("Depth data binary is missing the frame-count header.");
|
|
69
|
-
const n = new DataView(
|
|
70
|
-
if (
|
|
69
|
+
const n = new DataView(s.buffer, s.byteOffset, s.byteLength).getUint32(0, !0), i = t.width * t.height, r = 4 + n * i;
|
|
70
|
+
if (s.byteLength !== r)
|
|
71
71
|
throw new Error(
|
|
72
|
-
`Depth data byte length mismatch. Expected ${r} bytes, received ${
|
|
72
|
+
`Depth data byte length mismatch. Expected ${r} bytes, received ${s.byteLength}.`
|
|
73
73
|
);
|
|
74
74
|
if (n !== t.frameCount)
|
|
75
75
|
throw new Error(
|
|
76
76
|
`Depth frame count mismatch between metadata (${t.frameCount}) and binary header (${n}).`
|
|
77
77
|
);
|
|
78
|
-
const
|
|
79
|
-
for (let
|
|
80
|
-
const
|
|
81
|
-
a
|
|
78
|
+
const o = s.subarray(4), l = new Array(n);
|
|
79
|
+
for (let a = 0; a < n; a += 1) {
|
|
80
|
+
const h = a * i;
|
|
81
|
+
l[a] = o.subarray(h, h + i);
|
|
82
82
|
}
|
|
83
|
-
return { meta: t, frames:
|
|
83
|
+
return { meta: t, frames: l };
|
|
84
84
|
}
|
|
85
|
-
function
|
|
86
|
-
if (!
|
|
85
|
+
function ie(s) {
|
|
86
|
+
if (!s || typeof s.frameCount != "number" || typeof s.fps != "number" || typeof s.width != "number" || typeof s.height != "number" || typeof s.sourceFps != "number")
|
|
87
87
|
throw new Error("Depth metadata is malformed.");
|
|
88
|
-
if (!Number.isFinite(
|
|
88
|
+
if (!Number.isFinite(s.frameCount) || !Number.isFinite(s.fps) || !Number.isFinite(s.width) || !Number.isFinite(s.height) || !Number.isFinite(s.sourceFps) || s.frameCount <= 0 || s.fps <= 0 || s.width <= 0 || s.height <= 0 || s.sourceFps <= 0)
|
|
89
89
|
throw new Error("Depth metadata contains invalid numeric values.");
|
|
90
90
|
}
|
|
91
|
-
function N(
|
|
92
|
-
const e = new Uint8Array(
|
|
91
|
+
function N(s, t) {
|
|
92
|
+
const e = new Uint8Array(s * t);
|
|
93
93
|
return e.fill(128), {
|
|
94
|
-
meta: { frameCount: 1, fps: 1, width:
|
|
94
|
+
meta: { frameCount: 1, fps: 1, width: s, height: t, sourceFps: 1 },
|
|
95
95
|
frames: [e]
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
function
|
|
99
|
-
return Math.min(e, Math.max(t,
|
|
98
|
+
function re(s, t, e) {
|
|
99
|
+
return Math.min(e, Math.max(t, s));
|
|
100
100
|
}
|
|
101
|
-
const
|
|
101
|
+
const se = {
|
|
102
102
|
parallaxStrength: 0.05,
|
|
103
103
|
contrastLow: 0.05,
|
|
104
104
|
contrastHigh: 0.95,
|
|
@@ -108,29 +108,29 @@ const re = {
|
|
|
108
108
|
pomSteps: 16,
|
|
109
109
|
overscanPadding: 0.08
|
|
110
110
|
};
|
|
111
|
-
function oe(
|
|
111
|
+
function oe(s, t, e) {
|
|
112
112
|
const n = new Float32Array(256);
|
|
113
|
-
if (
|
|
113
|
+
if (s.length === 0 || t <= 0 || e <= 0)
|
|
114
114
|
return Pt(n);
|
|
115
|
-
const i =
|
|
116
|
-
let
|
|
117
|
-
const
|
|
115
|
+
const i = le(s.length), r = t * e;
|
|
116
|
+
let o = 0;
|
|
117
|
+
const l = new Uint32Array(256);
|
|
118
118
|
for (const m of i) {
|
|
119
|
-
const T =
|
|
119
|
+
const T = s[m], w = Math.min(T.length, r);
|
|
120
120
|
for (let A = 0; A < w; A += 1)
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
l[T[A]] += 1;
|
|
122
|
+
o += w;
|
|
123
123
|
}
|
|
124
|
-
if (
|
|
124
|
+
if (o === 0)
|
|
125
125
|
return Pt(n);
|
|
126
|
-
const
|
|
126
|
+
const a = 1 / o;
|
|
127
127
|
for (let m = 0; m < 256; m += 1)
|
|
128
|
-
n[m] =
|
|
129
|
-
const
|
|
130
|
-
|
|
128
|
+
n[m] = l[m] * a;
|
|
129
|
+
const h = new Float32Array(256);
|
|
130
|
+
h[0] = n[0];
|
|
131
131
|
for (let m = 1; m < 256; m += 1)
|
|
132
|
-
|
|
133
|
-
const
|
|
132
|
+
h[m] = h[m - 1] + n[m];
|
|
133
|
+
const c = nt(h, 0.05), f = nt(h, 0.25), u = nt(h, 0.5), x = nt(h, 0.75), p = nt(h, 0.95);
|
|
134
134
|
let d = 0;
|
|
135
135
|
for (let m = 0; m < 256; m += 1)
|
|
136
136
|
d += m / 255 * n[m];
|
|
@@ -139,92 +139,92 @@ function oe(o, t, e) {
|
|
|
139
139
|
const T = m / 255 - d;
|
|
140
140
|
y += n[m] * T * T;
|
|
141
141
|
}
|
|
142
|
-
const E = Math.sqrt(y), b =
|
|
142
|
+
const E = Math.sqrt(y), b = p - c, g = x - f, v = ue(n);
|
|
143
143
|
return {
|
|
144
144
|
mean: d,
|
|
145
145
|
stdDev: E,
|
|
146
|
-
p5:
|
|
146
|
+
p5: c,
|
|
147
147
|
p25: f,
|
|
148
|
-
median:
|
|
148
|
+
median: u,
|
|
149
149
|
p75: x,
|
|
150
|
-
p95:
|
|
150
|
+
p95: p,
|
|
151
151
|
effectiveRange: b,
|
|
152
|
-
iqr:
|
|
152
|
+
iqr: g,
|
|
153
153
|
bimodality: v,
|
|
154
154
|
histogram: n
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
|
-
function
|
|
158
|
-
if (
|
|
159
|
-
return { ...
|
|
160
|
-
const t =
|
|
157
|
+
function ae(s) {
|
|
158
|
+
if (s.effectiveRange < 0.05 || s.stdDev < 0.02)
|
|
159
|
+
return { ...se };
|
|
160
|
+
const t = s.effectiveRange - 0.5, e = s.bimodality - 0.4, n = H(
|
|
161
161
|
0.05 - t * 0.03 + e * 0.01,
|
|
162
162
|
0.035,
|
|
163
163
|
0.065
|
|
164
|
-
), i =
|
|
164
|
+
), i = H(s.p5 - 0.03, 0, 0.25), r = H(s.p95 + 0.03, 0.75, 1), o = H((n - 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(n + 0.03, 0.06, 0.1);
|
|
165
165
|
return {
|
|
166
166
|
parallaxStrength: n,
|
|
167
167
|
contrastLow: i,
|
|
168
168
|
contrastHigh: r,
|
|
169
|
-
verticalReduction:
|
|
170
|
-
dofStart:
|
|
171
|
-
dofStrength:
|
|
172
|
-
pomSteps:
|
|
169
|
+
verticalReduction: l,
|
|
170
|
+
dofStart: a,
|
|
171
|
+
dofStrength: h,
|
|
172
|
+
pomSteps: c,
|
|
173
173
|
overscanPadding: f
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
function
|
|
177
|
-
if (
|
|
178
|
-
if (
|
|
179
|
-
const t =
|
|
176
|
+
function le(s) {
|
|
177
|
+
if (s <= 0) return [];
|
|
178
|
+
if (s === 1) return [0];
|
|
179
|
+
const t = s - 1, e = [
|
|
180
180
|
0,
|
|
181
|
-
Math.floor(
|
|
182
|
-
Math.floor(
|
|
183
|
-
Math.floor(3 *
|
|
181
|
+
Math.floor(s / 4),
|
|
182
|
+
Math.floor(s / 2),
|
|
183
|
+
Math.floor(3 * s / 4),
|
|
184
184
|
t
|
|
185
185
|
], n = /* @__PURE__ */ new Set(), i = [];
|
|
186
186
|
for (const r of e)
|
|
187
187
|
n.has(r) || (n.add(r), i.push(r));
|
|
188
188
|
return i;
|
|
189
189
|
}
|
|
190
|
-
function
|
|
190
|
+
function nt(s, t) {
|
|
191
191
|
for (let e = 0; e < 256; e += 1)
|
|
192
|
-
if (
|
|
192
|
+
if (s[e] >= t)
|
|
193
193
|
return e / 255;
|
|
194
194
|
return 1;
|
|
195
195
|
}
|
|
196
|
-
function
|
|
196
|
+
function ue(s) {
|
|
197
197
|
const t = new Float32Array(256);
|
|
198
|
-
for (let
|
|
199
|
-
let x = 0,
|
|
200
|
-
for (let d =
|
|
201
|
-
d >= 0 && d < 256 && (x +=
|
|
202
|
-
t[
|
|
198
|
+
for (let u = 0; u < 256; u += 1) {
|
|
199
|
+
let x = 0, p = 0;
|
|
200
|
+
for (let d = u - 2; d <= u + 2; d += 1)
|
|
201
|
+
d >= 0 && d < 256 && (x += s[d], p += 1);
|
|
202
|
+
t[u] = x / p;
|
|
203
203
|
}
|
|
204
204
|
let e = 0;
|
|
205
|
-
for (let
|
|
206
|
-
e += t[
|
|
205
|
+
for (let u = 0; u < 256; u += 1)
|
|
206
|
+
e += t[u];
|
|
207
207
|
e /= 256;
|
|
208
208
|
const n = e * 2, i = 25, r = [];
|
|
209
|
-
for (let
|
|
210
|
-
t[
|
|
211
|
-
if (t[0] > t[1] && t[0] >= n && r.push({ bin: 0, height: t[0] }), t[255] > t[254] && t[255] >= n && r.push({ bin: 255, height: t[255] }), r.sort((
|
|
212
|
-
const
|
|
213
|
-
let
|
|
214
|
-
for (let
|
|
215
|
-
if (Math.abs(r[
|
|
216
|
-
|
|
209
|
+
for (let u = 1; u < 255; u += 1)
|
|
210
|
+
t[u] > t[u - 1] && t[u] > t[u + 1] && t[u] >= n && r.push({ bin: u, height: t[u] });
|
|
211
|
+
if (t[0] > t[1] && t[0] >= n && r.push({ bin: 0, height: t[0] }), t[255] > t[254] && t[255] >= n && r.push({ bin: 255, height: t[255] }), r.sort((u, x) => x.height - u.height), r.length < 2) return 0;
|
|
212
|
+
const o = r[0];
|
|
213
|
+
let l = null;
|
|
214
|
+
for (let u = 1; u < r.length; u += 1)
|
|
215
|
+
if (Math.abs(r[u].bin - o.bin) >= i) {
|
|
216
|
+
l = r[u];
|
|
217
217
|
break;
|
|
218
218
|
}
|
|
219
|
-
if (!
|
|
220
|
-
const
|
|
221
|
-
let
|
|
222
|
-
for (let
|
|
223
|
-
t[
|
|
224
|
-
const f = Math.min(
|
|
225
|
-
return f <= 0 ? 0 :
|
|
226
|
-
}
|
|
227
|
-
function Pt(
|
|
219
|
+
if (!l) return 0;
|
|
220
|
+
const a = Math.min(o.bin, l.bin), h = Math.max(o.bin, l.bin);
|
|
221
|
+
let c = 1 / 0;
|
|
222
|
+
for (let u = a; u <= h; u += 1)
|
|
223
|
+
t[u] < c && (c = t[u]);
|
|
224
|
+
const f = Math.min(o.height, l.height);
|
|
225
|
+
return f <= 0 ? 0 : H(1 - c / f, 0, 1);
|
|
226
|
+
}
|
|
227
|
+
function Pt(s) {
|
|
228
228
|
return {
|
|
229
229
|
mean: 0,
|
|
230
230
|
stdDev: 0,
|
|
@@ -236,39 +236,39 @@ function Pt(o) {
|
|
|
236
236
|
effectiveRange: 0,
|
|
237
237
|
iqr: 0,
|
|
238
238
|
bimodality: 0,
|
|
239
|
-
histogram:
|
|
239
|
+
histogram: s
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
|
-
function
|
|
243
|
-
return Math.min(e, Math.max(t,
|
|
242
|
+
function H(s, t, e) {
|
|
243
|
+
return Math.min(e, Math.max(t, s));
|
|
244
244
|
}
|
|
245
|
-
function
|
|
246
|
-
const n =
|
|
245
|
+
function G(s, t, e) {
|
|
246
|
+
const n = s.createShader(t);
|
|
247
247
|
if (!n) throw new Error("Failed to create shader.");
|
|
248
|
-
if (
|
|
249
|
-
const i =
|
|
250
|
-
throw
|
|
248
|
+
if (s.shaderSource(n, e), s.compileShader(n), !s.getShaderParameter(n, s.COMPILE_STATUS)) {
|
|
249
|
+
const i = s.getShaderInfoLog(n) ?? "";
|
|
250
|
+
throw s.deleteShader(n), new Error(`Shader compilation failed:
|
|
251
251
|
${i}`);
|
|
252
252
|
}
|
|
253
253
|
return n;
|
|
254
254
|
}
|
|
255
|
-
function
|
|
256
|
-
const n =
|
|
255
|
+
function mt(s, t, e) {
|
|
256
|
+
const n = s.createProgram();
|
|
257
257
|
if (!n) throw new Error("Failed to create program.");
|
|
258
|
-
if (
|
|
259
|
-
const i =
|
|
260
|
-
throw
|
|
258
|
+
if (s.attachShader(n, t), s.attachShader(n, e), s.linkProgram(n), !s.getProgramParameter(n, s.LINK_STATUS)) {
|
|
259
|
+
const i = s.getProgramInfoLog(n) ?? "";
|
|
260
|
+
throw s.deleteProgram(n), new Error(`Program linking failed:
|
|
261
261
|
${i}`);
|
|
262
262
|
}
|
|
263
|
-
return
|
|
263
|
+
return s.detachShader(n, t), s.detachShader(n, e), s.deleteShader(t), s.deleteShader(e), n;
|
|
264
264
|
}
|
|
265
|
-
function
|
|
265
|
+
function pt(s, t, e) {
|
|
266
266
|
const n = {};
|
|
267
267
|
for (const i of e)
|
|
268
|
-
n[i] =
|
|
268
|
+
n[i] = s.getUniformLocation(t, i);
|
|
269
269
|
return n;
|
|
270
270
|
}
|
|
271
|
-
const
|
|
271
|
+
const ce = new Float32Array([
|
|
272
272
|
-1,
|
|
273
273
|
-1,
|
|
274
274
|
1,
|
|
@@ -278,16 +278,16 @@ const ue = new Float32Array([
|
|
|
278
278
|
1,
|
|
279
279
|
1
|
|
280
280
|
]);
|
|
281
|
-
function Ot(
|
|
282
|
-
const e =
|
|
281
|
+
function Ot(s, t) {
|
|
282
|
+
const e = s.createVertexArray();
|
|
283
283
|
if (!e) throw new Error("Failed to create VAO.");
|
|
284
|
-
|
|
285
|
-
const n =
|
|
286
|
-
|
|
287
|
-
const i =
|
|
288
|
-
return
|
|
284
|
+
s.bindVertexArray(e);
|
|
285
|
+
const n = s.createBuffer();
|
|
286
|
+
s.bindBuffer(s.ARRAY_BUFFER, n), s.bufferData(s.ARRAY_BUFFER, ce, s.STATIC_DRAW);
|
|
287
|
+
const i = s.getAttribLocation(t, "aPosition");
|
|
288
|
+
return s.enableVertexAttribArray(i), s.vertexAttribPointer(i, 2, s.FLOAT, !1, 0, 0), s.bindVertexArray(null), e;
|
|
289
289
|
}
|
|
290
|
-
class
|
|
290
|
+
class Ht {
|
|
291
291
|
slots = /* @__PURE__ */ new Map();
|
|
292
292
|
nextUnit = 0;
|
|
293
293
|
/**
|
|
@@ -323,18 +323,56 @@ class kt {
|
|
|
323
323
|
return this.slots.size;
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
|
-
function
|
|
327
|
-
const r =
|
|
326
|
+
function O(s, t, e, n, i) {
|
|
327
|
+
const r = G(s, s.VERTEX_SHADER, e), o = G(s, s.FRAGMENT_SHADER, n), l = mt(s, r, o), a = pt(s, l, i);
|
|
328
328
|
return {
|
|
329
|
+
name: t,
|
|
330
|
+
program: l,
|
|
331
|
+
uniforms: a,
|
|
332
|
+
dispose(h) {
|
|
333
|
+
h.deleteProgram(l);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function Dt(s, t, e, n, i, r) {
|
|
338
|
+
const o = G(s, s.VERTEX_SHADER, e), l = G(s, s.FRAGMENT_SHADER, n), a = mt(s, o, l), h = pt(s, a, i), c = {
|
|
339
|
+
texture: null,
|
|
340
|
+
unit: r.textureUnit,
|
|
341
|
+
attachment: s.COLOR_ATTACHMENT0
|
|
342
|
+
}, f = {
|
|
329
343
|
name: t,
|
|
330
344
|
program: a,
|
|
331
|
-
uniforms:
|
|
332
|
-
|
|
333
|
-
|
|
345
|
+
uniforms: h,
|
|
346
|
+
fbo: null,
|
|
347
|
+
outputs: [c],
|
|
348
|
+
width: 0,
|
|
349
|
+
height: 0,
|
|
350
|
+
resize(u, x, p) {
|
|
351
|
+
f.fbo && u.deleteFramebuffer(f.fbo), c.texture && u.deleteTexture(c.texture), f.width = x, f.height = p, c.texture = u.createTexture(), u.activeTexture(u.TEXTURE0 + c.unit), u.bindTexture(u.TEXTURE_2D, c.texture), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_MIN_FILTER, u.LINEAR), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_MAG_FILTER, u.LINEAR), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_WRAP_S, u.CLAMP_TO_EDGE), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_WRAP_T, u.CLAMP_TO_EDGE), u.texImage2D(
|
|
352
|
+
u.TEXTURE_2D,
|
|
353
|
+
0,
|
|
354
|
+
r.internalFormat,
|
|
355
|
+
x,
|
|
356
|
+
p,
|
|
357
|
+
0,
|
|
358
|
+
r.format,
|
|
359
|
+
r.type,
|
|
360
|
+
null
|
|
361
|
+
), f.fbo = u.createFramebuffer(), u.bindFramebuffer(u.FRAMEBUFFER, f.fbo), u.framebufferTexture2D(
|
|
362
|
+
u.FRAMEBUFFER,
|
|
363
|
+
u.COLOR_ATTACHMENT0,
|
|
364
|
+
u.TEXTURE_2D,
|
|
365
|
+
c.texture,
|
|
366
|
+
0
|
|
367
|
+
), u.bindFramebuffer(u.FRAMEBUFFER, null);
|
|
368
|
+
},
|
|
369
|
+
dispose(u) {
|
|
370
|
+
f.fbo && (u.deleteFramebuffer(f.fbo), f.fbo = null), c.texture && (u.deleteTexture(c.texture), c.texture = null), u.deleteProgram(a);
|
|
334
371
|
}
|
|
335
372
|
};
|
|
373
|
+
return r.width > 0 && r.height > 0 && f.resize(s, r.width, r.height), f;
|
|
336
374
|
}
|
|
337
|
-
const
|
|
375
|
+
const he = {
|
|
338
376
|
high: {
|
|
339
377
|
dprCap: 2,
|
|
340
378
|
depthMaxDim: 512,
|
|
@@ -344,8 +382,8 @@ const ce = {
|
|
|
344
382
|
},
|
|
345
383
|
medium: {
|
|
346
384
|
dprCap: 1.5,
|
|
347
|
-
depthMaxDim:
|
|
348
|
-
pomSteps:
|
|
385
|
+
depthMaxDim: 384,
|
|
386
|
+
pomSteps: 12,
|
|
349
387
|
bilateralRadius: 2,
|
|
350
388
|
jfaDivisor: 2
|
|
351
389
|
},
|
|
@@ -357,22 +395,22 @@ const ce = {
|
|
|
357
395
|
jfaDivisor: 4
|
|
358
396
|
}
|
|
359
397
|
};
|
|
360
|
-
function
|
|
398
|
+
function fe(s) {
|
|
361
399
|
let t = "unknown";
|
|
362
|
-
const e =
|
|
363
|
-
e && (t =
|
|
364
|
-
const n =
|
|
400
|
+
const e = s.getExtension("WEBGL_debug_renderer_info");
|
|
401
|
+
e && (t = s.getParameter(e.UNMASKED_RENDERER_WEBGL) || "unknown");
|
|
402
|
+
const n = s.getParameter(s.MAX_TEXTURE_SIZE), i = 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;
|
|
365
403
|
return {
|
|
366
404
|
gpuRenderer: t,
|
|
367
405
|
maxTextureSize: n,
|
|
368
406
|
hardwareConcurrency: i,
|
|
369
407
|
deviceMemory: r,
|
|
370
|
-
devicePixelRatio:
|
|
371
|
-
screenPixels:
|
|
372
|
-
isMobile:
|
|
408
|
+
devicePixelRatio: o,
|
|
409
|
+
screenPixels: l,
|
|
410
|
+
isMobile: a && h
|
|
373
411
|
};
|
|
374
412
|
}
|
|
375
|
-
const
|
|
413
|
+
const de = [
|
|
376
414
|
"mali-4",
|
|
377
415
|
"mali-t",
|
|
378
416
|
"adreno 3",
|
|
@@ -385,7 +423,7 @@ const fe = [
|
|
|
385
423
|
"llvmpipe",
|
|
386
424
|
"swiftshader",
|
|
387
425
|
"software"
|
|
388
|
-
],
|
|
426
|
+
], me = [
|
|
389
427
|
"nvidia",
|
|
390
428
|
"geforce",
|
|
391
429
|
"radeon rx",
|
|
@@ -397,16 +435,16 @@ const fe = [
|
|
|
397
435
|
"mali-g7",
|
|
398
436
|
"mali-g6"
|
|
399
437
|
];
|
|
400
|
-
function
|
|
438
|
+
function pe(s) {
|
|
401
439
|
let t = 0;
|
|
402
|
-
const e =
|
|
403
|
-
return n && (t -= 30), i && (t += 20),
|
|
440
|
+
const e = s.gpuRenderer.toLowerCase(), n = de.some((r) => e.includes(r)), i = me.some((r) => e.includes(r));
|
|
441
|
+
return n && (t -= 30), i && (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";
|
|
404
442
|
}
|
|
405
|
-
function
|
|
406
|
-
const e = t && t !== "auto" ? t :
|
|
407
|
-
return { tier: e, ...
|
|
443
|
+
function Nt(s, t) {
|
|
444
|
+
const e = t && t !== "auto" ? t : pe(fe(s));
|
|
445
|
+
return { tier: e, ...he[e] };
|
|
408
446
|
}
|
|
409
|
-
class
|
|
447
|
+
class gt {
|
|
410
448
|
static RESIZE_DEBOUNCE_MS = 100;
|
|
411
449
|
// ---- Canvas + container ----
|
|
412
450
|
canvas;
|
|
@@ -449,7 +487,7 @@ class mt {
|
|
|
449
487
|
/** Adaptive quality parameters. Set by subclass constructor after GL init. */
|
|
450
488
|
qualityParams;
|
|
451
489
|
constructor(t) {
|
|
452
|
-
this.container = t, this.canvas = document.createElement("canvas"), this.container.appendChild(this.canvas), this.canvas.addEventListener("webglcontextlost", this._handleContextLost), this.canvas.addEventListener("webglcontextrestored", this._handleContextRestored);
|
|
490
|
+
this.container = t, this.canvas = document.createElement("canvas"), this.canvas.style.display = "block", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.container.appendChild(this.canvas), this.canvas.addEventListener("webglcontextlost", this._handleContextLost), this.canvas.addEventListener("webglcontextrestored", this._handleContextRestored);
|
|
453
491
|
}
|
|
454
492
|
/** The underlying canvas element. */
|
|
455
493
|
get canvasElement() {
|
|
@@ -531,7 +569,7 @@ class mt {
|
|
|
531
569
|
scheduleResizeRecalculate = () => {
|
|
532
570
|
this.resizeTimer !== null && window.clearTimeout(this.resizeTimer), this.resizeTimer = window.setTimeout(() => {
|
|
533
571
|
this.resizeTimer = null, this.recalculateViewportLayout();
|
|
534
|
-
},
|
|
572
|
+
}, gt.RESIZE_DEBOUNCE_MS);
|
|
535
573
|
};
|
|
536
574
|
/** Read the container's pixel dimensions, with a minimum of 1x1. */
|
|
537
575
|
getViewportSize() {
|
|
@@ -549,8 +587,8 @@ class mt {
|
|
|
549
587
|
this.sourceDepthWidth = t, this.sourceDepthHeight = e;
|
|
550
588
|
let i = t, r = e;
|
|
551
589
|
if (i > n || r > n) {
|
|
552
|
-
const
|
|
553
|
-
i = Math.max(1, Math.round(i *
|
|
590
|
+
const o = n / Math.max(i, r);
|
|
591
|
+
i = Math.max(1, Math.round(i * o)), r = Math.max(1, Math.round(r * o));
|
|
554
592
|
}
|
|
555
593
|
this.depthWidth = i, this.depthHeight = r, i !== t || r !== e ? this.depthSubsampleBuffer = new Uint8Array(i * r) : this.depthSubsampleBuffer = null;
|
|
556
594
|
}
|
|
@@ -563,11 +601,11 @@ class mt {
|
|
|
563
601
|
subsampleDepth(t) {
|
|
564
602
|
if (!this.depthSubsampleBuffer) return t;
|
|
565
603
|
const e = this.depthSubsampleBuffer, n = this.sourceDepthWidth, i = this.depthWidth, r = this.depthHeight;
|
|
566
|
-
for (let
|
|
567
|
-
const
|
|
568
|
-
for (let
|
|
569
|
-
const f = Math.min(Math.round(
|
|
570
|
-
e[
|
|
604
|
+
for (let o = 0; o < r; o++) {
|
|
605
|
+
const a = Math.min(Math.round(o * this.sourceDepthHeight / r), this.sourceDepthHeight - 1) * n, h = o * i;
|
|
606
|
+
for (let c = 0; c < i; c++) {
|
|
607
|
+
const f = Math.min(Math.round(c * n / i), n - 1);
|
|
608
|
+
e[h + c] = t[a + f];
|
|
571
609
|
}
|
|
572
610
|
}
|
|
573
611
|
return e;
|
|
@@ -583,14 +621,14 @@ class mt {
|
|
|
583
621
|
* Updates `this.uvOffset` and `this.uvScale`.
|
|
584
622
|
*/
|
|
585
623
|
computeCoverFitUV(t, e) {
|
|
586
|
-
const { width: n, height: i } = this.getViewportSize(), r = n / i,
|
|
587
|
-
let
|
|
588
|
-
r > this.videoAspect ?
|
|
589
|
-
const
|
|
590
|
-
|
|
624
|
+
const { width: n, height: i } = this.getViewportSize(), r = n / i, o = t + e;
|
|
625
|
+
let l = 1, a = 1;
|
|
626
|
+
r > this.videoAspect ? a = this.videoAspect / r : l = r / this.videoAspect;
|
|
627
|
+
const h = 1 + o * 2;
|
|
628
|
+
l /= h, a /= h, this.uvOffset = [(1 - l) / 2, (1 - a) / 2], this.uvScale = [l, a], this.isCameraSource && (this.uvOffset[0] += this.uvScale[0], this.uvScale[0] = -this.uvScale[0]);
|
|
591
629
|
}
|
|
592
630
|
}
|
|
593
|
-
const
|
|
631
|
+
const ge = `#version 300 es
|
|
594
632
|
in vec2 aPosition;
|
|
595
633
|
|
|
596
634
|
// UV coordinates for cover-fit + overscan.
|
|
@@ -611,7 +649,7 @@ void main() {
|
|
|
611
649
|
vScreenUv = baseUv;
|
|
612
650
|
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
613
651
|
}
|
|
614
|
-
`,
|
|
652
|
+
`, bt = `#version 300 es
|
|
615
653
|
in vec2 aPosition;
|
|
616
654
|
out vec2 vUv;
|
|
617
655
|
|
|
@@ -773,6 +811,9 @@ uniform float uGlowRadius;
|
|
|
773
811
|
/** Glow edge softness — controls blending of the glow mask. */
|
|
774
812
|
uniform float uGlowSoftness;
|
|
775
813
|
|
|
814
|
+
/** Pre-blurred glow mask from separable blur passes (R channel). */
|
|
815
|
+
uniform sampler2D uGlowBlurred;
|
|
816
|
+
|
|
776
817
|
/**
|
|
777
818
|
* Color-shift curve LUT — 256×1 R8 texture.
|
|
778
819
|
* Maps depth → color-shift intensity [0,1].
|
|
@@ -921,6 +962,8 @@ vec2 pomDisplace(vec2 uv) {
|
|
|
921
962
|
return mix(uv, hitUV, fade);
|
|
922
963
|
}
|
|
923
964
|
|
|
965
|
+
if (abs(currentLayerDepth - depthAtUV) < 0.001) break;
|
|
966
|
+
|
|
924
967
|
currentUV += deltaUV;
|
|
925
968
|
currentLayerDepth += layerDepth;
|
|
926
969
|
}
|
|
@@ -994,27 +1037,12 @@ void main() {
|
|
|
994
1037
|
}
|
|
995
1038
|
|
|
996
1039
|
// ---- Glow pass ----
|
|
997
|
-
//
|
|
998
|
-
//
|
|
999
|
-
// The glow is additive: it brightens pixels without replacing color.
|
|
1040
|
+
// Reads the pre-blurred glow mask (computed via separable blur at RVFC rate)
|
|
1041
|
+
// and the direct glow curve. Blending via softness controls sharp vs spread.
|
|
1000
1042
|
if (uGlowEnabled) {
|
|
1001
1043
|
float glowDepth = texture(uDepth, displaced).r;
|
|
1002
1044
|
float glowMask = texture(uGlowCurve, vec2(glowDepth, 0.5)).r;
|
|
1003
|
-
|
|
1004
|
-
// Spread glow to neighbors for a soft halo effect
|
|
1005
|
-
float spreadMask = 0.0;
|
|
1006
|
-
float spreadSamples = 0.0;
|
|
1007
|
-
for (int x = -3; x <= 3; x++) {
|
|
1008
|
-
for (int y = -3; y <= 3; y++) {
|
|
1009
|
-
vec2 sampleOffset = vec2(float(x), float(y)) * uImageTexelSize * uGlowRadius * 100.0;
|
|
1010
|
-
float d = texture(uDepth, displaced + sampleOffset).r;
|
|
1011
|
-
spreadMask += texture(uGlowCurve, vec2(d, 0.5)).r;
|
|
1012
|
-
spreadSamples += 1.0;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
spreadMask /= spreadSamples;
|
|
1016
|
-
|
|
1017
|
-
// Combine direct glow mask with spread, apply softness
|
|
1045
|
+
float spreadMask = texture(uGlowBlurred, displaced).r;
|
|
1018
1046
|
float finalGlow = mix(spreadMask * 0.5, glowMask, uGlowSoftness);
|
|
1019
1047
|
color.rgb += uGlowColor * finalGlow;
|
|
1020
1048
|
}
|
|
@@ -1054,6 +1082,57 @@ void main() {
|
|
|
1054
1082
|
|
|
1055
1083
|
fragColor = color;
|
|
1056
1084
|
}
|
|
1085
|
+
`, Ft = `#version 300 es
|
|
1086
|
+
precision highp float;
|
|
1087
|
+
|
|
1088
|
+
// Separable glow blur — 7-tap box filter.
|
|
1089
|
+
// Compile with #define PASS_HORIZONTAL for the H pass;
|
|
1090
|
+
// without it, runs as the vertical pass reading from the H result.
|
|
1091
|
+
|
|
1092
|
+
in vec2 vUv;
|
|
1093
|
+
out vec4 fragColor;
|
|
1094
|
+
|
|
1095
|
+
#ifdef PASS_HORIZONTAL
|
|
1096
|
+
/** Single-channel depth map (filtered, unit 1). */
|
|
1097
|
+
uniform sampler2D uDepth;
|
|
1098
|
+
|
|
1099
|
+
/** Glow curve LUT — maps depth → glow intensity (unit 5). */
|
|
1100
|
+
uniform sampler2D uGlowCurve;
|
|
1101
|
+
#else
|
|
1102
|
+
/** Horizontal pass output (unit 7). */
|
|
1103
|
+
uniform sampler2D uHorizResult;
|
|
1104
|
+
#endif
|
|
1105
|
+
|
|
1106
|
+
/** Texel size of the depth texture (1.0 / depthDimension). */
|
|
1107
|
+
uniform vec2 uTexelSize;
|
|
1108
|
+
|
|
1109
|
+
/** Glow spread radius multiplier. */
|
|
1110
|
+
uniform float uGlowRadius;
|
|
1111
|
+
|
|
1112
|
+
/** Blur direction: (1,0) for horizontal, (0,1) for vertical. */
|
|
1113
|
+
uniform vec2 uBlurDir;
|
|
1114
|
+
|
|
1115
|
+
void main() {
|
|
1116
|
+
float accum = 0.0;
|
|
1117
|
+
vec2 step = uBlurDir * uTexelSize * uGlowRadius * 100.0;
|
|
1118
|
+
|
|
1119
|
+
for (int i = -3; i <= 3; i++) {
|
|
1120
|
+
vec2 sampleUV = vUv + float(i) * step;
|
|
1121
|
+
sampleUV = clamp(sampleUV, vec2(0.0), vec2(1.0));
|
|
1122
|
+
|
|
1123
|
+
#ifdef PASS_HORIZONTAL
|
|
1124
|
+
// Sample depth → look up glow curve
|
|
1125
|
+
float d = texture(uDepth, sampleUV).r;
|
|
1126
|
+
accum += texture(uGlowCurve, vec2(d, 0.5)).r;
|
|
1127
|
+
#else
|
|
1128
|
+
// Sample the horizontal blur result
|
|
1129
|
+
accum += texture(uHorizResult, sampleUV).r;
|
|
1130
|
+
#endif
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
accum /= 7.0;
|
|
1134
|
+
fragColor = vec4(accum, 0.0, 0.0, 1.0);
|
|
1135
|
+
}
|
|
1057
1136
|
`, B = {
|
|
1058
1137
|
contrastLow: 0.05,
|
|
1059
1138
|
contrastHigh: 0.95,
|
|
@@ -1074,52 +1153,52 @@ void main() {
|
|
|
1074
1153
|
1: 0.5625
|
|
1075
1154
|
// 0.75²
|
|
1076
1155
|
};
|
|
1077
|
-
function be(
|
|
1156
|
+
function be(s, t) {
|
|
1078
1157
|
const e = ve.replace(
|
|
1079
1158
|
"#version 300 es",
|
|
1080
1159
|
`#version 300 es
|
|
1081
1160
|
#define BILATERAL_RADIUS ${t}`
|
|
1082
|
-
), n =
|
|
1083
|
-
let
|
|
1084
|
-
const
|
|
1161
|
+
), n = G(s, s.VERTEX_SHADER, bt), i = G(s, s.FRAGMENT_SHADER, e), r = mt(s, n, i), o = pt(s, r, Te), l = Ee[t] ?? 2.25;
|
|
1162
|
+
let a = null;
|
|
1163
|
+
const h = {
|
|
1085
1164
|
name: "bilateral-filter",
|
|
1086
1165
|
program: r,
|
|
1087
|
-
uniforms:
|
|
1166
|
+
uniforms: o,
|
|
1088
1167
|
fbo: null,
|
|
1089
1168
|
outputs: [],
|
|
1090
1169
|
width: 0,
|
|
1091
1170
|
height: 0,
|
|
1092
|
-
resize(
|
|
1171
|
+
resize(c, f, u) {
|
|
1093
1172
|
},
|
|
1094
|
-
initFBO(
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1173
|
+
initFBO(c, f, u, x) {
|
|
1174
|
+
a && c.deleteFramebuffer(a), h.width = u, h.height = x, a = c.createFramebuffer(), h.fbo = a, c.bindFramebuffer(c.FRAMEBUFFER, a), c.framebufferTexture2D(
|
|
1175
|
+
c.FRAMEBUFFER,
|
|
1176
|
+
c.COLOR_ATTACHMENT0,
|
|
1177
|
+
c.TEXTURE_2D,
|
|
1099
1178
|
f,
|
|
1100
1179
|
0
|
|
1101
|
-
),
|
|
1180
|
+
), c.bindFramebuffer(c.FRAMEBUFFER, null), c.useProgram(r), c.uniform1i(o.uRawDepth, 2), c.uniform2f(o.uTexelSize, 1 / u, 1 / x), c.uniform1f(o.uSpatialSigma2, l);
|
|
1102
1181
|
},
|
|
1103
|
-
execute(
|
|
1104
|
-
|
|
1105
|
-
|
|
1182
|
+
execute(c, f, u, x, p, d, y, E) {
|
|
1183
|
+
a && (c.activeTexture(c.TEXTURE2), c.bindTexture(c.TEXTURE_2D, u), c.texSubImage2D(
|
|
1184
|
+
c.TEXTURE_2D,
|
|
1106
1185
|
0,
|
|
1107
1186
|
0,
|
|
1108
1187
|
0,
|
|
1109
|
-
|
|
1188
|
+
p,
|
|
1110
1189
|
d,
|
|
1111
|
-
|
|
1112
|
-
|
|
1190
|
+
c.RED,
|
|
1191
|
+
c.UNSIGNED_BYTE,
|
|
1113
1192
|
x
|
|
1114
|
-
),
|
|
1193
|
+
), c.bindFramebuffer(c.FRAMEBUFFER, a), c.viewport(0, 0, p, d), c.useProgram(r), c.bindVertexArray(f), c.drawArrays(c.TRIANGLE_STRIP, 0, 4), c.bindFramebuffer(c.FRAMEBUFFER, null), c.viewport(0, 0, y, E));
|
|
1115
1194
|
},
|
|
1116
|
-
dispose(
|
|
1117
|
-
|
|
1195
|
+
dispose(c) {
|
|
1196
|
+
a && (c.deleteFramebuffer(a), a = null, h.fbo = null), c.deleteProgram(r);
|
|
1118
1197
|
}
|
|
1119
1198
|
};
|
|
1120
|
-
return
|
|
1199
|
+
return h;
|
|
1121
1200
|
}
|
|
1122
|
-
const
|
|
1201
|
+
const Se = [
|
|
1123
1202
|
"uImage",
|
|
1124
1203
|
"uDepth",
|
|
1125
1204
|
"uOffset",
|
|
@@ -1144,6 +1223,7 @@ const ye = [
|
|
|
1144
1223
|
"uGlowColor",
|
|
1145
1224
|
"uGlowRadius",
|
|
1146
1225
|
"uGlowSoftness",
|
|
1226
|
+
"uGlowBlurred",
|
|
1147
1227
|
"uColorShiftCurve",
|
|
1148
1228
|
"uColorShiftEnabled",
|
|
1149
1229
|
"uColorShiftHue",
|
|
@@ -1157,29 +1237,29 @@ const ye = [
|
|
|
1157
1237
|
"uTiltPeakIntensity",
|
|
1158
1238
|
"uTiltPlaneNormal",
|
|
1159
1239
|
"uTiltPlaneD"
|
|
1160
|
-
],
|
|
1161
|
-
function we(
|
|
1240
|
+
], ye = 64;
|
|
1241
|
+
function we(s) {
|
|
1162
1242
|
const t = xe.replace(
|
|
1163
1243
|
"#version 300 es",
|
|
1164
1244
|
`#version 300 es
|
|
1165
|
-
#define MAX_POM_STEPS ${
|
|
1166
|
-
), e =
|
|
1245
|
+
#define MAX_POM_STEPS ${ye}`
|
|
1246
|
+
), e = G(s, s.VERTEX_SHADER, ge), n = G(s, s.FRAGMENT_SHADER, t), i = mt(s, e, n), r = pt(s, i, Se);
|
|
1167
1247
|
return {
|
|
1168
1248
|
name: "depth-effect",
|
|
1169
1249
|
program: i,
|
|
1170
1250
|
uniforms: r,
|
|
1171
|
-
setStaticUniforms(
|
|
1172
|
-
|
|
1251
|
+
setStaticUniforms(o, l, a, h) {
|
|
1252
|
+
o.useProgram(i), 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);
|
|
1173
1253
|
},
|
|
1174
|
-
updateUvTransform(
|
|
1175
|
-
|
|
1254
|
+
updateUvTransform(o, l, a) {
|
|
1255
|
+
o.useProgram(i), o.uniform2f(r.uUvOffset, l[0], l[1]), o.uniform2f(r.uUvScale, a[0], a[1]);
|
|
1176
1256
|
},
|
|
1177
|
-
dispose(
|
|
1178
|
-
|
|
1257
|
+
dispose(o) {
|
|
1258
|
+
o.deleteProgram(i);
|
|
1179
1259
|
}
|
|
1180
1260
|
};
|
|
1181
1261
|
}
|
|
1182
|
-
class
|
|
1262
|
+
class Re extends gt {
|
|
1183
1263
|
// ---- Shared GPU resources ----
|
|
1184
1264
|
gl = null;
|
|
1185
1265
|
quadVao = null;
|
|
@@ -1187,7 +1267,7 @@ class Ae extends mt {
|
|
|
1187
1267
|
bilateralPass = null;
|
|
1188
1268
|
effectPass = null;
|
|
1189
1269
|
// ---- Texture registry (init-time allocation, zero per-frame overhead) ----
|
|
1190
|
-
textures = new
|
|
1270
|
+
textures = new Ht();
|
|
1191
1271
|
videoSlot;
|
|
1192
1272
|
filteredDepthSlot;
|
|
1193
1273
|
rawDepthSlot;
|
|
@@ -1195,6 +1275,12 @@ class Ae extends mt {
|
|
|
1195
1275
|
blurLutSlot;
|
|
1196
1276
|
glowLutSlot;
|
|
1197
1277
|
colorShiftLutSlot;
|
|
1278
|
+
glowBlurHorizSlot;
|
|
1279
|
+
glowBlurResultSlot;
|
|
1280
|
+
// ---- Glow blur passes ----
|
|
1281
|
+
glowBlurHPass = null;
|
|
1282
|
+
glowBlurVPass = null;
|
|
1283
|
+
glowEnabled = !1;
|
|
1198
1284
|
/** Resolved config with all optional shader params filled from defaults. */
|
|
1199
1285
|
config;
|
|
1200
1286
|
/**
|
|
@@ -1206,7 +1292,7 @@ class Ae extends mt {
|
|
|
1206
1292
|
* Optional shader parameters are merged with calibrated defaults.
|
|
1207
1293
|
*/
|
|
1208
1294
|
constructor(t, e) {
|
|
1209
|
-
super(t), this.videoSlot = this.textures.register("video"), this.filteredDepthSlot = this.textures.register("filteredDepth"), this.rawDepthSlot = this.textures.register("rawDepth"), this.displacementLutSlot = this.textures.register("displacementLut"), this.blurLutSlot = this.textures.register("blurLut"), this.glowLutSlot = this.textures.register("glowLut"), this.colorShiftLutSlot = this.textures.register("colorShiftLut"), this.config = {
|
|
1295
|
+
super(t), this.videoSlot = this.textures.register("video"), this.filteredDepthSlot = this.textures.register("filteredDepth"), this.rawDepthSlot = this.textures.register("rawDepth"), this.displacementLutSlot = this.textures.register("displacementLut"), this.blurLutSlot = this.textures.register("blurLut"), this.glowLutSlot = this.textures.register("glowLut"), this.colorShiftLutSlot = this.textures.register("colorShiftLut"), this.glowBlurHorizSlot = this.textures.register("glowBlurHoriz"), this.glowBlurResultSlot = this.textures.register("glowBlurResult"), this.config = {
|
|
1210
1296
|
parallaxStrength: e.parallaxStrength,
|
|
1211
1297
|
pomEnabled: e.pomEnabled,
|
|
1212
1298
|
pomSteps: e.pomSteps,
|
|
@@ -1232,7 +1318,7 @@ class Ae extends mt {
|
|
|
1232
1318
|
powerPreference: "high-performance"
|
|
1233
1319
|
});
|
|
1234
1320
|
if (!n) throw new Error("WebGL 2 is not supported.");
|
|
1235
|
-
this.gl = n, this.qualityParams =
|
|
1321
|
+
this.gl = n, this.qualityParams = Nt(n, e.quality), "drawingBufferColorSpace" in n && (n.drawingBufferColorSpace = "srgb"), n.clearColor(0, 0, 0, 1), n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
|
|
1236
1322
|
}
|
|
1237
1323
|
/**
|
|
1238
1324
|
* Set up the scene: create video texture, depth textures + FBO, and
|
|
@@ -1247,7 +1333,13 @@ class Ae extends mt {
|
|
|
1247
1333
|
*/
|
|
1248
1334
|
initialize(t, e, n) {
|
|
1249
1335
|
const i = this.gl;
|
|
1250
|
-
|
|
1336
|
+
if (i) {
|
|
1337
|
+
if (this.disposeTextures(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.clampDepthDimensions(e, n, this.qualityParams.depthMaxDim), this.videoSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.videoSlot.unit), i.bindTexture(i.TEXTURE_2D, this.videoSlot.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), this.rawDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.rawDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.rawDepthSlot.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, e, n), this.filteredDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.filteredDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.filteredDepthSlot.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, e, n), this.bilateralPass && this.filteredDepthSlot.texture && this.bilateralPass.initFBO(i, this.filteredDepthSlot.texture, e, n), this.glowBlurHPass && this.glowBlurVPass) {
|
|
1338
|
+
const r = this.depthWidth, o = this.depthHeight;
|
|
1339
|
+
this.glowBlurHPass.resize(i, r, o), this.glowBlurVPass.resize(i, r, o), this.glowBlurHorizSlot.texture = this.glowBlurHPass.outputs[0].texture, this.glowBlurResultSlot.texture = this.glowBlurVPass.outputs[0].texture, i.useProgram(this.glowBlurHPass.program), i.uniform1i(this.glowBlurHPass.uniforms.uDepth, this.filteredDepthSlot.unit), i.uniform1i(this.glowBlurHPass.uniforms.uGlowCurve, this.glowLutSlot.unit), i.uniform2f(this.glowBlurHPass.uniforms.uBlurDir, 1, 0), i.uniform2f(this.glowBlurHPass.uniforms.uTexelSize, 1 / r, 1 / o), i.uniform1f(this.glowBlurHPass.uniforms.uGlowRadius, this.config.glowRadius), i.useProgram(this.glowBlurVPass.program), i.uniform1i(this.glowBlurVPass.uniforms.uHorizResult, this.glowBlurHorizSlot.unit), i.uniform2f(this.glowBlurVPass.uniforms.uBlurDir, 0, 1), i.uniform2f(this.glowBlurVPass.uniforms.uTexelSize, 1 / r, 1 / o), i.uniform1f(this.glowBlurVPass.uniforms.uGlowRadius, this.config.glowRadius);
|
|
1340
|
+
}
|
|
1341
|
+
this.effectPass && this.effectPass.setStaticUniforms(i, this.config, t.width, t.height), this.recalculateViewportLayout();
|
|
1342
|
+
}
|
|
1251
1343
|
}
|
|
1252
1344
|
/**
|
|
1253
1345
|
* Update shader parameters at runtime without re-creating the renderer.
|
|
@@ -1262,29 +1354,31 @@ class Ae extends mt {
|
|
|
1262
1354
|
if (!e || !this.effectPass) return;
|
|
1263
1355
|
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);
|
|
1264
1356
|
const { uniforms: n, program: i } = this.effectPass;
|
|
1265
|
-
e.useProgram(i), e.uniform1f(n.uStrength, this.config.parallaxStrength), e.uniform1i(n.uPomEnabled, this.config.pomEnabled ? 1 : 0), e.uniform1i(n.uPomSteps, this.config.pomSteps), e.uniform1f(n.uContrastLow, this.config.contrastLow), e.uniform1f(n.uContrastHigh, this.config.contrastHigh), e.uniform1f(n.uVerticalReduction, this.config.verticalReduction), e.uniform1f(n.uDofStart, this.config.dofStart), e.uniform1f(n.uDofStrength, this.config.dofStrength), e.uniform1f(n.uBlurRadius, this.config.blurRadius), e.uniform3f(n.uGlowColor, this.config.glowColor[0], this.config.glowColor[1], this.config.glowColor[2]), e.uniform1f(n.uGlowRadius, this.config.glowRadius), e.uniform1f(n.uGlowSoftness, this.config.glowSoftness), e.uniform1i(n.uTiltEnabled, this.config.tiltEnabled ? 1 : 0), e.uniform1f(n.uTiltHalfTanFov, this.config.tiltHalfTanFov), e.uniform1f(n.uTiltTransitionWidth, this.config.tiltTransitionWidth), e.uniform1f(n.uTiltPeakIntensity, this.config.tiltPeakIntensity), (t.parallaxStrength !== void 0 || t.overscanPadding !== void 0) && this.recalculateViewportLayout();
|
|
1357
|
+
e.useProgram(i), e.uniform1f(n.uStrength, this.config.parallaxStrength), e.uniform1i(n.uPomEnabled, this.config.pomEnabled ? 1 : 0), e.uniform1i(n.uPomSteps, this.config.pomSteps), e.uniform1f(n.uContrastLow, this.config.contrastLow), e.uniform1f(n.uContrastHigh, this.config.contrastHigh), e.uniform1f(n.uVerticalReduction, this.config.verticalReduction), e.uniform1f(n.uDofStart, this.config.dofStart), e.uniform1f(n.uDofStrength, this.config.dofStrength), e.uniform1f(n.uBlurRadius, this.config.blurRadius), e.uniform3f(n.uGlowColor, this.config.glowColor[0], this.config.glowColor[1], this.config.glowColor[2]), e.uniform1f(n.uGlowRadius, this.config.glowRadius), e.uniform1f(n.uGlowSoftness, this.config.glowSoftness), e.uniform1i(n.uTiltEnabled, this.config.tiltEnabled ? 1 : 0), e.uniform1f(n.uTiltHalfTanFov, this.config.tiltHalfTanFov), e.uniform1f(n.uTiltTransitionWidth, this.config.tiltTransitionWidth), e.uniform1f(n.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();
|
|
1266
1358
|
}
|
|
1267
1359
|
/**
|
|
1268
1360
|
* Upload new curve LUT data to the GPU.
|
|
1269
1361
|
* Call this whenever the curve editor changes.
|
|
1270
1362
|
*/
|
|
1271
1363
|
updateCurveLUTs(t, e, n, i, r) {
|
|
1272
|
-
const
|
|
1273
|
-
if (!
|
|
1274
|
-
const
|
|
1275
|
-
|
|
1364
|
+
const o = this.gl;
|
|
1365
|
+
if (!o || !this.effectPass) return;
|
|
1366
|
+
const l = !!(t || e), a = !!n, h = !!i;
|
|
1367
|
+
t && this.uploadLUT(this.displacementLutSlot, t), e && this.uploadLUT(this.blurLutSlot, e), n && this.uploadLUT(this.glowLutSlot, n), i && this.uploadLUT(this.colorShiftLutSlot, i), o.useProgram(this.effectPass.program), o.uniform1i(
|
|
1276
1368
|
this.effectPass.uniforms.uCurvesEnabled,
|
|
1277
|
-
a ? 1 : 0
|
|
1278
|
-
), s.uniform1i(
|
|
1279
|
-
this.effectPass.uniforms.uGlowEnabled,
|
|
1280
1369
|
l ? 1 : 0
|
|
1281
|
-
),
|
|
1370
|
+
), o.uniform1i(
|
|
1371
|
+
this.effectPass.uniforms.uGlowEnabled,
|
|
1372
|
+
a ? 1 : 0
|
|
1373
|
+
), o.uniform1i(
|
|
1282
1374
|
this.effectPass.uniforms.uColorShiftEnabled,
|
|
1283
|
-
|
|
1284
|
-
)
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1375
|
+
h ? 1 : 0
|
|
1376
|
+
);
|
|
1377
|
+
const c = this.glowEnabled !== a;
|
|
1378
|
+
if (this.glowEnabled = a, a && (c || n) && this.refreshGlowBlur(), h && r) {
|
|
1379
|
+
const f = this.effectPass.uniforms;
|
|
1380
|
+
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(
|
|
1381
|
+
f.uColorShiftTintColor,
|
|
1288
1382
|
r.tintColor[0],
|
|
1289
1383
|
r.tintColor[1],
|
|
1290
1384
|
r.tintColor[2]
|
|
@@ -1302,7 +1396,49 @@ class Ae extends mt {
|
|
|
1302
1396
|
*/
|
|
1303
1397
|
initGPUResources() {
|
|
1304
1398
|
const t = this.gl;
|
|
1305
|
-
|
|
1399
|
+
if (!t) return;
|
|
1400
|
+
this.bilateralPass = be(t, this.qualityParams.bilateralRadius), this.effectPass = we(t);
|
|
1401
|
+
const e = Ft.replace(
|
|
1402
|
+
"#version 300 es",
|
|
1403
|
+
`#version 300 es
|
|
1404
|
+
#define PASS_HORIZONTAL`
|
|
1405
|
+
), n = [
|
|
1406
|
+
"uDepth",
|
|
1407
|
+
"uGlowCurve",
|
|
1408
|
+
"uHorizResult",
|
|
1409
|
+
"uTexelSize",
|
|
1410
|
+
"uGlowRadius",
|
|
1411
|
+
"uBlurDir"
|
|
1412
|
+
];
|
|
1413
|
+
this.glowBlurHPass = Dt(
|
|
1414
|
+
t,
|
|
1415
|
+
"glow-blur-h",
|
|
1416
|
+
bt,
|
|
1417
|
+
e,
|
|
1418
|
+
n,
|
|
1419
|
+
{
|
|
1420
|
+
internalFormat: t.R8,
|
|
1421
|
+
format: t.RED,
|
|
1422
|
+
type: t.UNSIGNED_BYTE,
|
|
1423
|
+
textureUnit: this.glowBlurHorizSlot.unit,
|
|
1424
|
+
width: 0,
|
|
1425
|
+
height: 0
|
|
1426
|
+
}
|
|
1427
|
+
), this.glowBlurVPass = Dt(
|
|
1428
|
+
t,
|
|
1429
|
+
"glow-blur-v",
|
|
1430
|
+
bt,
|
|
1431
|
+
Ft,
|
|
1432
|
+
n,
|
|
1433
|
+
{
|
|
1434
|
+
internalFormat: t.R8,
|
|
1435
|
+
format: t.RED,
|
|
1436
|
+
type: t.UNSIGNED_BYTE,
|
|
1437
|
+
textureUnit: this.glowBlurResultSlot.unit,
|
|
1438
|
+
width: 0,
|
|
1439
|
+
height: 0
|
|
1440
|
+
}
|
|
1441
|
+
), this.quadVao = Ot(t, this.effectPass.program), t.disable(t.DEPTH_TEST);
|
|
1306
1442
|
}
|
|
1307
1443
|
// -----------------------------------------------------------------------
|
|
1308
1444
|
// Curve LUT texture management
|
|
@@ -1368,7 +1504,24 @@ class Ae extends mt {
|
|
|
1368
1504
|
this.depthHeight,
|
|
1369
1505
|
this.canvas.width,
|
|
1370
1506
|
this.canvas.height
|
|
1371
|
-
);
|
|
1507
|
+
), this.glowEnabled && this.executeGlowBlur(e);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Execute the 2-pass separable glow blur (H then V).
|
|
1511
|
+
* Runs at depth resolution into R8 FBOs.
|
|
1512
|
+
*/
|
|
1513
|
+
executeGlowBlur(t) {
|
|
1514
|
+
if (!this.glowBlurHPass?.fbo || !this.glowBlurVPass?.fbo || !this.quadVao) return;
|
|
1515
|
+
const e = this.depthWidth, n = this.depthHeight;
|
|
1516
|
+
t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurHPass.fbo), t.viewport(0, 0, e, n), 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);
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Re-execute glow blur on demand (when glow LUT or radius changes).
|
|
1520
|
+
* Only runs if depth data has been uploaded at least once.
|
|
1521
|
+
*/
|
|
1522
|
+
refreshGlowBlur() {
|
|
1523
|
+
const t = this.gl;
|
|
1524
|
+
!t || !this.glowEnabled || this.depthWidth === 0 || this.executeGlowBlur(t);
|
|
1372
1525
|
}
|
|
1373
1526
|
/**
|
|
1374
1527
|
* Recalculate the WebGL canvas size and UV transform to match the
|
|
@@ -1380,8 +1533,8 @@ class Ae extends mt {
|
|
|
1380
1533
|
recalculateViewportLayout() {
|
|
1381
1534
|
const t = this.gl;
|
|
1382
1535
|
if (!t) return;
|
|
1383
|
-
const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i),
|
|
1384
|
-
(this.canvas.width !== r || this.canvas.height !==
|
|
1536
|
+
const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), o = Math.round(n * i);
|
|
1537
|
+
(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);
|
|
1385
1538
|
}
|
|
1386
1539
|
/** Release all GPU resources. */
|
|
1387
1540
|
disposeRenderer() {
|
|
@@ -1403,18 +1556,18 @@ class Ae extends mt {
|
|
|
1403
1556
|
/** Dispose render passes and shared VAO. */
|
|
1404
1557
|
disposeGPUResources() {
|
|
1405
1558
|
const t = this.gl;
|
|
1406
|
-
t && (this.bilateralPass && (this.bilateralPass.dispose(t), this.bilateralPass = null), this.effectPass && (this.effectPass.dispose(t), this.effectPass = null), this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null));
|
|
1559
|
+
t && (this.bilateralPass && (this.bilateralPass.dispose(t), this.bilateralPass = null), this.effectPass && (this.effectPass.dispose(t), this.effectPass = null), this.glowBlurHPass && (this.glowBlurHPass.dispose(t), this.glowBlurHPass = null), this.glowBlurVPass && (this.glowBlurVPass.dispose(t), this.glowBlurVPass = null), this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null));
|
|
1407
1560
|
}
|
|
1408
1561
|
}
|
|
1409
|
-
async function
|
|
1562
|
+
async function ht(s, t = {}) {
|
|
1410
1563
|
const {
|
|
1411
1564
|
parent: e = document.body,
|
|
1412
1565
|
loop: n = !0,
|
|
1413
1566
|
muted: i = !0
|
|
1414
1567
|
} = t, r = document.createElement("video");
|
|
1415
|
-
return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted = i, r.defaultMuted = i, i && r.setAttribute("muted", ""), r.loop = n, r.preload = "auto", r.style.display = "none", r.src =
|
|
1568
|
+
return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted = i, r.defaultMuted = i, i && r.setAttribute("muted", ""), r.loop = n, r.preload = "auto", r.style.display = "none", r.src = s, e.appendChild(r), await Gt(r), new Ae(r);
|
|
1416
1569
|
}
|
|
1417
|
-
class
|
|
1570
|
+
class Ae {
|
|
1418
1571
|
constructor(t) {
|
|
1419
1572
|
this.video = t;
|
|
1420
1573
|
}
|
|
@@ -1460,17 +1613,17 @@ class Re {
|
|
|
1460
1613
|
this.video.pause(), this.video.removeAttribute("src"), this.video.load(), this.video.remove();
|
|
1461
1614
|
}
|
|
1462
1615
|
}
|
|
1463
|
-
async function
|
|
1616
|
+
async function ft(s, t = {}) {
|
|
1464
1617
|
const e = new Image();
|
|
1465
|
-
return e.crossOrigin = "anonymous", e.src =
|
|
1618
|
+
return e.crossOrigin = "anonymous", e.src = s, await new Promise((n, i) => {
|
|
1466
1619
|
if (e.complete && e.naturalWidth > 0) {
|
|
1467
1620
|
n();
|
|
1468
1621
|
return;
|
|
1469
1622
|
}
|
|
1470
|
-
e.addEventListener("load", () => n(), { once: !0 }), e.addEventListener("error", () => i(new Error(`Failed to load image: ${
|
|
1471
|
-
}), new
|
|
1623
|
+
e.addEventListener("load", () => n(), { once: !0 }), e.addEventListener("error", () => i(new Error(`Failed to load image: ${s}`)), { once: !0 });
|
|
1624
|
+
}), new Pe(e);
|
|
1472
1625
|
}
|
|
1473
|
-
class
|
|
1626
|
+
class Pe {
|
|
1474
1627
|
constructor(t) {
|
|
1475
1628
|
this.img = t;
|
|
1476
1629
|
}
|
|
@@ -1492,11 +1645,11 @@ class De {
|
|
|
1492
1645
|
this.img.removeAttribute("src");
|
|
1493
1646
|
}
|
|
1494
1647
|
}
|
|
1495
|
-
async function
|
|
1496
|
-
const { parent: e = document.body } = t, n = await navigator.mediaDevices.getUserMedia(
|
|
1497
|
-
return i.playsInline = !0, i.setAttribute("playsinline", ""), i.muted = !0, i.defaultMuted = !0, i.style.display = "none", i.srcObject = n, e.appendChild(i), await
|
|
1648
|
+
async function Xt(s = { video: !0 }, t = {}) {
|
|
1649
|
+
const { parent: e = document.body } = t, n = await navigator.mediaDevices.getUserMedia(s), i = document.createElement("video");
|
|
1650
|
+
return i.playsInline = !0, i.setAttribute("playsinline", ""), i.muted = !0, i.defaultMuted = !0, i.style.display = "none", i.srcObject = n, e.appendChild(i), await Gt(i), await i.play(), new De(i, n);
|
|
1498
1651
|
}
|
|
1499
|
-
class
|
|
1652
|
+
class De {
|
|
1500
1653
|
constructor(t, e) {
|
|
1501
1654
|
this.video = t, this.stream = e;
|
|
1502
1655
|
}
|
|
@@ -1542,19 +1695,19 @@ class Pe {
|
|
|
1542
1695
|
t.stop();
|
|
1543
1696
|
}
|
|
1544
1697
|
}
|
|
1545
|
-
async function
|
|
1546
|
-
|
|
1698
|
+
async function Gt(s) {
|
|
1699
|
+
s.readyState >= HTMLMediaElement.HAVE_METADATA || await new Promise((t, e) => {
|
|
1547
1700
|
const n = () => {
|
|
1548
1701
|
r(), t();
|
|
1549
1702
|
}, i = () => {
|
|
1550
1703
|
r(), e(new Error("Failed to load video metadata."));
|
|
1551
1704
|
}, r = () => {
|
|
1552
|
-
|
|
1705
|
+
s.removeEventListener("loadedmetadata", n), s.removeEventListener("error", i);
|
|
1553
1706
|
};
|
|
1554
|
-
|
|
1707
|
+
s.addEventListener("loadedmetadata", n), s.addEventListener("error", i), s.load();
|
|
1555
1708
|
});
|
|
1556
1709
|
}
|
|
1557
|
-
const
|
|
1710
|
+
const Z = 518;
|
|
1558
1711
|
async function Fe() {
|
|
1559
1712
|
return await import("onnxruntime-web/webgpu");
|
|
1560
1713
|
}
|
|
@@ -1583,6 +1736,8 @@ class Ce {
|
|
|
1583
1736
|
// Frame capture canvas (reused)
|
|
1584
1737
|
captureCanvas = null;
|
|
1585
1738
|
captureCtx = null;
|
|
1739
|
+
// Preprocessing worker (offloads ImageNet norm + depth quantisation)
|
|
1740
|
+
preprocessWorker = null;
|
|
1586
1741
|
disposed = !1;
|
|
1587
1742
|
// -----------------------------------------------------------------------
|
|
1588
1743
|
// Initialisation
|
|
@@ -1596,7 +1751,7 @@ class Ce {
|
|
|
1596
1751
|
*/
|
|
1597
1752
|
async init(t, e) {
|
|
1598
1753
|
const n = await Fe();
|
|
1599
|
-
if (this.ort = n, this.captureCanvas = document.createElement("canvas"), this.captureCanvas.width =
|
|
1754
|
+
if (this.ort = n, this.captureCanvas = document.createElement("canvas"), this.captureCanvas.width = Z, this.captureCanvas.height = Z, this.captureCtx = this.captureCanvas.getContext("2d", {
|
|
1600
1755
|
willReadFrequently: !0
|
|
1601
1756
|
}), !this.captureCtx)
|
|
1602
1757
|
throw new Error("[DepthEstimator] Failed to create 2D canvas context.");
|
|
@@ -1608,12 +1763,19 @@ class Ce {
|
|
|
1608
1763
|
r = await n.InferenceSession.create(i, {
|
|
1609
1764
|
executionProviders: ["webgpu"]
|
|
1610
1765
|
}), console.log("[DepthEstimator] Using WebGPU execution provider");
|
|
1611
|
-
} catch (
|
|
1612
|
-
console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:",
|
|
1766
|
+
} catch (o) {
|
|
1767
|
+
console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:", o), n.env.wasm.proxy = !0, r = await n.InferenceSession.create(i, {
|
|
1613
1768
|
executionProviders: ["wasm"]
|
|
1614
1769
|
}), console.log("[DepthEstimator] Using WASM execution provider (proxy worker)");
|
|
1615
1770
|
}
|
|
1616
|
-
this.session = r, this.inputName = r.inputNames[0], this.outputName = r.outputNames[0], this.
|
|
1771
|
+
this.session = r, this.inputName = r.inputNames[0], this.outputName = r.outputNames[0], this.preprocessWorker = new Worker(
|
|
1772
|
+
new URL(
|
|
1773
|
+
/* @vite-ignore */
|
|
1774
|
+
"/assets/preprocess-worker-wra-uI6w.js",
|
|
1775
|
+
import.meta.url
|
|
1776
|
+
),
|
|
1777
|
+
{ type: "module" }
|
|
1778
|
+
), this.readyResolve?.(), this.readyResolve = null;
|
|
1617
1779
|
}
|
|
1618
1780
|
/** Wait for model loading and session creation to complete. */
|
|
1619
1781
|
waitUntilReady() {
|
|
@@ -1651,28 +1813,28 @@ class Ce {
|
|
|
1651
1813
|
// Cleanup
|
|
1652
1814
|
// -----------------------------------------------------------------------
|
|
1653
1815
|
dispose() {
|
|
1654
|
-
this.disposed = !0, this.session?.release(), this.session = null, this.ort = null, this.captureCanvas = null, this.captureCtx = null;
|
|
1816
|
+
this.disposed = !0, this.session?.release(), this.session = null, this.ort = null, this.captureCanvas = null, this.captureCtx = null, this.preprocessWorker?.terminate(), this.preprocessWorker = null;
|
|
1655
1817
|
}
|
|
1656
1818
|
// -----------------------------------------------------------------------
|
|
1657
1819
|
// Internal inference pipeline
|
|
1658
1820
|
// -----------------------------------------------------------------------
|
|
1659
1821
|
async runInference(t) {
|
|
1660
1822
|
try {
|
|
1661
|
-
if (!this.session || !this.captureCtx || !this.ort) return;
|
|
1823
|
+
if (!this.session || !this.captureCtx || !this.ort || !this.preprocessWorker) return;
|
|
1662
1824
|
this.captureCtx.drawImage(
|
|
1663
1825
|
t,
|
|
1664
1826
|
0,
|
|
1665
1827
|
0,
|
|
1666
|
-
|
|
1667
|
-
|
|
1828
|
+
Z,
|
|
1829
|
+
Z
|
|
1668
1830
|
);
|
|
1669
1831
|
const e = this.captureCtx.getImageData(
|
|
1670
1832
|
0,
|
|
1671
1833
|
0,
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
), n = this.
|
|
1675
|
-
this.
|
|
1834
|
+
Z,
|
|
1835
|
+
Z
|
|
1836
|
+
), n = await this.workerPreprocess(e.data.buffer, e.width, e.height), i = new this.ort.Tensor("float32", new Float32Array(n), [1, 3, e.height, e.width]), o = (await this.session.run({ [this.inputName]: i }))[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);
|
|
1837
|
+
this.backBuffer.set(new Uint8Array(f));
|
|
1676
1838
|
const u = this.frontBuffer;
|
|
1677
1839
|
this.frontBuffer = this.backBuffer, this.backBuffer = u;
|
|
1678
1840
|
} catch (e) {
|
|
@@ -1681,47 +1843,47 @@ class Ce {
|
|
|
1681
1843
|
this.inferenceInFlight = !1;
|
|
1682
1844
|
}
|
|
1683
1845
|
}
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1846
|
+
workerPreprocess(t, e, n) {
|
|
1847
|
+
return new Promise((i, r) => {
|
|
1848
|
+
if (!this.preprocessWorker) {
|
|
1849
|
+
r(new Error("Worker not ready"));
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
const o = (a) => {
|
|
1853
|
+
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "preprocessed" ? i(a.data.float32) : a.data.type === "error" && r(new Error(a.data.message));
|
|
1854
|
+
};
|
|
1855
|
+
this.preprocessWorker.addEventListener("message", o);
|
|
1856
|
+
const l = t.slice(0);
|
|
1857
|
+
this.preprocessWorker.postMessage(
|
|
1858
|
+
{ type: "preprocess", pixels: l, width: e, height: n },
|
|
1859
|
+
[l]
|
|
1860
|
+
);
|
|
1861
|
+
});
|
|
1694
1862
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
* higher raw values = closer to camera. This matches the convention used
|
|
1701
|
-
* by the precompute pipeline (`normalizeToUint8` in scripts/precompute-depth.ts),
|
|
1702
|
-
* so no inversion is applied: 255 = nearest, 0 = farthest.
|
|
1703
|
-
*/
|
|
1704
|
-
postProcess(t, e, n) {
|
|
1705
|
-
const { depthWidth: i, depthHeight: r } = this;
|
|
1706
|
-
let s = 1 / 0, a = -1 / 0;
|
|
1707
|
-
for (let f = 0; f < t.length; f++) {
|
|
1708
|
-
const h = t[f];
|
|
1709
|
-
h < s && (s = h), h > a && (a = h);
|
|
1710
|
-
}
|
|
1711
|
-
const l = a - s || 1, c = e / i, u = n / r;
|
|
1712
|
-
for (let f = 0; f < r; f++)
|
|
1713
|
-
for (let h = 0; h < i; h++) {
|
|
1714
|
-
const x = h * c, g = f * u, d = Math.floor(x), y = Math.floor(g), E = Math.min(d + 1, e - 1), b = Math.min(y + 1, n - 1), p = x - d, v = g - y, m = t[y * e + d], T = t[y * e + E], w = t[b * e + d], A = t[b * e + E], P = (m * (1 - p) * (1 - v) + T * p * (1 - v) + w * (1 - p) * v + A * p * v - s) / l;
|
|
1715
|
-
this.backBuffer[f * i + h] = P * 255 + 0.5 | 0;
|
|
1863
|
+
workerPostprocess(t, e, n) {
|
|
1864
|
+
return new Promise((i, r) => {
|
|
1865
|
+
if (!this.preprocessWorker) {
|
|
1866
|
+
r(new Error("Worker not ready"));
|
|
1867
|
+
return;
|
|
1716
1868
|
}
|
|
1869
|
+
const o = (a) => {
|
|
1870
|
+
this.preprocessWorker?.removeEventListener("message", o), a.data.type === "postprocessed" ? i(a.data.depth) : a.data.type === "error" && r(new Error(a.data.message));
|
|
1871
|
+
};
|
|
1872
|
+
this.preprocessWorker.addEventListener("message", o);
|
|
1873
|
+
const l = t.slice(0);
|
|
1874
|
+
this.preprocessWorker.postMessage(
|
|
1875
|
+
{ type: "postprocess", depthFloat: l, srcW: e, srcH: n, dstW: this.depthWidth, dstH: this.depthHeight },
|
|
1876
|
+
[l]
|
|
1877
|
+
);
|
|
1878
|
+
});
|
|
1717
1879
|
}
|
|
1718
1880
|
}
|
|
1719
|
-
async function
|
|
1881
|
+
async function dt(s, t, e, n) {
|
|
1720
1882
|
const i = new Ce(t, e);
|
|
1721
|
-
return await i.init(
|
|
1883
|
+
return await i.init(s, n), i;
|
|
1722
1884
|
}
|
|
1723
|
-
async function Ue(
|
|
1724
|
-
const e = await fetch(
|
|
1885
|
+
async function Ue(s, t) {
|
|
1886
|
+
const e = await fetch(s);
|
|
1725
1887
|
if (!e.ok)
|
|
1726
1888
|
throw new Error(`[DepthEstimator] Failed to fetch model (${e.status} ${e.statusText}).`);
|
|
1727
1889
|
const n = e.headers.get("content-length"), i = n ? Number(n) : null, r = e.body;
|
|
@@ -1734,73 +1896,73 @@ async function Ue(o, t) {
|
|
|
1734
1896
|
label: "Downloading depth model…"
|
|
1735
1897
|
}), f;
|
|
1736
1898
|
}
|
|
1737
|
-
const
|
|
1738
|
-
let
|
|
1739
|
-
const
|
|
1899
|
+
const o = [];
|
|
1900
|
+
let l = 0;
|
|
1901
|
+
const a = r.getReader();
|
|
1740
1902
|
for (; ; ) {
|
|
1741
|
-
const { done: f, value:
|
|
1903
|
+
const { done: f, value: u } = await a.read();
|
|
1742
1904
|
if (f) break;
|
|
1743
|
-
|
|
1744
|
-
receivedBytes:
|
|
1905
|
+
u && (o.push(u), l += u.byteLength, t?.({
|
|
1906
|
+
receivedBytes: l,
|
|
1745
1907
|
totalBytes: i,
|
|
1746
|
-
fraction: i ? Math.min(
|
|
1908
|
+
fraction: i ? Math.min(l / i, 1) : 0,
|
|
1747
1909
|
label: "Downloading depth model…"
|
|
1748
1910
|
}));
|
|
1749
1911
|
}
|
|
1750
|
-
const
|
|
1751
|
-
let
|
|
1752
|
-
for (const f of
|
|
1753
|
-
|
|
1754
|
-
return
|
|
1912
|
+
const h = new Uint8Array(l);
|
|
1913
|
+
let c = 0;
|
|
1914
|
+
for (const f of o)
|
|
1915
|
+
h.set(f, c), c += f.byteLength;
|
|
1916
|
+
return h.buffer;
|
|
1755
1917
|
}
|
|
1756
|
-
const
|
|
1918
|
+
const Ct = {
|
|
1757
1919
|
sensitivityX: 0.4,
|
|
1758
1920
|
sensitivityY: 1,
|
|
1759
1921
|
lerpFactor: 0.08
|
|
1760
1922
|
};
|
|
1761
|
-
function
|
|
1762
|
-
const e =
|
|
1923
|
+
function St(s, t) {
|
|
1924
|
+
const e = s.points;
|
|
1763
1925
|
if (e.length === 0) return 0;
|
|
1764
1926
|
if (e.length === 1 || t <= e[0].x) return e[0].y;
|
|
1765
1927
|
if (t >= e[e.length - 1].x) return e[e.length - 1].y;
|
|
1766
1928
|
let n = 0;
|
|
1767
1929
|
for (; n < e.length - 1 && e[n + 1].x < t; ) n++;
|
|
1768
|
-
const i = e[n], r = e[n + 1],
|
|
1769
|
-
switch (
|
|
1930
|
+
const i = e[n], r = e[n + 1], o = (t - i.x) / (r.x - i.x);
|
|
1931
|
+
switch (s.interpolation) {
|
|
1770
1932
|
case "step":
|
|
1771
1933
|
return i.y;
|
|
1772
1934
|
case "linear":
|
|
1773
|
-
return i.y + (r.y - i.y) *
|
|
1935
|
+
return i.y + (r.y - i.y) * o;
|
|
1774
1936
|
case "smooth": {
|
|
1775
|
-
const
|
|
1776
|
-
return i.y + (r.y - i.y) *
|
|
1937
|
+
const l = o * o * (3 - 2 * o);
|
|
1938
|
+
return i.y + (r.y - i.y) * l;
|
|
1777
1939
|
}
|
|
1778
1940
|
default:
|
|
1779
|
-
return i.y + (r.y - i.y) *
|
|
1941
|
+
return i.y + (r.y - i.y) * o;
|
|
1780
1942
|
}
|
|
1781
1943
|
}
|
|
1782
|
-
function
|
|
1944
|
+
function lt(s, t = 256) {
|
|
1783
1945
|
const e = new Uint8Array(t);
|
|
1784
1946
|
for (let n = 0; n < t; n++) {
|
|
1785
1947
|
const i = n / (t - 1);
|
|
1786
|
-
e[n] = Math.round(
|
|
1948
|
+
e[n] = Math.round(St(s, i) * 255);
|
|
1787
1949
|
}
|
|
1788
1950
|
return e;
|
|
1789
1951
|
}
|
|
1790
|
-
function
|
|
1791
|
-
return
|
|
1952
|
+
function q(s, t) {
|
|
1953
|
+
return s.find((e) => e.channel === t && e.enabled);
|
|
1792
1954
|
}
|
|
1793
|
-
function
|
|
1794
|
-
const e =
|
|
1795
|
-
let
|
|
1955
|
+
function Ut(s, t) {
|
|
1956
|
+
const e = q(s, "displacement"), n = q(s, "blur"), i = q(s, "glow"), r = e?.params;
|
|
1957
|
+
let o = 0.6, l = 0;
|
|
1796
1958
|
if (n) {
|
|
1797
|
-
const
|
|
1798
|
-
for (let
|
|
1799
|
-
if (
|
|
1800
|
-
|
|
1959
|
+
const a = n.curve;
|
|
1960
|
+
for (let h = 0; h <= 1; h += 0.01)
|
|
1961
|
+
if (St(a, h) > 0.01) {
|
|
1962
|
+
o = h;
|
|
1801
1963
|
break;
|
|
1802
1964
|
}
|
|
1803
|
-
|
|
1965
|
+
l = St(a, 1);
|
|
1804
1966
|
}
|
|
1805
1967
|
return {
|
|
1806
1968
|
parallaxStrength: r?.strength ?? 0.05,
|
|
@@ -1809,8 +1971,8 @@ function Ct(o, t) {
|
|
|
1809
1971
|
contrastLow: t.contrastLow,
|
|
1810
1972
|
contrastHigh: t.contrastHigh,
|
|
1811
1973
|
verticalReduction: t.verticalReduction,
|
|
1812
|
-
dofStart:
|
|
1813
|
-
dofStrength:
|
|
1974
|
+
dofStart: o,
|
|
1975
|
+
dofStrength: l,
|
|
1814
1976
|
blurRadius: n?.params?.maxRadius ?? 0.01,
|
|
1815
1977
|
glowColor: i?.params?.color ?? [1, 0.95, 0.85],
|
|
1816
1978
|
glowRadius: i?.params?.radius ?? 0.02,
|
|
@@ -1821,13 +1983,13 @@ function Ct(o, t) {
|
|
|
1821
1983
|
tiltPeakIntensity: n?.params?.peakIntensity ?? 0.8
|
|
1822
1984
|
};
|
|
1823
1985
|
}
|
|
1824
|
-
function
|
|
1825
|
-
const t =
|
|
1986
|
+
function Lt(s) {
|
|
1987
|
+
const t = q(s, "displacement"), e = q(s, "blur"), n = q(s, "glow"), i = q(s, "color-shift"), r = i?.params;
|
|
1826
1988
|
return {
|
|
1827
|
-
displacementLUT: t ?
|
|
1828
|
-
blurLUT: e ?
|
|
1829
|
-
glowLUT: n ?
|
|
1830
|
-
colorShiftLUT: i ?
|
|
1989
|
+
displacementLUT: t ? lt(t.curve) : null,
|
|
1990
|
+
blurLUT: e ? lt(e.curve) : null,
|
|
1991
|
+
glowLUT: n ? lt(n.curve) : null,
|
|
1992
|
+
colorShiftLUT: i ? lt(i.curve) : null,
|
|
1831
1993
|
colorShiftParams: r ? {
|
|
1832
1994
|
hueShift: r.hueShift ?? 0,
|
|
1833
1995
|
saturation: r.saturation ?? 1,
|
|
@@ -1837,7 +1999,7 @@ function Ut(o) {
|
|
|
1837
1999
|
} : null
|
|
1838
2000
|
};
|
|
1839
2001
|
}
|
|
1840
|
-
class
|
|
2002
|
+
class Wt {
|
|
1841
2003
|
abortController = null;
|
|
1842
2004
|
initialized = !1;
|
|
1843
2005
|
initializing = !1;
|
|
@@ -1887,7 +2049,7 @@ class Gt {
|
|
|
1887
2049
|
this.abortController?.abort(), this.abortController = null, this.initializing = !1;
|
|
1888
2050
|
}
|
|
1889
2051
|
}
|
|
1890
|
-
const
|
|
2052
|
+
const z = {
|
|
1891
2053
|
parallaxX: 0.4,
|
|
1892
2054
|
parallaxY: 1,
|
|
1893
2055
|
parallaxMax: 30,
|
|
@@ -1895,7 +2057,7 @@ const G = {
|
|
|
1895
2057
|
autoplay: !0,
|
|
1896
2058
|
loop: !0,
|
|
1897
2059
|
muted: !0
|
|
1898
|
-
},
|
|
2060
|
+
}, $ = 512, K = 512;
|
|
1899
2061
|
class xt extends HTMLElement {
|
|
1900
2062
|
static TAG_NAME = "layershift-effect";
|
|
1901
2063
|
static get observedAttributes() {
|
|
@@ -1939,7 +2101,7 @@ class xt extends HTMLElement {
|
|
|
1939
2101
|
*/
|
|
1940
2102
|
depthFallback = null;
|
|
1941
2103
|
constructor() {
|
|
1942
|
-
super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new
|
|
2104
|
+
super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new Wt(this);
|
|
1943
2105
|
}
|
|
1944
2106
|
/** The current input offset. Set this externally to drive the effect. */
|
|
1945
2107
|
get input() {
|
|
@@ -1961,16 +2123,16 @@ class xt extends HTMLElement {
|
|
|
1961
2123
|
return !(n === "false" || n === "0");
|
|
1962
2124
|
}
|
|
1963
2125
|
get parallaxX() {
|
|
1964
|
-
return this.getAttrFloat("parallax-x",
|
|
2126
|
+
return this.getAttrFloat("parallax-x", z.parallaxX);
|
|
1965
2127
|
}
|
|
1966
2128
|
get parallaxY() {
|
|
1967
|
-
return this.getAttrFloat("parallax-y",
|
|
2129
|
+
return this.getAttrFloat("parallax-y", z.parallaxY);
|
|
1968
2130
|
}
|
|
1969
2131
|
get parallaxMax() {
|
|
1970
|
-
return this.getAttrFloat("parallax-max",
|
|
2132
|
+
return this.getAttrFloat("parallax-max", z.parallaxMax);
|
|
1971
2133
|
}
|
|
1972
2134
|
get overscan() {
|
|
1973
|
-
return this.getAttrFloat("overscan",
|
|
2135
|
+
return this.getAttrFloat("overscan", z.overscan);
|
|
1974
2136
|
}
|
|
1975
2137
|
get quality() {
|
|
1976
2138
|
const t = this.getAttribute("quality");
|
|
@@ -1988,13 +2150,13 @@ class xt extends HTMLElement {
|
|
|
1988
2150
|
return this.getAttribute("depth-model");
|
|
1989
2151
|
}
|
|
1990
2152
|
get shouldAutoplay() {
|
|
1991
|
-
return this.getAttrBool("autoplay",
|
|
2153
|
+
return this.getAttrBool("autoplay", z.autoplay);
|
|
1992
2154
|
}
|
|
1993
2155
|
get shouldLoop() {
|
|
1994
|
-
return this.getAttrBool("loop",
|
|
2156
|
+
return this.getAttrBool("loop", z.loop);
|
|
1995
2157
|
}
|
|
1996
2158
|
get shouldMute() {
|
|
1997
|
-
return this.getAttrBool("muted",
|
|
2159
|
+
return this.getAttrBool("muted", z.muted);
|
|
1998
2160
|
}
|
|
1999
2161
|
// --- Event dispatching ---
|
|
2000
2162
|
/**
|
|
@@ -2081,7 +2243,7 @@ class xt extends HTMLElement {
|
|
|
2081
2243
|
const i = await n.json();
|
|
2082
2244
|
return {
|
|
2083
2245
|
channels: i.channels ?? [],
|
|
2084
|
-
motion: i.motion ??
|
|
2246
|
+
motion: i.motion ?? Ct,
|
|
2085
2247
|
overscanPadding: i.overscanPadding ?? 0.05,
|
|
2086
2248
|
quality: i.quality ?? "auto"
|
|
2087
2249
|
};
|
|
@@ -2112,12 +2274,12 @@ class xt extends HTMLElement {
|
|
|
2112
2274
|
if (!this.container) return;
|
|
2113
2275
|
const e = this.sourceType === "camera", n = this.depthModel;
|
|
2114
2276
|
try {
|
|
2115
|
-
let i, r,
|
|
2116
|
-
const
|
|
2277
|
+
let i, r, o = null;
|
|
2278
|
+
const l = (m) => {
|
|
2117
2279
|
this.emit("layershift-effect:model-progress", m);
|
|
2118
2280
|
};
|
|
2119
2281
|
if (e) {
|
|
2120
|
-
if (i = await
|
|
2282
|
+
if (i = await Xt(
|
|
2121
2283
|
{ video: { facingMode: "user" } },
|
|
2122
2284
|
{ parent: this.shadow }
|
|
2123
2285
|
), t.aborted) {
|
|
@@ -2125,91 +2287,91 @@ class xt extends HTMLElement {
|
|
|
2125
2287
|
return;
|
|
2126
2288
|
}
|
|
2127
2289
|
if (n) {
|
|
2128
|
-
if (
|
|
2129
|
-
|
|
2290
|
+
if (o = await dt(n, $, K, l), t.aborted) {
|
|
2291
|
+
o.dispose(), i.dispose();
|
|
2130
2292
|
return;
|
|
2131
2293
|
}
|
|
2132
|
-
r = N(
|
|
2294
|
+
r = N($, K);
|
|
2133
2295
|
} else
|
|
2134
2296
|
r = N(i.width, i.height);
|
|
2135
2297
|
} else {
|
|
2136
|
-
const m = this.getAttribute("src"), T = this.getAttribute("depth-src"), w = this.getAttribute("depth-meta"), A = !!T && !!w,
|
|
2298
|
+
const m = this.getAttribute("src"), T = this.getAttribute("depth-src"), w = this.getAttribute("depth-meta"), A = !!T && !!w, P = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(m);
|
|
2137
2299
|
if (A) {
|
|
2138
|
-
const [
|
|
2139
|
-
|
|
2300
|
+
const [F, _] = await Promise.all([
|
|
2301
|
+
P ? ft(m) : ht(m, {
|
|
2140
2302
|
parent: this.shadow,
|
|
2141
2303
|
loop: this.shouldLoop,
|
|
2142
2304
|
muted: this.shouldMute
|
|
2143
2305
|
}),
|
|
2144
|
-
|
|
2306
|
+
kt(T, w)
|
|
2145
2307
|
]);
|
|
2146
2308
|
if (t.aborted) {
|
|
2147
|
-
|
|
2309
|
+
F.dispose();
|
|
2148
2310
|
return;
|
|
2149
2311
|
}
|
|
2150
|
-
i =
|
|
2312
|
+
i = F, r = _;
|
|
2151
2313
|
} else if (n) {
|
|
2152
|
-
const [
|
|
2153
|
-
|
|
2314
|
+
const [F, _] = await Promise.all([
|
|
2315
|
+
P ? ft(m) : ht(m, {
|
|
2154
2316
|
parent: this.shadow,
|
|
2155
2317
|
loop: this.shouldLoop,
|
|
2156
2318
|
muted: this.shouldMute
|
|
2157
2319
|
}),
|
|
2158
|
-
|
|
2320
|
+
dt(n, $, K, l)
|
|
2159
2321
|
]);
|
|
2160
2322
|
if (t.aborted) {
|
|
2161
|
-
|
|
2323
|
+
F.dispose(), _.dispose();
|
|
2162
2324
|
return;
|
|
2163
2325
|
}
|
|
2164
|
-
if (i =
|
|
2326
|
+
if (i = F, o = _, P || !i.isLive) {
|
|
2165
2327
|
const I = i.getImageSource();
|
|
2166
2328
|
if (I) {
|
|
2167
|
-
const C = await
|
|
2329
|
+
const C = await o.submitFrameAndWait(I);
|
|
2168
2330
|
r = {
|
|
2169
|
-
meta: { frameCount: 1, fps: 1, width:
|
|
2331
|
+
meta: { frameCount: 1, fps: 1, width: $, height: K, sourceFps: 1 },
|
|
2170
2332
|
frames: [C]
|
|
2171
2333
|
};
|
|
2172
2334
|
} else
|
|
2173
|
-
r = N(
|
|
2335
|
+
r = N($, K);
|
|
2174
2336
|
} else
|
|
2175
|
-
r = N(
|
|
2337
|
+
r = N($, K);
|
|
2176
2338
|
} else
|
|
2177
2339
|
throw new Error("Either depth-src/depth-meta or depth-model must be provided.");
|
|
2178
2340
|
}
|
|
2179
|
-
this.source = i, this.depthEstimator =
|
|
2180
|
-
const
|
|
2341
|
+
this.source = i, this.depthEstimator = o, this.loopCount = 0, this.attachSourceEventListeners(i);
|
|
2342
|
+
const a = oe(
|
|
2181
2343
|
r.frames,
|
|
2182
2344
|
r.meta.width,
|
|
2183
2345
|
r.meta.height
|
|
2184
|
-
),
|
|
2346
|
+
), h = ae(a);
|
|
2185
2347
|
this.depthFallback = {
|
|
2186
|
-
contrastLow:
|
|
2187
|
-
contrastHigh:
|
|
2188
|
-
verticalReduction:
|
|
2348
|
+
contrastLow: h.contrastLow,
|
|
2349
|
+
contrastHigh: h.contrastHigh,
|
|
2350
|
+
verticalReduction: h.verticalReduction
|
|
2189
2351
|
};
|
|
2190
|
-
let
|
|
2191
|
-
if (
|
|
2192
|
-
|
|
2352
|
+
let c;
|
|
2353
|
+
if (o)
|
|
2354
|
+
c = () => o.getLatestDepth();
|
|
2193
2355
|
else {
|
|
2194
|
-
const m = new
|
|
2195
|
-
|
|
2356
|
+
const m = new Vt(r);
|
|
2357
|
+
c = (T) => m.sample(T);
|
|
2196
2358
|
}
|
|
2197
2359
|
if (t.aborted) return;
|
|
2198
|
-
let f,
|
|
2199
|
-
const
|
|
2360
|
+
let f, u = null, x = Ct;
|
|
2361
|
+
const p = await this.fetchFilterConfig(t);
|
|
2200
2362
|
if (t.aborted) return;
|
|
2201
|
-
if (
|
|
2202
|
-
const m =
|
|
2203
|
-
contrastLow:
|
|
2204
|
-
contrastHigh:
|
|
2205
|
-
verticalReduction:
|
|
2363
|
+
if (p && p.channels.length > 0) {
|
|
2364
|
+
const m = Ut(p.channels, {
|
|
2365
|
+
contrastLow: h.contrastLow,
|
|
2366
|
+
contrastHigh: h.contrastHigh,
|
|
2367
|
+
verticalReduction: h.verticalReduction
|
|
2206
2368
|
});
|
|
2207
2369
|
f = {
|
|
2208
2370
|
parallaxStrength: m.parallaxStrength,
|
|
2209
2371
|
pomEnabled: m.pomEnabled,
|
|
2210
2372
|
pomSteps: m.pomSteps,
|
|
2211
|
-
overscanPadding:
|
|
2212
|
-
quality:
|
|
2373
|
+
overscanPadding: p.overscanPadding,
|
|
2374
|
+
quality: p.quality,
|
|
2213
2375
|
contrastLow: m.contrastLow,
|
|
2214
2376
|
contrastHigh: m.contrastHigh,
|
|
2215
2377
|
verticalReduction: m.verticalReduction,
|
|
@@ -2223,28 +2385,28 @@ class xt extends HTMLElement {
|
|
|
2223
2385
|
tiltHalfTanFov: m.tiltHalfTanFov,
|
|
2224
2386
|
tiltTransitionWidth: m.tiltTransitionWidth,
|
|
2225
2387
|
tiltPeakIntensity: m.tiltPeakIntensity
|
|
2226
|
-
},
|
|
2388
|
+
}, u = Lt(p.channels), x = p.motion;
|
|
2227
2389
|
} else
|
|
2228
|
-
f = this.buildLegacyConfig(
|
|
2229
|
-
this.renderer = new
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2390
|
+
f = this.buildLegacyConfig(h, i.width);
|
|
2391
|
+
this.renderer = new Re(this.container, f), this.renderer.initialize(i, r.meta.width, r.meta.height), u && this.renderer.updateCurveLUTs(
|
|
2392
|
+
u.displacementLUT,
|
|
2393
|
+
u.blurLUT,
|
|
2394
|
+
u.glowLUT,
|
|
2395
|
+
u.colorShiftLUT,
|
|
2396
|
+
u.colorShiftParams ?? void 0
|
|
2235
2397
|
);
|
|
2236
|
-
const d = x.tiltPlaneInput ?? !1, y = x.tiltPitchSensitivity ?? 0.35, E = x.tiltYawSensitivity ?? 0.15,
|
|
2398
|
+
const d = x.tiltPlaneInput ?? !1, y = x.tiltPitchSensitivity ?? 0.35, E = x.tiltYawSensitivity ?? 0.15, g = p?.channels.find((m) => m.channel === "blur" && m.enabled)?.params?.focalCenter ?? 0.5, v = o;
|
|
2237
2399
|
if (this.renderer.start(
|
|
2238
2400
|
i,
|
|
2239
|
-
|
|
2401
|
+
c,
|
|
2240
2402
|
() => {
|
|
2241
2403
|
const m = this._input;
|
|
2242
2404
|
if (d) {
|
|
2243
|
-
const A = m.y * y,
|
|
2405
|
+
const A = m.y * y, P = m.x * E, F = Math.cos(A), _ = Math.sin(A), I = Math.cos(P), S = Math.sin(P) * F, D = -_, U = I * F, M = 0.5 + g * (5 - 0.5);
|
|
2244
2406
|
return {
|
|
2245
2407
|
x: m.x * 0.3,
|
|
2246
2408
|
y: m.y * 0.3,
|
|
2247
|
-
tiltPlaneNormal: [S,
|
|
2409
|
+
tiltPlaneNormal: [S, D, U],
|
|
2248
2410
|
tiltPlaneD: U * M
|
|
2249
2411
|
};
|
|
2250
2412
|
}
|
|
@@ -2270,8 +2432,8 @@ class xt extends HTMLElement {
|
|
|
2270
2432
|
videoWidth: i.width,
|
|
2271
2433
|
videoHeight: i.height,
|
|
2272
2434
|
duration: i.duration,
|
|
2273
|
-
depthProfile:
|
|
2274
|
-
derivedParams:
|
|
2435
|
+
depthProfile: a,
|
|
2436
|
+
derivedParams: h,
|
|
2275
2437
|
motionConfig: x
|
|
2276
2438
|
});
|
|
2277
2439
|
} catch (i) {
|
|
@@ -2295,9 +2457,9 @@ class xt extends HTMLElement {
|
|
|
2295
2457
|
contrastLow: 0.05,
|
|
2296
2458
|
contrastHigh: 0.95,
|
|
2297
2459
|
verticalReduction: 0.5
|
|
2298
|
-
}, n =
|
|
2460
|
+
}, n = Ut(t, e);
|
|
2299
2461
|
this.renderer.updateConfig(n);
|
|
2300
|
-
const i =
|
|
2462
|
+
const i = Lt(t);
|
|
2301
2463
|
this.renderer.updateCurveLUTs(
|
|
2302
2464
|
i.displacementLUT,
|
|
2303
2465
|
i.blurLUT,
|
|
@@ -2359,15 +2521,15 @@ class Rt {
|
|
|
2359
2521
|
createResources(t, e, n) {
|
|
2360
2522
|
const i = this.gl;
|
|
2361
2523
|
this.dispose();
|
|
2362
|
-
const r = Math.max(1, Math.round(t / n)),
|
|
2363
|
-
this._width = r, this._height =
|
|
2364
|
-
const
|
|
2524
|
+
const r = Math.max(1, Math.round(t / n)), o = Math.max(1, Math.round(e / n));
|
|
2525
|
+
this._width = r, this._height = o;
|
|
2526
|
+
const l = (h, c, f, u) => {
|
|
2365
2527
|
const x = i.createFramebuffer();
|
|
2366
|
-
return i.bindFramebuffer(i.FRAMEBUFFER, x), i.bindTexture(i.TEXTURE_2D,
|
|
2528
|
+
return i.bindFramebuffer(i.FRAMEBUFFER, x), i.bindTexture(i.TEXTURE_2D, h), i.texStorage2D(i.TEXTURE_2D, 1, c, f, u), 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, h, 0), i.bindFramebuffer(i.FRAMEBUFFER, null), x;
|
|
2367
2529
|
};
|
|
2368
|
-
this.maskTex = i.createTexture(), this.maskFbo =
|
|
2369
|
-
const
|
|
2370
|
-
this.pingTex = i.createTexture(), this.pingFbo =
|
|
2530
|
+
this.maskTex = i.createTexture(), this.maskFbo = l(this.maskTex, i.R8, r, o);
|
|
2531
|
+
const a = this.hasColorBufferFloat ? i.RG16F : i.RGBA8;
|
|
2532
|
+
this.pingTex = i.createTexture(), this.pingFbo = l(this.pingTex, a, r, o), this.pongTex = i.createTexture(), this.pongFbo = l(this.pongTex, a, r, o), this.distTex = i.createTexture(), this.distFbo = l(this.distTex, i.RGBA8, r, o), this._dirty = !0;
|
|
2371
2533
|
}
|
|
2372
2534
|
// -----------------------------------------------------------------------
|
|
2373
2535
|
// Distance field computation
|
|
@@ -2388,14 +2550,14 @@ class Rt {
|
|
|
2388
2550
|
e.viewport(0, 0, n, i), 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 / n, 1 / i), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
|
|
2389
2551
|
const r = Rt.computeFloodIterations(n, i);
|
|
2390
2552
|
e.useProgram(t.floodPass.program);
|
|
2391
|
-
let
|
|
2392
|
-
for (let
|
|
2393
|
-
const
|
|
2394
|
-
e.bindFramebuffer(e.FRAMEBUFFER,
|
|
2395
|
-
const f =
|
|
2396
|
-
|
|
2553
|
+
let o = this.pingTex, l = this.pongFbo, a = this.pongTex;
|
|
2554
|
+
for (let h = 0; h < r.length; h++) {
|
|
2555
|
+
const c = r[h] / Math.max(n, i);
|
|
2556
|
+
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);
|
|
2557
|
+
const f = o, u = l;
|
|
2558
|
+
o = a, l = u === this.pongFbo ? this.pingFbo : this.pongFbo, a = f;
|
|
2397
2559
|
}
|
|
2398
|
-
e.bindFramebuffer(e.FRAMEBUFFER, this.distFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.distPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D,
|
|
2560
|
+
e.bindFramebuffer(e.FRAMEBUFFER, this.distFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.distPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, o), e.uniform1i(t.distPass.uniforms.uSeedTex, 5), e.activeTexture(e.TEXTURE6), e.bindTexture(e.TEXTURE_2D, this.maskTex), e.uniform1i(t.distPass.uniforms.uMask, 6), e.uniform1f(t.distPass.uniforms.uBevelWidth, t.distRange), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, this.distTex), e.bindFramebuffer(e.FRAMEBUFFER, null), this._dirty = !1;
|
|
2399
2561
|
}
|
|
2400
2562
|
// -----------------------------------------------------------------------
|
|
2401
2563
|
// Flood iteration planning (shared between backends)
|
|
@@ -2471,14 +2633,14 @@ void main() {
|
|
|
2471
2633
|
fragSeed = vec2(-1.0);
|
|
2472
2634
|
}
|
|
2473
2635
|
}
|
|
2474
|
-
`,
|
|
2636
|
+
`, ke = `#version 300 es
|
|
2475
2637
|
in vec2 aPosition;
|
|
2476
2638
|
out vec2 vUv;
|
|
2477
2639
|
void main() {
|
|
2478
2640
|
vUv = aPosition * 0.5 + 0.5;
|
|
2479
2641
|
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
2480
2642
|
}
|
|
2481
|
-
`,
|
|
2643
|
+
`, Oe = `#version 300 es
|
|
2482
2644
|
precision highp float;
|
|
2483
2645
|
uniform sampler2D uSeedTex;
|
|
2484
2646
|
uniform float uStepSize;
|
|
@@ -2507,7 +2669,7 @@ void main() {
|
|
|
2507
2669
|
|
|
2508
2670
|
fragSeed = bestSeed;
|
|
2509
2671
|
}
|
|
2510
|
-
`,
|
|
2672
|
+
`, He = `#version 300 es
|
|
2511
2673
|
in vec2 aPosition;
|
|
2512
2674
|
out vec2 vUv;
|
|
2513
2675
|
void main() {
|
|
@@ -2539,7 +2701,7 @@ void main() {
|
|
|
2539
2701
|
float normalized = clamp(d / max(uBevelWidth, 0.001), 0.0, 1.0);
|
|
2540
2702
|
fragDist = vec4(normalized, 0.0, 0.0, 1.0);
|
|
2541
2703
|
}
|
|
2542
|
-
`,
|
|
2704
|
+
`, Xe = `#version 300 es
|
|
2543
2705
|
in vec2 aPosition;
|
|
2544
2706
|
uniform vec2 uUvOffset;
|
|
2545
2707
|
uniform vec2 uUvScale;
|
|
@@ -2928,38 +3090,38 @@ void main() {
|
|
|
2928
3090
|
fragColor = vec4(toSRGB(lit), 1.0);
|
|
2929
3091
|
}
|
|
2930
3092
|
`;
|
|
2931
|
-
function $e(
|
|
3093
|
+
function $e(s) {
|
|
2932
3094
|
const t = [];
|
|
2933
3095
|
let e = 0;
|
|
2934
|
-
for (let n = 0; n <
|
|
2935
|
-
const i =
|
|
2936
|
-
if (
|
|
2937
|
-
const f = -
|
|
3096
|
+
for (let n = 0; n < s.length - 2; n += 2) {
|
|
3097
|
+
const i = s[n], r = s[n + 1], o = s[n + 2], l = s[n + 3], a = o - i, h = l - r, c = Math.sqrt(a * a + h * h);
|
|
3098
|
+
if (c < 1e-6) continue;
|
|
3099
|
+
const f = -h / c, u = a / c;
|
|
2938
3100
|
t.push(
|
|
2939
3101
|
i,
|
|
2940
3102
|
r,
|
|
2941
3103
|
f,
|
|
2942
|
-
|
|
3104
|
+
u,
|
|
2943
3105
|
i,
|
|
2944
3106
|
r,
|
|
2945
3107
|
-f,
|
|
2946
|
-
-
|
|
2947
|
-
|
|
2948
|
-
|
|
3108
|
+
-u,
|
|
3109
|
+
o,
|
|
3110
|
+
l,
|
|
2949
3111
|
f,
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
3112
|
+
u,
|
|
3113
|
+
o,
|
|
3114
|
+
l,
|
|
2953
3115
|
f,
|
|
2954
|
-
|
|
3116
|
+
u,
|
|
2955
3117
|
i,
|
|
2956
3118
|
r,
|
|
2957
3119
|
-f,
|
|
2958
|
-
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3120
|
+
-u,
|
|
3121
|
+
o,
|
|
3122
|
+
l,
|
|
2961
3123
|
-f,
|
|
2962
|
-
-
|
|
3124
|
+
-u
|
|
2963
3125
|
), e += 6;
|
|
2964
3126
|
}
|
|
2965
3127
|
return {
|
|
@@ -2967,43 +3129,43 @@ function $e(o) {
|
|
|
2967
3129
|
count: e
|
|
2968
3130
|
};
|
|
2969
3131
|
}
|
|
2970
|
-
function Ke(
|
|
3132
|
+
function Ke(s, t, e, n, i) {
|
|
2971
3133
|
if (n <= 0)
|
|
2972
3134
|
return { vertices: new Float32Array(0), count: 0 };
|
|
2973
|
-
const r = i * Math.PI / 180,
|
|
2974
|
-
let
|
|
2975
|
-
for (let
|
|
2976
|
-
const f = t[
|
|
2977
|
-
if (
|
|
2978
|
-
const d =
|
|
3135
|
+
const r = i * Math.PI / 180, o = -Math.cos(r), l = Math.sin(r), a = [];
|
|
3136
|
+
let h = 0;
|
|
3137
|
+
for (let c = 0; c < t.length; c++) {
|
|
3138
|
+
const f = t[c], p = ((c + 1 < t.length ? t[c + 1] : s.length) - f) / 2;
|
|
3139
|
+
if (p < 3) continue;
|
|
3140
|
+
const d = p - 1;
|
|
2979
3141
|
let y = 0;
|
|
2980
3142
|
for (let T = 0; T < d; T++) {
|
|
2981
|
-
const w = f + T * 2, A =
|
|
2982
|
-
y += A * _ -
|
|
3143
|
+
const w = f + T * 2, A = s[w], P = s[w + 1], F = s[w + 2], _ = s[w + 3];
|
|
3144
|
+
y += A * _ - F * P;
|
|
2983
3145
|
}
|
|
2984
|
-
const E = y >= 0 ? 1 : -1, b = [],
|
|
3146
|
+
const E = y >= 0 ? 1 : -1, b = [], g = [];
|
|
2985
3147
|
for (let T = 0; T < d; T++) {
|
|
2986
|
-
const w = f + T * 2, A =
|
|
2987
|
-
|
|
3148
|
+
const w = f + T * 2, A = s[w + 2] - s[w], P = s[w + 3] - s[w + 1], F = Math.sqrt(A * A + P * P);
|
|
3149
|
+
F < 1e-8 ? (b.push(T > 0 ? b[T - 1] : 0), g.push(T > 0 ? g[T - 1] : 0)) : (b.push(-P / F * E), g.push(A / F * E));
|
|
2988
3150
|
}
|
|
2989
3151
|
const v = [], m = [];
|
|
2990
3152
|
for (let T = 0; T < d; T++) {
|
|
2991
3153
|
const w = (T - 1 + d) % d;
|
|
2992
|
-
let A = b[w] + b[T],
|
|
2993
|
-
const
|
|
2994
|
-
|
|
3154
|
+
let A = b[w] + b[T], P = g[w] + g[T];
|
|
3155
|
+
const F = Math.sqrt(A * A + P * P);
|
|
3156
|
+
F > 1e-8 ? (A /= F, P /= F) : (A = b[T], P = g[T]), v.push(A), m.push(P);
|
|
2995
3157
|
}
|
|
2996
3158
|
for (let T = 0; T < d; T++) {
|
|
2997
|
-
const w = T, A = (T + 1) % d,
|
|
2998
|
-
|
|
3159
|
+
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] * n, At = I + m[w] * n, Jt = C + v[A] * n, Qt = S + m[A] * n;
|
|
3160
|
+
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;
|
|
2999
3161
|
}
|
|
3000
3162
|
}
|
|
3001
3163
|
return {
|
|
3002
|
-
vertices: new Float32Array(
|
|
3003
|
-
count:
|
|
3164
|
+
vertices: new Float32Array(a),
|
|
3165
|
+
count: h
|
|
3004
3166
|
};
|
|
3005
3167
|
}
|
|
3006
|
-
class Je extends
|
|
3168
|
+
class Je extends gt {
|
|
3007
3169
|
gl = null;
|
|
3008
3170
|
// Render passes (each owns its program + cached uniforms)
|
|
3009
3171
|
stencilPass = null;
|
|
@@ -3025,7 +3187,7 @@ class Je extends mt {
|
|
|
3025
3187
|
chamferVao = null;
|
|
3026
3188
|
chamferVertexCount = 0;
|
|
3027
3189
|
// Source textures (via TextureRegistry — init-time allocation)
|
|
3028
|
-
textures = new
|
|
3190
|
+
textures = new Ht();
|
|
3029
3191
|
videoSlot;
|
|
3030
3192
|
depthSlot;
|
|
3031
3193
|
// Interior FBO (units 2, 3)
|
|
@@ -3052,7 +3214,7 @@ class Je extends mt {
|
|
|
3052
3214
|
this.lightDirX = Math.cos(n), this.lightDirY = Math.sin(n);
|
|
3053
3215
|
const i = this.config.lightDirection, r = Math.sqrt(i[0] * i[0] + i[1] * i[1] + i[2] * i[2]);
|
|
3054
3216
|
r > 1e-6 && (this.lightDir3 = [i[0] / r, i[1] / r, i[2] / r]);
|
|
3055
|
-
const
|
|
3217
|
+
const o = this.canvas.getContext("webgl2", {
|
|
3056
3218
|
antialias: !0,
|
|
3057
3219
|
alpha: !0,
|
|
3058
3220
|
premultipliedAlpha: !0,
|
|
@@ -3060,8 +3222,8 @@ class Je extends mt {
|
|
|
3060
3222
|
desynchronized: !0,
|
|
3061
3223
|
powerPreference: "high-performance"
|
|
3062
3224
|
});
|
|
3063
|
-
if (!
|
|
3064
|
-
this.gl =
|
|
3225
|
+
if (!o) throw new Error("WebGL 2 is not supported.");
|
|
3226
|
+
this.gl = o, this.qualityParams = Nt(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();
|
|
3065
3227
|
}
|
|
3066
3228
|
initialize(t, e, n, i) {
|
|
3067
3229
|
const r = this.gl;
|
|
@@ -3100,10 +3262,10 @@ class Je extends mt {
|
|
|
3100
3262
|
this.boundaryVao = e.createVertexArray(), e.bindVertexArray(this.boundaryVao);
|
|
3101
3263
|
const i = e.createBuffer();
|
|
3102
3264
|
e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, n.vertices, e.STATIC_DRAW);
|
|
3103
|
-
const r = 16,
|
|
3104
|
-
e.enableVertexAttribArray(
|
|
3105
|
-
const
|
|
3106
|
-
|
|
3265
|
+
const r = 16, o = e.getAttribLocation(this.boundaryPass.program, "aPosition");
|
|
3266
|
+
e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
|
|
3267
|
+
const l = e.getAttribLocation(this.boundaryPass.program, "aNormal");
|
|
3268
|
+
l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 2, e.FLOAT, !1, r, 8)), this.boundaryVertexCount = n.count, e.bindVertexArray(null);
|
|
3107
3269
|
}
|
|
3108
3270
|
uploadChamferMesh(t) {
|
|
3109
3271
|
const e = this.gl;
|
|
@@ -3119,12 +3281,12 @@ class Je extends mt {
|
|
|
3119
3281
|
this.chamferVao = e.createVertexArray(), e.bindVertexArray(this.chamferVao);
|
|
3120
3282
|
const i = e.createBuffer();
|
|
3121
3283
|
e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, n.vertices, e.STATIC_DRAW);
|
|
3122
|
-
const r = 24,
|
|
3123
|
-
e.enableVertexAttribArray(
|
|
3124
|
-
const
|
|
3125
|
-
|
|
3126
|
-
const
|
|
3127
|
-
|
|
3284
|
+
const r = 24, o = e.getAttribLocation(this.chamferPass.program, "aPosition");
|
|
3285
|
+
e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
|
|
3286
|
+
const l = e.getAttribLocation(this.chamferPass.program, "aNormal3");
|
|
3287
|
+
l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 3, e.FLOAT, !1, r, 8));
|
|
3288
|
+
const a = e.getAttribLocation(this.chamferPass.program, "aLerpT");
|
|
3289
|
+
a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 1, e.FLOAT, !1, r, 20)), this.chamferVertexCount = n.count, e.bindVertexArray(null);
|
|
3128
3290
|
}
|
|
3129
3291
|
disposeChamferGeometry() {
|
|
3130
3292
|
const t = this.gl;
|
|
@@ -3166,7 +3328,7 @@ class Je extends mt {
|
|
|
3166
3328
|
// -----------------------------------------------------------------------
|
|
3167
3329
|
initGPUResources() {
|
|
3168
3330
|
const t = this.gl;
|
|
3169
|
-
t && (this.stencilPass =
|
|
3331
|
+
t && (this.stencilPass = O(t, "stencil", Le, _e, ["uMeshScale"]), this.maskPass = O(t, "mask", Ie, Me, ["uMeshScale"]), this.jfaSeedPass = O(t, "jfa-seed", Be, Ve, ["uMask", "uTexelSize"]), this.jfaFloodPass = O(t, "jfa-flood", ke, Oe, ["uSeedTex", "uStepSize"]), this.jfaDistPass = O(t, "jfa-dist", He, Ne, ["uSeedTex", "uMask", "uBevelWidth"]), this.interiorPass = O(t, "interior", Xe, Ge, [
|
|
3170
3332
|
"uImage",
|
|
3171
3333
|
"uDepth",
|
|
3172
3334
|
"uOffset",
|
|
@@ -3187,12 +3349,12 @@ class Je extends mt {
|
|
|
3187
3349
|
"uBrightnessBias",
|
|
3188
3350
|
"uUvOffset",
|
|
3189
3351
|
"uUvScale"
|
|
3190
|
-
]), this.compositePass =
|
|
3352
|
+
]), this.compositePass = O(t, "composite", We, ze, [
|
|
3191
3353
|
"uInteriorColor",
|
|
3192
3354
|
"uDistField",
|
|
3193
3355
|
"uEdgeOcclusionWidth",
|
|
3194
3356
|
"uEdgeOcclusionStrength"
|
|
3195
|
-
]), this.boundaryPass =
|
|
3357
|
+
]), this.boundaryPass = O(t, "boundary", qe, Ye, [
|
|
3196
3358
|
"uInteriorColor",
|
|
3197
3359
|
"uInteriorDepth",
|
|
3198
3360
|
"uDistField",
|
|
@@ -3209,7 +3371,7 @@ class Je extends mt {
|
|
|
3209
3371
|
"uEdgeColor",
|
|
3210
3372
|
"uLightDir",
|
|
3211
3373
|
"uBevelIntensity"
|
|
3212
|
-
]), this.chamferPass =
|
|
3374
|
+
]), this.chamferPass = O(t, "chamfer", je, Ze, [
|
|
3213
3375
|
"uMeshScale",
|
|
3214
3376
|
"uLightDir3",
|
|
3215
3377
|
"uChamferColor",
|
|
@@ -3234,11 +3396,15 @@ class Je extends mt {
|
|
|
3234
3396
|
if (!t || !this.interiorPass || !this.quadVao) return;
|
|
3235
3397
|
const n = e?.getImageSource();
|
|
3236
3398
|
if (!n || !this.interiorFbo || !this.interiorColorTex || !this.interiorDepthTex) return;
|
|
3237
|
-
this.jfa?.isDirty && this.maskVao
|
|
3399
|
+
if (this.jfa?.isDirty && this.maskVao) {
|
|
3400
|
+
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));
|
|
3401
|
+
(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);
|
|
3402
|
+
}
|
|
3403
|
+
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, n), this.rvfcSupported || this.onDepthUpdate(e.currentTime);
|
|
3238
3404
|
let i = 0, r = 0;
|
|
3239
3405
|
if (this.readInput) {
|
|
3240
|
-
const
|
|
3241
|
-
i = -
|
|
3406
|
+
const o = this.readInput();
|
|
3407
|
+
i = -o.x, r = o.y;
|
|
3242
3408
|
}
|
|
3243
3409
|
if (t.bindFramebuffer(t.FRAMEBUFFER, this.interiorFbo), t.checkFramebufferStatus(t.FRAMEBUFFER) !== t.FRAMEBUFFER_COMPLETE) {
|
|
3244
3410
|
t.bindFramebuffer(t.FRAMEBUFFER, null);
|
|
@@ -3264,7 +3430,7 @@ class Je extends mt {
|
|
|
3264
3430
|
e.RED,
|
|
3265
3431
|
e.UNSIGNED_BYTE,
|
|
3266
3432
|
n
|
|
3267
|
-
);
|
|
3433
|
+
), this.jfa && this.jfa.markDirty();
|
|
3268
3434
|
}
|
|
3269
3435
|
// -----------------------------------------------------------------------
|
|
3270
3436
|
// Resize handling
|
|
@@ -3272,12 +3438,10 @@ class Je extends mt {
|
|
|
3272
3438
|
recalculateViewportLayout() {
|
|
3273
3439
|
const t = this.gl;
|
|
3274
3440
|
if (!t) return;
|
|
3275
|
-
const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i),
|
|
3276
|
-
(this.canvas.width !== r || this.canvas.height !==
|
|
3277
|
-
const
|
|
3278
|
-
|
|
3279
|
-
const u = e / n, f = 0.65;
|
|
3280
|
-
this.meshScaleX = f, this.meshScaleY = f, u > this.meshAspect ? this.meshScaleX = f * (this.meshAspect / u) : this.meshScaleY = f * (u / 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 / s)), this.chamferPass && (t.useProgram(this.chamferPass.program), t.uniform2f(this.chamferPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY)), this.jfa && this.jfa.markDirty();
|
|
3441
|
+
const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), o = Math.round(n * i);
|
|
3442
|
+
(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]));
|
|
3443
|
+
const l = e / n, a = 0.65;
|
|
3444
|
+
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));
|
|
3281
3445
|
}
|
|
3282
3446
|
// -----------------------------------------------------------------------
|
|
3283
3447
|
// Context loss
|
|
@@ -3335,336 +3499,336 @@ class Je extends mt {
|
|
|
3335
3499
|
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);
|
|
3336
3500
|
}
|
|
3337
3501
|
}
|
|
3338
|
-
async function Tt(
|
|
3339
|
-
const t = await fetch(
|
|
3502
|
+
async function Tt(s) {
|
|
3503
|
+
const t = await fetch(s);
|
|
3340
3504
|
if (!t.ok)
|
|
3341
3505
|
throw new Error(`Failed to fetch SVG: ${t.status} ${t.statusText}`);
|
|
3342
3506
|
const e = await t.text();
|
|
3343
3507
|
return Qe(e);
|
|
3344
3508
|
}
|
|
3345
|
-
function Qe(
|
|
3346
|
-
const n = new DOMParser().parseFromString(
|
|
3509
|
+
function Qe(s) {
|
|
3510
|
+
const n = new DOMParser().parseFromString(s, "image/svg+xml").querySelector("svg");
|
|
3347
3511
|
if (!n)
|
|
3348
3512
|
throw new Error("No <svg> element found in document.");
|
|
3349
3513
|
const i = tn(n);
|
|
3350
3514
|
if (i.length === 0)
|
|
3351
3515
|
throw new Error("No path data found in SVG.");
|
|
3352
|
-
let r = 1 / 0,
|
|
3516
|
+
let r = 1 / 0, o = 1 / 0, l = -1 / 0, a = -1 / 0;
|
|
3353
3517
|
for (const C of i)
|
|
3354
3518
|
for (let S = 0; S < C.length; S += 2)
|
|
3355
|
-
r = Math.min(r, C[S]),
|
|
3356
|
-
const
|
|
3519
|
+
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]);
|
|
3520
|
+
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 = i.map((C) => {
|
|
3357
3521
|
const S = [];
|
|
3358
|
-
for (let
|
|
3359
|
-
S.push((C[
|
|
3522
|
+
for (let D = 0; D < C.length; D += 2)
|
|
3523
|
+
S.push((C[D] - f) * x), S.push(-((C[D + 1] - u) * x));
|
|
3360
3524
|
return S;
|
|
3361
3525
|
}), y = un(d), E = [], b = [];
|
|
3362
3526
|
for (const C of y) {
|
|
3363
|
-
const { flatCoords: S, holeIndices:
|
|
3364
|
-
for (const
|
|
3365
|
-
b.push(
|
|
3366
|
-
for (const
|
|
3367
|
-
E.push(
|
|
3527
|
+
const { flatCoords: S, holeIndices: D } = ln(C), U = cn(S, D), M = E.length / 2;
|
|
3528
|
+
for (const k of U)
|
|
3529
|
+
b.push(k + M);
|
|
3530
|
+
for (const k of S)
|
|
3531
|
+
E.push(k);
|
|
3368
3532
|
}
|
|
3369
|
-
const
|
|
3533
|
+
const g = E, v = b, m = [], T = [], w = [], A = zt(d);
|
|
3370
3534
|
for (let C = 0; C < d.length; C++) {
|
|
3371
3535
|
const S = d[C];
|
|
3372
3536
|
T.push(m.length), w.push(A[C]);
|
|
3373
|
-
for (let
|
|
3374
|
-
m.push(S[
|
|
3537
|
+
for (let D = 0; D < S.length; D++)
|
|
3538
|
+
m.push(S[D]);
|
|
3375
3539
|
S.length >= 2 && m.push(S[0], S[1]);
|
|
3376
3540
|
}
|
|
3377
|
-
let
|
|
3378
|
-
for (let C = 0; C <
|
|
3379
|
-
|
|
3541
|
+
let P = 1 / 0, F = 1 / 0, _ = -1 / 0, I = -1 / 0;
|
|
3542
|
+
for (let C = 0; C < g.length; C += 2)
|
|
3543
|
+
P = Math.min(P, g[C]), _ = Math.max(_, g[C]), F = Math.min(F, g[C + 1]), I = Math.max(I, g[C + 1]);
|
|
3380
3544
|
return {
|
|
3381
|
-
vertices: new Float32Array(
|
|
3545
|
+
vertices: new Float32Array(g),
|
|
3382
3546
|
indices: new Uint16Array(v),
|
|
3383
3547
|
edgeVertices: new Float32Array(m),
|
|
3384
3548
|
contourOffsets: T,
|
|
3385
3549
|
contourIsHole: w,
|
|
3386
|
-
bounds: { minX:
|
|
3387
|
-
aspect:
|
|
3550
|
+
bounds: { minX: P, maxX: _, minY: F, maxY: I },
|
|
3551
|
+
aspect: p
|
|
3388
3552
|
};
|
|
3389
3553
|
}
|
|
3390
|
-
function tn(
|
|
3554
|
+
function tn(s) {
|
|
3391
3555
|
const t = [];
|
|
3392
|
-
return
|
|
3393
|
-
const
|
|
3394
|
-
if (!
|
|
3395
|
-
const
|
|
3396
|
-
t.push(...
|
|
3397
|
-
}),
|
|
3398
|
-
const
|
|
3399
|
-
if (!
|
|
3400
|
-
const
|
|
3401
|
-
|
|
3402
|
-
}),
|
|
3403
|
-
const
|
|
3404
|
-
if (!
|
|
3405
|
-
const
|
|
3406
|
-
|
|
3407
|
-
}),
|
|
3408
|
-
const
|
|
3409
|
-
f > 0 &&
|
|
3410
|
-
}),
|
|
3411
|
-
const
|
|
3412
|
-
f > 0 && t.push(en(
|
|
3413
|
-
}),
|
|
3414
|
-
const
|
|
3415
|
-
f > 0 &&
|
|
3556
|
+
return s.querySelectorAll("path").forEach((a) => {
|
|
3557
|
+
const h = a.getAttribute("d");
|
|
3558
|
+
if (!h) return;
|
|
3559
|
+
const c = rn(h);
|
|
3560
|
+
t.push(...c);
|
|
3561
|
+
}), s.querySelectorAll("polygon").forEach((a) => {
|
|
3562
|
+
const h = a.getAttribute("points");
|
|
3563
|
+
if (!h) return;
|
|
3564
|
+
const c = _t(h);
|
|
3565
|
+
c.length >= 6 && t.push(c);
|
|
3566
|
+
}), s.querySelectorAll("polyline").forEach((a) => {
|
|
3567
|
+
const h = a.getAttribute("points");
|
|
3568
|
+
if (!h) return;
|
|
3569
|
+
const c = _t(h);
|
|
3570
|
+
c.length >= 6 && t.push(c);
|
|
3571
|
+
}), s.querySelectorAll("rect").forEach((a) => {
|
|
3572
|
+
const h = parseFloat(a.getAttribute("x") || "0"), c = parseFloat(a.getAttribute("y") || "0"), f = parseFloat(a.getAttribute("width") || "0"), u = parseFloat(a.getAttribute("height") || "0");
|
|
3573
|
+
f > 0 && u > 0 && t.push([h, c, h + f, c, h + f, c + u, h, c + u]);
|
|
3574
|
+
}), s.querySelectorAll("circle").forEach((a) => {
|
|
3575
|
+
const h = parseFloat(a.getAttribute("cx") || "0"), c = parseFloat(a.getAttribute("cy") || "0"), f = parseFloat(a.getAttribute("r") || "0");
|
|
3576
|
+
f > 0 && t.push(en(h, c, f));
|
|
3577
|
+
}), s.querySelectorAll("ellipse").forEach((a) => {
|
|
3578
|
+
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");
|
|
3579
|
+
f > 0 && u > 0 && t.push(nn(h, c, f, u));
|
|
3416
3580
|
}), t;
|
|
3417
3581
|
}
|
|
3418
|
-
function
|
|
3419
|
-
const t = [], e =
|
|
3582
|
+
function _t(s) {
|
|
3583
|
+
const t = [], e = s.trim().split(/[\s,]+/);
|
|
3420
3584
|
for (let n = 0; n < e.length - 1; n += 2) {
|
|
3421
3585
|
const i = parseFloat(e[n]), r = parseFloat(e[n + 1]);
|
|
3422
3586
|
Number.isFinite(i) && Number.isFinite(r) && t.push(i, r);
|
|
3423
3587
|
}
|
|
3424
3588
|
return t;
|
|
3425
3589
|
}
|
|
3426
|
-
function en(
|
|
3590
|
+
function en(s, t, e, n = 64) {
|
|
3427
3591
|
const i = [];
|
|
3428
3592
|
for (let r = 0; r < n; r++) {
|
|
3429
|
-
const
|
|
3430
|
-
i.push(
|
|
3593
|
+
const o = 2 * Math.PI * r / n;
|
|
3594
|
+
i.push(s + e * Math.cos(o), t + e * Math.sin(o));
|
|
3431
3595
|
}
|
|
3432
3596
|
return i;
|
|
3433
3597
|
}
|
|
3434
|
-
function nn(
|
|
3598
|
+
function nn(s, t, e, n, i = 64) {
|
|
3435
3599
|
const r = [];
|
|
3436
|
-
for (let
|
|
3437
|
-
const
|
|
3438
|
-
r.push(
|
|
3600
|
+
for (let o = 0; o < i; o++) {
|
|
3601
|
+
const l = 2 * Math.PI * o / i;
|
|
3602
|
+
r.push(s + e * Math.cos(l), t + n * Math.sin(l));
|
|
3439
3603
|
}
|
|
3440
3604
|
return r;
|
|
3441
3605
|
}
|
|
3442
|
-
function rn(
|
|
3606
|
+
function rn(s) {
|
|
3443
3607
|
const t = [];
|
|
3444
|
-
let e = [], n = 0, i = 0, r = 0,
|
|
3445
|
-
const
|
|
3608
|
+
let e = [], n = 0, i = 0, r = 0, o = 0, l = 0, a = 0, h = "";
|
|
3609
|
+
const c = sn(s);
|
|
3446
3610
|
let f = 0;
|
|
3447
|
-
function
|
|
3448
|
-
return f >=
|
|
3449
|
-
}
|
|
3450
|
-
for (; f <
|
|
3451
|
-
const x =
|
|
3452
|
-
let
|
|
3453
|
-
/^[a-zA-Z]$/.test(x) ? (
|
|
3454
|
-
const d =
|
|
3455
|
-
switch (
|
|
3611
|
+
function u() {
|
|
3612
|
+
return f >= c.length ? 0 : parseFloat(c[f++]);
|
|
3613
|
+
}
|
|
3614
|
+
for (; f < c.length; ) {
|
|
3615
|
+
const x = c[f];
|
|
3616
|
+
let p;
|
|
3617
|
+
/^[a-zA-Z]$/.test(x) ? (p = x, f++) : p = h === "M" ? "L" : h === "m" ? "l" : h;
|
|
3618
|
+
const d = p === p.toLowerCase();
|
|
3619
|
+
switch (p.toUpperCase()) {
|
|
3456
3620
|
case "M": {
|
|
3457
3621
|
e.length > 0 && t.push(e), e = [];
|
|
3458
|
-
const E =
|
|
3459
|
-
n = E, i = b, r = E,
|
|
3622
|
+
const E = u() + (d ? n : 0), b = u() + (d ? i : 0);
|
|
3623
|
+
n = E, i = b, r = E, o = b, e.push(n, i), l = n, a = i;
|
|
3460
3624
|
break;
|
|
3461
3625
|
}
|
|
3462
3626
|
case "L": {
|
|
3463
|
-
n =
|
|
3627
|
+
n = u() + (d ? n : 0), i = u() + (d ? i : 0), e.push(n, i), l = n, a = i;
|
|
3464
3628
|
break;
|
|
3465
3629
|
}
|
|
3466
3630
|
case "H": {
|
|
3467
|
-
n =
|
|
3631
|
+
n = u() + (d ? n : 0), e.push(n, i), l = n, a = i;
|
|
3468
3632
|
break;
|
|
3469
3633
|
}
|
|
3470
3634
|
case "V": {
|
|
3471
|
-
i =
|
|
3635
|
+
i = u() + (d ? i : 0), e.push(n, i), l = n, a = i;
|
|
3472
3636
|
break;
|
|
3473
3637
|
}
|
|
3474
3638
|
case "C": {
|
|
3475
|
-
const E =
|
|
3476
|
-
|
|
3639
|
+
const E = u() + (d ? n : 0), b = u() + (d ? i : 0), g = u() + (d ? n : 0), v = u() + (d ? i : 0), m = u() + (d ? n : 0), T = u() + (d ? i : 0);
|
|
3640
|
+
it(e, n, i, E, b, g, v, m, T), n = m, i = T, l = g, a = v;
|
|
3477
3641
|
break;
|
|
3478
3642
|
}
|
|
3479
3643
|
case "S": {
|
|
3480
|
-
const E = 2 * n -
|
|
3481
|
-
|
|
3644
|
+
const E = 2 * n - l, b = 2 * i - a, g = u() + (d ? n : 0), v = u() + (d ? i : 0), m = u() + (d ? n : 0), T = u() + (d ? i : 0);
|
|
3645
|
+
it(e, n, i, E, b, g, v, m, T), n = m, i = T, l = g, a = v;
|
|
3482
3646
|
break;
|
|
3483
3647
|
}
|
|
3484
3648
|
case "Q": {
|
|
3485
|
-
const E =
|
|
3486
|
-
|
|
3649
|
+
const E = u() + (d ? n : 0), b = u() + (d ? i : 0), g = u() + (d ? n : 0), v = u() + (d ? i : 0);
|
|
3650
|
+
It(e, n, i, E, b, g, v), n = g, i = v, l = E, a = b;
|
|
3487
3651
|
break;
|
|
3488
3652
|
}
|
|
3489
3653
|
case "T": {
|
|
3490
|
-
const E = 2 * n -
|
|
3491
|
-
|
|
3654
|
+
const E = 2 * n - l, b = 2 * i - a, g = u() + (d ? n : 0), v = u() + (d ? i : 0);
|
|
3655
|
+
It(e, n, i, E, b, g, v), n = g, i = v, l = E, a = b;
|
|
3492
3656
|
break;
|
|
3493
3657
|
}
|
|
3494
3658
|
case "A": {
|
|
3495
|
-
const E =
|
|
3496
|
-
an(e, n, i, E, b,
|
|
3659
|
+
const E = u(), b = u(), g = u(), v = u(), m = u(), T = u() + (d ? n : 0), w = u() + (d ? i : 0);
|
|
3660
|
+
an(e, n, i, E, b, g, !!v, !!m, T, w), n = T, i = w, l = n, a = i;
|
|
3497
3661
|
break;
|
|
3498
3662
|
}
|
|
3499
3663
|
case "Z": {
|
|
3500
|
-
n = r, i =
|
|
3664
|
+
n = r, i = o, e.length > 0 && t.push(e), e = [], l = n, a = i;
|
|
3501
3665
|
break;
|
|
3502
3666
|
}
|
|
3503
3667
|
default:
|
|
3504
3668
|
f++;
|
|
3505
3669
|
break;
|
|
3506
3670
|
}
|
|
3507
|
-
|
|
3671
|
+
h = p;
|
|
3508
3672
|
}
|
|
3509
3673
|
return e.length >= 6 && t.push(e), t;
|
|
3510
3674
|
}
|
|
3511
|
-
function
|
|
3675
|
+
function sn(s) {
|
|
3512
3676
|
const t = [], e = /([a-zA-Z])|([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/g;
|
|
3513
3677
|
let n;
|
|
3514
|
-
for (; (n = e.exec(
|
|
3678
|
+
for (; (n = e.exec(s)) !== null; )
|
|
3515
3679
|
t.push(n[0]);
|
|
3516
3680
|
return t;
|
|
3517
3681
|
}
|
|
3518
|
-
const
|
|
3519
|
-
function
|
|
3520
|
-
if (
|
|
3521
|
-
|
|
3682
|
+
const on = 0.5;
|
|
3683
|
+
function it(s, t, e, n, i, r, o, l, a, h = 0) {
|
|
3684
|
+
if (h > 12) {
|
|
3685
|
+
s.push(l, a);
|
|
3522
3686
|
return;
|
|
3523
3687
|
}
|
|
3524
|
-
const
|
|
3525
|
-
if (
|
|
3526
|
-
|
|
3688
|
+
const c = l - t, f = a - e, u = Math.sqrt(c * c + f * f);
|
|
3689
|
+
if (u < 1e-6) {
|
|
3690
|
+
s.push(l, a);
|
|
3527
3691
|
return;
|
|
3528
3692
|
}
|
|
3529
|
-
const x = Math.abs((n -
|
|
3530
|
-
if (x +
|
|
3531
|
-
|
|
3693
|
+
const x = Math.abs((n - l) * f - (i - a) * c) / u, p = Math.abs((r - l) * f - (o - a) * c) / u;
|
|
3694
|
+
if (x + p < on) {
|
|
3695
|
+
s.push(l, a);
|
|
3532
3696
|
return;
|
|
3533
3697
|
}
|
|
3534
|
-
const d = (t + n) / 2, y = (e + i) / 2, E = (n + r) / 2, b = (i +
|
|
3535
|
-
|
|
3698
|
+
const d = (t + n) / 2, y = (e + i) / 2, E = (n + r) / 2, b = (i + o) / 2, g = (r + l) / 2, v = (o + a) / 2, m = (d + E) / 2, T = (y + b) / 2, w = (E + g) / 2, A = (b + v) / 2, P = (m + w) / 2, F = (T + A) / 2;
|
|
3699
|
+
it(s, t, e, d, y, m, T, P, F, h + 1), it(s, P, F, w, A, g, v, l, a, h + 1);
|
|
3536
3700
|
}
|
|
3537
|
-
function
|
|
3538
|
-
const
|
|
3539
|
-
|
|
3701
|
+
function It(s, t, e, n, i, r, o) {
|
|
3702
|
+
const l = t + 0.6666666666666666 * (n - t), a = e + 2 / 3 * (i - e), h = r + 2 / 3 * (n - r), c = o + 2 / 3 * (i - o);
|
|
3703
|
+
it(s, t, e, l, a, h, c, r, o);
|
|
3540
3704
|
}
|
|
3541
|
-
function an(
|
|
3705
|
+
function an(s, t, e, n, i, r, o, l, a, h) {
|
|
3542
3706
|
if (n === 0 || i === 0) {
|
|
3543
|
-
|
|
3707
|
+
s.push(a, h);
|
|
3544
3708
|
return;
|
|
3545
3709
|
}
|
|
3546
|
-
let
|
|
3547
|
-
const
|
|
3548
|
-
let
|
|
3549
|
-
if (
|
|
3550
|
-
const U = Math.sqrt(
|
|
3551
|
-
|
|
3710
|
+
let c = Math.abs(n), f = Math.abs(i);
|
|
3711
|
+
const u = r * Math.PI / 180, x = Math.cos(u), p = Math.sin(u), d = (t - a) / 2, y = (e - h) / 2, E = x * d + p * y, b = -p * d + x * y;
|
|
3712
|
+
let g = E * E / (c * c) + b * b / (f * f);
|
|
3713
|
+
if (g > 1) {
|
|
3714
|
+
const U = Math.sqrt(g);
|
|
3715
|
+
c *= U, f *= U, g = 1;
|
|
3552
3716
|
}
|
|
3553
|
-
const v =
|
|
3717
|
+
const v = c * c, m = f * f, T = E * E, w = b * b;
|
|
3554
3718
|
let A = Math.max(0, (v * m - v * w - m * T) / (v * w + m * T));
|
|
3555
|
-
A = Math.sqrt(A),
|
|
3556
|
-
const
|
|
3557
|
-
let S =
|
|
3558
|
-
(E -
|
|
3559
|
-
(b -
|
|
3560
|
-
(-E -
|
|
3561
|
-
(-b -
|
|
3719
|
+
A = Math.sqrt(A), o === l && (A = -A);
|
|
3720
|
+
const P = A * (c * b) / f, F = A * -(f * E) / c, _ = x * P - p * F + (t + a) / 2, I = p * P + x * F + (e + h) / 2, C = Mt(1, 0, (E - P) / c, (b - F) / f);
|
|
3721
|
+
let S = Mt(
|
|
3722
|
+
(E - P) / c,
|
|
3723
|
+
(b - F) / f,
|
|
3724
|
+
(-E - P) / c,
|
|
3725
|
+
(-b - F) / f
|
|
3562
3726
|
);
|
|
3563
|
-
!
|
|
3564
|
-
const
|
|
3565
|
-
for (let U = 1; U <=
|
|
3566
|
-
const M = C + U /
|
|
3567
|
-
|
|
3727
|
+
!l && S > 0 && (S -= 2 * Math.PI), l && S < 0 && (S += 2 * Math.PI);
|
|
3728
|
+
const D = Math.max(4, Math.ceil(Math.abs(S) / (Math.PI / 16)));
|
|
3729
|
+
for (let U = 1; U <= D; U++) {
|
|
3730
|
+
const M = C + U / D * S, k = Math.cos(M), j = Math.sin(M), et = x * c * k - p * f * j + _, at = p * c * k + x * f * j + I;
|
|
3731
|
+
s.push(et, at);
|
|
3568
3732
|
}
|
|
3569
3733
|
}
|
|
3570
|
-
function
|
|
3571
|
-
const i =
|
|
3572
|
-
return i * Math.acos(Math.max(-1, Math.min(1,
|
|
3734
|
+
function Mt(s, t, e, n) {
|
|
3735
|
+
const i = s * n - t * e < 0 ? -1 : 1, r = s * e + t * n, o = Math.sqrt(s * s + t * t), l = Math.sqrt(e * e + n * n), a = r / (o * l);
|
|
3736
|
+
return i * Math.acos(Math.max(-1, Math.min(1, a)));
|
|
3573
3737
|
}
|
|
3574
|
-
function ln(
|
|
3738
|
+
function ln(s) {
|
|
3575
3739
|
const t = [], e = [];
|
|
3576
|
-
for (let n = 0; n <
|
|
3740
|
+
for (let n = 0; n < s.length; n++) {
|
|
3577
3741
|
n > 0 && e.push(t.length / 2);
|
|
3578
|
-
for (const i of
|
|
3742
|
+
for (const i of s[n])
|
|
3579
3743
|
t.push(i);
|
|
3580
3744
|
}
|
|
3581
3745
|
return { flatCoords: t, holeIndices: e };
|
|
3582
3746
|
}
|
|
3583
|
-
function
|
|
3584
|
-
const t =
|
|
3747
|
+
function zt(s) {
|
|
3748
|
+
const t = s.length, e = s.map((i) => Math.abs(qt(i))), n = new Array(t).fill(!1);
|
|
3585
3749
|
for (let i = 0; i < t; i++) {
|
|
3586
3750
|
let r = 0;
|
|
3587
|
-
const
|
|
3588
|
-
for (let
|
|
3589
|
-
i !==
|
|
3751
|
+
const o = s[i][0], l = s[i][1];
|
|
3752
|
+
for (let a = 0; a < t; a++)
|
|
3753
|
+
i !== a && e[a] > e[i] && Yt(o, l, s[a]) && r++;
|
|
3590
3754
|
n[i] = r % 2 === 1;
|
|
3591
3755
|
}
|
|
3592
3756
|
return n;
|
|
3593
3757
|
}
|
|
3594
|
-
function un(
|
|
3595
|
-
if (
|
|
3596
|
-
return [
|
|
3597
|
-
const t =
|
|
3598
|
-
const
|
|
3599
|
-
return { index:
|
|
3600
|
-
}), n = e.filter((
|
|
3758
|
+
function un(s) {
|
|
3759
|
+
if (s.length <= 1)
|
|
3760
|
+
return [s];
|
|
3761
|
+
const t = zt(s), e = s.map((o, l) => {
|
|
3762
|
+
const a = qt(o);
|
|
3763
|
+
return { index: l, contour: o, area: a, isOuter: !t[l] };
|
|
3764
|
+
}), n = e.filter((o) => o.isOuter), i = e.filter((o) => !o.isOuter);
|
|
3601
3765
|
if (n.length === 0)
|
|
3602
|
-
return
|
|
3603
|
-
const r = n.map((
|
|
3604
|
-
outer:
|
|
3766
|
+
return s.map((o) => [o]);
|
|
3767
|
+
const r = n.map((o) => ({
|
|
3768
|
+
outer: o.contour,
|
|
3605
3769
|
holes: []
|
|
3606
3770
|
}));
|
|
3607
|
-
for (const
|
|
3608
|
-
const
|
|
3609
|
-
let
|
|
3771
|
+
for (const o of i) {
|
|
3772
|
+
const l = o.contour[0], a = o.contour[1];
|
|
3773
|
+
let h = -1, c = 1 / 0;
|
|
3610
3774
|
for (let f = 0; f < n.length; f++)
|
|
3611
|
-
if (
|
|
3612
|
-
const
|
|
3613
|
-
|
|
3775
|
+
if (Yt(l, a, n[f].contour)) {
|
|
3776
|
+
const u = Math.abs(n[f].area);
|
|
3777
|
+
u < c && (c = u, h = f);
|
|
3614
3778
|
}
|
|
3615
|
-
|
|
3779
|
+
h >= 0 ? r[h].holes.push(o.contour) : r.push({ outer: o.contour, holes: [] });
|
|
3616
3780
|
}
|
|
3617
|
-
return r.map((
|
|
3781
|
+
return r.map((o) => [o.outer, ...o.holes]);
|
|
3618
3782
|
}
|
|
3619
|
-
function
|
|
3783
|
+
function qt(s) {
|
|
3620
3784
|
let t = 0;
|
|
3621
|
-
const e =
|
|
3785
|
+
const e = s.length;
|
|
3622
3786
|
for (let n = 0; n < e; n += 2) {
|
|
3623
|
-
const i =
|
|
3624
|
-
t += i *
|
|
3787
|
+
const i = s[n], r = s[n + 1], o = s[(n + 2) % e], l = s[(n + 3) % e];
|
|
3788
|
+
t += i * l - o * r;
|
|
3625
3789
|
}
|
|
3626
3790
|
return t / 2;
|
|
3627
3791
|
}
|
|
3628
|
-
function
|
|
3792
|
+
function Yt(s, t, e) {
|
|
3629
3793
|
let n = !1;
|
|
3630
3794
|
const i = e.length;
|
|
3631
|
-
for (let r = 0,
|
|
3632
|
-
const
|
|
3633
|
-
|
|
3795
|
+
for (let r = 0, o = i - 2; r < i; o = r, r += 2) {
|
|
3796
|
+
const l = e[r], a = e[r + 1], h = e[o], c = e[o + 1];
|
|
3797
|
+
a > t != c > t && s < (h - l) * (t - a) / (c - a) + l && (n = !n);
|
|
3634
3798
|
}
|
|
3635
3799
|
return n;
|
|
3636
3800
|
}
|
|
3637
|
-
function cn(
|
|
3638
|
-
const n = t && t.length > 0, i = n ? t[0] * e :
|
|
3639
|
-
let r =
|
|
3640
|
-
const
|
|
3641
|
-
if (!r || r.next === r.prev) return
|
|
3642
|
-
n && (r = pn(
|
|
3643
|
-
let
|
|
3644
|
-
if (
|
|
3645
|
-
for (let
|
|
3646
|
-
const x =
|
|
3647
|
-
x <
|
|
3801
|
+
function cn(s, t, e = 2) {
|
|
3802
|
+
const n = t && t.length > 0, i = n ? t[0] * e : s.length;
|
|
3803
|
+
let r = jt(s, 0, i, e, !0);
|
|
3804
|
+
const o = [];
|
|
3805
|
+
if (!r || r.next === r.prev) return o;
|
|
3806
|
+
n && (r = pn(s, t, r, e));
|
|
3807
|
+
let l = 1 / 0, a = 1 / 0, h = -1 / 0, c = -1 / 0, f = 0;
|
|
3808
|
+
if (s.length > 80 * e) {
|
|
3809
|
+
for (let u = 0; u < i; u += e) {
|
|
3810
|
+
const x = s[u], p = s[u + 1];
|
|
3811
|
+
x < l && (l = x), p < a && (a = p), x > h && (h = x), p > c && (c = p);
|
|
3648
3812
|
}
|
|
3649
|
-
f = Math.max(
|
|
3813
|
+
f = Math.max(h - l, c - a), f = f !== 0 ? 32767 / f : 0;
|
|
3650
3814
|
}
|
|
3651
|
-
return
|
|
3815
|
+
return rt(r, o, e, l, a, f, 0), o;
|
|
3652
3816
|
}
|
|
3653
|
-
function
|
|
3817
|
+
function jt(s, t, e, n, i) {
|
|
3654
3818
|
let r = null;
|
|
3655
|
-
if (i ===
|
|
3656
|
-
for (let
|
|
3657
|
-
r =
|
|
3819
|
+
if (i === Rn(s, t, e, n) > 0)
|
|
3820
|
+
for (let o = t; o < e; o += n)
|
|
3821
|
+
r = Bt(o, s[o], s[o + 1], r);
|
|
3658
3822
|
else
|
|
3659
|
-
for (let
|
|
3660
|
-
r =
|
|
3661
|
-
return r &&
|
|
3823
|
+
for (let o = e - n; o >= t; o -= n)
|
|
3824
|
+
r = Bt(o, s[o], s[o + 1], r);
|
|
3825
|
+
return r && vt(r, r.next) && (ot(r), r = r.next), r ? (r.next.prev = r, r.prev.next = r, r.next) : null;
|
|
3662
3826
|
}
|
|
3663
|
-
function
|
|
3664
|
-
t || (t =
|
|
3665
|
-
let e =
|
|
3827
|
+
function Y(s, t) {
|
|
3828
|
+
t || (t = s);
|
|
3829
|
+
let e = s, n;
|
|
3666
3830
|
do
|
|
3667
|
-
if (n = !1, !e.steiner && (
|
|
3831
|
+
if (n = !1, !e.steiner && (vt(e, e.next) || L(e.prev, e, e.next) === 0)) {
|
|
3668
3832
|
if (ot(e), e = t = e.prev, e === e.next) break;
|
|
3669
3833
|
n = !0;
|
|
3670
3834
|
} else
|
|
@@ -3672,215 +3836,215 @@ function z(o, t) {
|
|
|
3672
3836
|
while (n || e !== t);
|
|
3673
3837
|
return t;
|
|
3674
3838
|
}
|
|
3675
|
-
function
|
|
3676
|
-
if (!
|
|
3677
|
-
!
|
|
3678
|
-
let
|
|
3679
|
-
for (;
|
|
3680
|
-
if (
|
|
3681
|
-
t.push(
|
|
3839
|
+
function rt(s, t, e, n, i, r, o) {
|
|
3840
|
+
if (!s) return;
|
|
3841
|
+
!o && r && Tn(s, n, i, r);
|
|
3842
|
+
let l = s, a, h;
|
|
3843
|
+
for (; s.prev !== s.next; ) {
|
|
3844
|
+
if (a = s.prev, h = s.next, r ? fn(s, n, i, r) : hn(s)) {
|
|
3845
|
+
t.push(a.i / e, s.i / e, h.i / e), ot(s), s = h.next, l = h.next;
|
|
3682
3846
|
continue;
|
|
3683
3847
|
}
|
|
3684
|
-
if (
|
|
3685
|
-
|
|
3848
|
+
if (s = h, s === l) {
|
|
3849
|
+
o ? o === 1 ? (s = dn(Y(s), t, e), rt(s, t, e, n, i, r, 2)) : o === 2 && mn(s, t, e, n, i, r) : rt(Y(s), t, e, n, i, r, 1);
|
|
3686
3850
|
break;
|
|
3687
3851
|
}
|
|
3688
3852
|
}
|
|
3689
3853
|
}
|
|
3690
|
-
function hn(
|
|
3691
|
-
const t =
|
|
3854
|
+
function hn(s) {
|
|
3855
|
+
const t = s.prev, e = s, n = s.next;
|
|
3692
3856
|
if (L(t, e, n) >= 0) return !1;
|
|
3693
|
-
const i = t.x, r = e.x,
|
|
3694
|
-
let
|
|
3695
|
-
for (;
|
|
3696
|
-
if (
|
|
3857
|
+
const i = t.x, r = e.x, o = n.x, l = t.y, a = e.y, h = n.y, c = i < r ? i < o ? i : o : r < o ? r : o, f = l < a ? l < h ? l : h : a < h ? a : h, u = i > r ? i > o ? i : o : r > o ? r : o, x = l > a ? l > h ? l : h : a > h ? a : h;
|
|
3858
|
+
let p = n.next;
|
|
3859
|
+
for (; p !== t; ) {
|
|
3860
|
+
if (p.x >= c && p.x <= u && p.y >= f && p.y <= x && tt(i, l, r, a, o, h, p.x, p.y) && L(p.prev, p, p.next) >= 0)
|
|
3697
3861
|
return !1;
|
|
3698
|
-
|
|
3862
|
+
p = p.next;
|
|
3699
3863
|
}
|
|
3700
3864
|
return !0;
|
|
3701
3865
|
}
|
|
3702
|
-
function fn(
|
|
3703
|
-
const i =
|
|
3704
|
-
if (L(i, r,
|
|
3705
|
-
const
|
|
3706
|
-
let
|
|
3707
|
-
for (;
|
|
3708
|
-
if (
|
|
3866
|
+
function fn(s, t, e, n) {
|
|
3867
|
+
const i = s.prev, r = s, o = s.next;
|
|
3868
|
+
if (L(i, r, o) >= 0) return !1;
|
|
3869
|
+
const l = i.x, a = r.x, h = o.x, c = i.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, E = yt(x, p, t, e, n), b = yt(d, y, t, e, n);
|
|
3870
|
+
let g = s.prevZ, v = s.nextZ;
|
|
3871
|
+
for (; g && g.z >= E && v && v.z <= b; ) {
|
|
3872
|
+
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== i && 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 !== i && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0)) return !1;
|
|
3709
3873
|
v = v.nextZ;
|
|
3710
3874
|
}
|
|
3711
|
-
for (;
|
|
3712
|
-
if (
|
|
3713
|
-
|
|
3875
|
+
for (; g && g.z >= E; ) {
|
|
3876
|
+
if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== i && g !== o && tt(l, c, a, f, h, u, g.x, g.y) && L(g.prev, g, g.next) >= 0) return !1;
|
|
3877
|
+
g = g.prevZ;
|
|
3714
3878
|
}
|
|
3715
3879
|
for (; v && v.z <= b; ) {
|
|
3716
|
-
if (v.x >= x && v.x <= d && v.y >=
|
|
3880
|
+
if (v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !== i && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0) return !1;
|
|
3717
3881
|
v = v.nextZ;
|
|
3718
3882
|
}
|
|
3719
3883
|
return !0;
|
|
3720
3884
|
}
|
|
3721
|
-
function dn(
|
|
3722
|
-
let n =
|
|
3885
|
+
function dn(s, t, e) {
|
|
3886
|
+
let n = s;
|
|
3723
3887
|
do {
|
|
3724
3888
|
const i = n.prev, r = n.next.next;
|
|
3725
|
-
!
|
|
3726
|
-
} while (n !==
|
|
3727
|
-
return
|
|
3889
|
+
!vt(i, r) && Zt(i, n, n.next, r) && st(i, r) && st(r, i) && (t.push(i.i / e, n.i / e, r.i / e), ot(n), ot(n.next), n = s = r), n = n.next;
|
|
3890
|
+
} while (n !== s);
|
|
3891
|
+
return Y(n);
|
|
3728
3892
|
}
|
|
3729
|
-
function mn(
|
|
3730
|
-
let
|
|
3893
|
+
function mn(s, t, e, n, i, r) {
|
|
3894
|
+
let o = s;
|
|
3731
3895
|
do {
|
|
3732
|
-
let
|
|
3733
|
-
for (;
|
|
3734
|
-
if (
|
|
3735
|
-
let
|
|
3736
|
-
|
|
3896
|
+
let l = o.next.next;
|
|
3897
|
+
for (; l !== o.prev; ) {
|
|
3898
|
+
if (o.i !== l.i && Sn(o, l)) {
|
|
3899
|
+
let a = $t(o, l);
|
|
3900
|
+
o = Y(o, o.next), a = Y(a, a.next), rt(o, t, e, n, i, r, 0), rt(a, t, e, n, i, r, 0);
|
|
3737
3901
|
return;
|
|
3738
3902
|
}
|
|
3739
|
-
|
|
3903
|
+
l = l.next;
|
|
3740
3904
|
}
|
|
3741
|
-
|
|
3742
|
-
} while (
|
|
3905
|
+
o = o.next;
|
|
3906
|
+
} while (o !== s);
|
|
3743
3907
|
}
|
|
3744
|
-
function pn(
|
|
3908
|
+
function pn(s, t, e, n) {
|
|
3745
3909
|
const i = [];
|
|
3746
3910
|
for (let r = 0; r < t.length; r++) {
|
|
3747
|
-
const
|
|
3748
|
-
|
|
3911
|
+
const o = t[r] * n, l = r < t.length - 1 ? t[r + 1] * n : s.length, a = jt(s, o, l, n, !1);
|
|
3912
|
+
a && (a === a.next && (a.steiner = !0), i.push(bn(a)));
|
|
3749
3913
|
}
|
|
3750
|
-
i.sort((r,
|
|
3914
|
+
i.sort((r, o) => r.x - o.x);
|
|
3751
3915
|
for (const r of i)
|
|
3752
3916
|
e = gn(r, e);
|
|
3753
3917
|
return e;
|
|
3754
3918
|
}
|
|
3755
|
-
function gn(
|
|
3756
|
-
const e = vn(
|
|
3919
|
+
function gn(s, t) {
|
|
3920
|
+
const e = vn(s, t);
|
|
3757
3921
|
if (!e) return t;
|
|
3758
|
-
const n =
|
|
3759
|
-
return
|
|
3922
|
+
const n = $t(e, s);
|
|
3923
|
+
return Y(n, n.next), Y(e, e.next);
|
|
3760
3924
|
}
|
|
3761
|
-
function vn(
|
|
3925
|
+
function vn(s, t) {
|
|
3762
3926
|
let e = t;
|
|
3763
|
-
const n =
|
|
3764
|
-
let r = -1 / 0,
|
|
3927
|
+
const n = s.x, i = s.y;
|
|
3928
|
+
let r = -1 / 0, o = null;
|
|
3765
3929
|
do {
|
|
3766
3930
|
if (i <= e.y && i >= e.next.y && e.next.y !== e.y) {
|
|
3767
3931
|
const f = e.x + (i - e.y) / (e.next.y - e.y) * (e.next.x - e.x);
|
|
3768
|
-
if (f <= n && f > r && (r = f,
|
|
3769
|
-
return
|
|
3932
|
+
if (f <= n && f > r && (r = f, o = e.x < e.next.x ? e : e.next, f === n))
|
|
3933
|
+
return o;
|
|
3770
3934
|
}
|
|
3771
3935
|
e = e.next;
|
|
3772
3936
|
} while (e !== t);
|
|
3773
|
-
if (!
|
|
3774
|
-
const
|
|
3775
|
-
let
|
|
3776
|
-
e =
|
|
3937
|
+
if (!o) return null;
|
|
3938
|
+
const l = o, a = o.x, h = o.y;
|
|
3939
|
+
let c = 1 / 0;
|
|
3940
|
+
e = o;
|
|
3777
3941
|
do {
|
|
3778
|
-
if (n >= e.x && e.x >=
|
|
3942
|
+
if (n >= e.x && e.x >= a && n !== e.x && tt(i < h ? n : r, i, a, h, i < h ? r : n, i, e.x, e.y)) {
|
|
3779
3943
|
const f = Math.abs(i - e.y) / (n - e.x);
|
|
3780
|
-
|
|
3944
|
+
st(e, s) && (f < c || f === c && (e.x > o.x || xn(o, e))) && (o = e, c = f);
|
|
3781
3945
|
}
|
|
3782
3946
|
e = e.next;
|
|
3783
|
-
} while (e !==
|
|
3784
|
-
return
|
|
3947
|
+
} while (e !== l);
|
|
3948
|
+
return o;
|
|
3785
3949
|
}
|
|
3786
|
-
function xn(
|
|
3787
|
-
return L(
|
|
3950
|
+
function xn(s, t) {
|
|
3951
|
+
return L(s.prev, s, t.prev) < 0 && L(t.next, s, s.next) < 0;
|
|
3788
3952
|
}
|
|
3789
|
-
function Tn(
|
|
3790
|
-
let i =
|
|
3953
|
+
function Tn(s, t, e, n) {
|
|
3954
|
+
let i = s;
|
|
3791
3955
|
do
|
|
3792
3956
|
i.z === 0 && (i.z = yt(i.x, i.y, t, e, n)), i.prevZ = i.prev, i.nextZ = i.next, i = i.next;
|
|
3793
|
-
while (i !==
|
|
3957
|
+
while (i !== s);
|
|
3794
3958
|
i.prevZ.nextZ = null, i.prevZ = null, En(i);
|
|
3795
3959
|
}
|
|
3796
|
-
function En(
|
|
3960
|
+
function En(s) {
|
|
3797
3961
|
let t = 1, e;
|
|
3798
3962
|
do {
|
|
3799
|
-
let n =
|
|
3800
|
-
|
|
3963
|
+
let n = s;
|
|
3964
|
+
s = null;
|
|
3801
3965
|
let i = null;
|
|
3802
3966
|
for (e = 0; n; ) {
|
|
3803
3967
|
e++;
|
|
3804
|
-
let r = n,
|
|
3805
|
-
for (let
|
|
3968
|
+
let r = n, o = 0;
|
|
3969
|
+
for (let a = 0; a < t && (o++, r = r.nextZ, !!r); a++)
|
|
3806
3970
|
;
|
|
3807
|
-
let
|
|
3808
|
-
for (;
|
|
3809
|
-
let
|
|
3810
|
-
|
|
3971
|
+
let l = t;
|
|
3972
|
+
for (; o > 0 || l > 0 && r; ) {
|
|
3973
|
+
let a;
|
|
3974
|
+
o !== 0 && (l === 0 || !r || n.z <= r.z) ? (a = n, n = n.nextZ, o--) : (a = r, r = r.nextZ, l--), i ? i.nextZ = a : s = a, a.prevZ = i, i = a;
|
|
3811
3975
|
}
|
|
3812
3976
|
n = r;
|
|
3813
3977
|
}
|
|
3814
3978
|
i.nextZ = null, t *= 2;
|
|
3815
3979
|
} while (e > 1);
|
|
3816
|
-
return
|
|
3980
|
+
return s;
|
|
3817
3981
|
}
|
|
3818
|
-
function yt(
|
|
3819
|
-
let r = (
|
|
3820
|
-
return r = (r | r << 8) & 16711935, r = (r | r << 4) & 252645135, r = (r | r << 2) & 858993459, r = (r | r << 1) & 1431655765,
|
|
3982
|
+
function yt(s, t, e, n, i) {
|
|
3983
|
+
let r = (s - e) * i | 0, o = (t - n) * i | 0;
|
|
3984
|
+
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;
|
|
3821
3985
|
}
|
|
3822
|
-
function bn(
|
|
3823
|
-
let t =
|
|
3986
|
+
function bn(s) {
|
|
3987
|
+
let t = s, e = s;
|
|
3824
3988
|
do
|
|
3825
3989
|
(t.x < e.x || t.x === e.x && t.y < e.y) && (e = t), t = t.next;
|
|
3826
|
-
while (t !==
|
|
3990
|
+
while (t !== s);
|
|
3827
3991
|
return e;
|
|
3828
3992
|
}
|
|
3829
|
-
function
|
|
3830
|
-
return (i -
|
|
3993
|
+
function tt(s, t, e, n, i, r, o, l) {
|
|
3994
|
+
return (i - o) * (t - l) - (s - o) * (r - l) >= 0 && (s - o) * (n - l) - (e - o) * (t - l) >= 0 && (e - o) * (r - l) - (i - o) * (n - l) >= 0;
|
|
3831
3995
|
}
|
|
3832
|
-
function
|
|
3833
|
-
return
|
|
3996
|
+
function Sn(s, t) {
|
|
3997
|
+
return s.next.i !== t.i && s.prev.i !== t.i && !yn(s, t) && (st(s, t) && st(t, s) && wn(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);
|
|
3834
3998
|
}
|
|
3835
|
-
function L(
|
|
3836
|
-
return (t.y -
|
|
3999
|
+
function L(s, t, e) {
|
|
4000
|
+
return (t.y - s.y) * (e.x - t.x) - (t.x - s.x) * (e.y - t.y);
|
|
3837
4001
|
}
|
|
3838
|
-
function
|
|
3839
|
-
return
|
|
4002
|
+
function vt(s, t) {
|
|
4003
|
+
return s.x === t.x && s.y === t.y;
|
|
3840
4004
|
}
|
|
3841
|
-
function
|
|
3842
|
-
const i =
|
|
3843
|
-
return !!(i !== r &&
|
|
4005
|
+
function Zt(s, t, e, n) {
|
|
4006
|
+
const i = ct(L(s, t, e)), r = ct(L(s, t, n)), o = ct(L(e, n, s)), l = ct(L(e, n, t));
|
|
4007
|
+
return !!(i !== r && o !== l || i === 0 && ut(s, e, t) || r === 0 && ut(s, n, t) || o === 0 && ut(e, s, n) || l === 0 && ut(e, t, n));
|
|
3844
4008
|
}
|
|
3845
|
-
function
|
|
3846
|
-
return t.x <= Math.max(
|
|
4009
|
+
function ut(s, t, e) {
|
|
4010
|
+
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);
|
|
3847
4011
|
}
|
|
3848
|
-
function
|
|
3849
|
-
return
|
|
4012
|
+
function ct(s) {
|
|
4013
|
+
return s > 0 ? 1 : s < 0 ? -1 : 0;
|
|
3850
4014
|
}
|
|
3851
|
-
function
|
|
3852
|
-
let e =
|
|
4015
|
+
function yn(s, t) {
|
|
4016
|
+
let e = s;
|
|
3853
4017
|
do {
|
|
3854
|
-
if (e.i !==
|
|
4018
|
+
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;
|
|
3855
4019
|
e = e.next;
|
|
3856
|
-
} while (e !==
|
|
4020
|
+
} while (e !== s);
|
|
3857
4021
|
return !1;
|
|
3858
4022
|
}
|
|
3859
|
-
function
|
|
3860
|
-
return L(
|
|
4023
|
+
function st(s, t) {
|
|
4024
|
+
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;
|
|
3861
4025
|
}
|
|
3862
|
-
function wn(
|
|
3863
|
-
let e =
|
|
3864
|
-
const i = (
|
|
4026
|
+
function wn(s, t) {
|
|
4027
|
+
let e = s, n = !1;
|
|
4028
|
+
const i = (s.x + t.x) / 2, r = (s.y + t.y) / 2;
|
|
3865
4029
|
do
|
|
3866
4030
|
e.y > r != e.next.y > r && e.next.y !== e.y && i < (e.next.x - e.x) * (r - e.y) / (e.next.y - e.y) + e.x && (n = !n), e = e.next;
|
|
3867
|
-
while (e !==
|
|
4031
|
+
while (e !== s);
|
|
3868
4032
|
return n;
|
|
3869
4033
|
}
|
|
3870
|
-
function
|
|
3871
|
-
const e =
|
|
3872
|
-
return
|
|
4034
|
+
function $t(s, t) {
|
|
4035
|
+
const e = wt(s.i, s.x, s.y), n = wt(t.i, t.x, t.y), i = s.next, r = t.prev;
|
|
4036
|
+
return s.next = t, t.prev = s, e.next = i, i.prev = e, n.next = e, e.prev = n, r.next = n, n.prev = r, n;
|
|
3873
4037
|
}
|
|
3874
|
-
function
|
|
3875
|
-
const i =
|
|
4038
|
+
function Bt(s, t, e, n) {
|
|
4039
|
+
const i = wt(s, t, e);
|
|
3876
4040
|
return n ? (i.next = n.next, i.prev = n, n.next.prev = i, n.next = i) : (i.prev = i, i.next = i), i;
|
|
3877
4041
|
}
|
|
3878
|
-
function ot(
|
|
3879
|
-
|
|
4042
|
+
function ot(s) {
|
|
4043
|
+
s.next.prev = s.prev, s.prev.next = s.next, s.prevZ && (s.prevZ.nextZ = s.nextZ), s.nextZ && (s.nextZ.prevZ = s.prevZ);
|
|
3880
4044
|
}
|
|
3881
|
-
function
|
|
4045
|
+
function wt(s, t, e) {
|
|
3882
4046
|
return {
|
|
3883
|
-
i:
|
|
4047
|
+
i: s,
|
|
3884
4048
|
x: t,
|
|
3885
4049
|
y: e,
|
|
3886
4050
|
prev: null,
|
|
@@ -3891,10 +4055,10 @@ function St(o, t, e) {
|
|
|
3891
4055
|
steiner: !1
|
|
3892
4056
|
};
|
|
3893
4057
|
}
|
|
3894
|
-
function
|
|
4058
|
+
function Rn(s, t, e, n) {
|
|
3895
4059
|
let i = 0;
|
|
3896
|
-
for (let r = t,
|
|
3897
|
-
i += (o
|
|
4060
|
+
for (let r = t, o = e - n; r < e; r += n)
|
|
4061
|
+
i += (s[o] - s[r]) * (s[r + 1] + s[o + 1]), o = r;
|
|
3898
4062
|
return i;
|
|
3899
4063
|
}
|
|
3900
4064
|
const R = {
|
|
@@ -3952,7 +4116,7 @@ const R = {
|
|
|
3952
4116
|
autoplay: !0,
|
|
3953
4117
|
loop: !0,
|
|
3954
4118
|
muted: !0
|
|
3955
|
-
},
|
|
4119
|
+
}, J = 512, Q = 512;
|
|
3956
4120
|
class Et extends HTMLElement {
|
|
3957
4121
|
static TAG_NAME = "layershift-portal";
|
|
3958
4122
|
static get observedAttributes() {
|
|
@@ -4034,7 +4198,7 @@ class Et extends HTMLElement {
|
|
|
4034
4198
|
loopCount = 0;
|
|
4035
4199
|
lifecycle;
|
|
4036
4200
|
constructor() {
|
|
4037
|
-
super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new
|
|
4201
|
+
super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new Wt(this);
|
|
4038
4202
|
}
|
|
4039
4203
|
// --- Attribute helpers ---
|
|
4040
4204
|
getAttrFloat(t, e) {
|
|
@@ -4050,13 +4214,13 @@ class Et extends HTMLElement {
|
|
|
4050
4214
|
}
|
|
4051
4215
|
getAttrColor(t, e) {
|
|
4052
4216
|
const n = this.getAttribute(t) ?? e;
|
|
4053
|
-
return
|
|
4217
|
+
return An(n);
|
|
4054
4218
|
}
|
|
4055
4219
|
getAttrVec3(t, e) {
|
|
4056
|
-
const i = (this.getAttribute(t) ?? e).split(",").map((
|
|
4220
|
+
const i = (this.getAttribute(t) ?? e).split(",").map((o) => parseFloat(o.trim()));
|
|
4057
4221
|
if (i.length >= 3 && i.every(Number.isFinite))
|
|
4058
4222
|
return [i[0], i[1], i[2]];
|
|
4059
|
-
const r = e.split(",").map((
|
|
4223
|
+
const r = e.split(",").map((o) => parseFloat(o.trim()));
|
|
4060
4224
|
return [r[0], r[1], r[2]];
|
|
4061
4225
|
}
|
|
4062
4226
|
get sourceType() {
|
|
@@ -4280,13 +4444,13 @@ class Et extends HTMLElement {
|
|
|
4280
4444
|
if (!this.container) return;
|
|
4281
4445
|
const n = this.sourceType === "camera", i = this.depthModel;
|
|
4282
4446
|
try {
|
|
4283
|
-
let r,
|
|
4284
|
-
const
|
|
4447
|
+
let r, o, l, a = null;
|
|
4448
|
+
const h = (d) => {
|
|
4285
4449
|
this.emit("layershift-portal:model-progress", d);
|
|
4286
4450
|
};
|
|
4287
4451
|
if (n) {
|
|
4288
4452
|
const [d, y] = await Promise.all([
|
|
4289
|
-
|
|
4453
|
+
Xt(
|
|
4290
4454
|
{ video: { facingMode: "user" } },
|
|
4291
4455
|
{ parent: this.shadow }
|
|
4292
4456
|
),
|
|
@@ -4296,68 +4460,68 @@ class Et extends HTMLElement {
|
|
|
4296
4460
|
d.dispose();
|
|
4297
4461
|
return;
|
|
4298
4462
|
}
|
|
4299
|
-
if (r = d,
|
|
4300
|
-
if (
|
|
4301
|
-
|
|
4463
|
+
if (r = d, l = y, i) {
|
|
4464
|
+
if (a = await dt(i, J, Q, h), t.aborted) {
|
|
4465
|
+
a.dispose(), r.dispose();
|
|
4302
4466
|
return;
|
|
4303
4467
|
}
|
|
4304
|
-
|
|
4468
|
+
o = N(J, Q);
|
|
4305
4469
|
} else
|
|
4306
|
-
|
|
4470
|
+
o = N(r.width, r.height);
|
|
4307
4471
|
} else {
|
|
4308
|
-
const d = this.getAttribute("src"), y = this.getAttribute("depth-src"), E = this.getAttribute("depth-meta"), b = !!y && !!E,
|
|
4472
|
+
const d = this.getAttribute("src"), y = this.getAttribute("depth-src"), E = this.getAttribute("depth-meta"), b = !!y && !!E, g = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(d);
|
|
4309
4473
|
if (b) {
|
|
4310
4474
|
const [v, m, T] = await Promise.all([
|
|
4311
|
-
|
|
4475
|
+
g ? ft(d) : ht(d, {
|
|
4312
4476
|
parent: this.shadow,
|
|
4313
4477
|
loop: this.shouldLoop,
|
|
4314
4478
|
muted: this.shouldMute
|
|
4315
4479
|
}),
|
|
4316
|
-
|
|
4480
|
+
kt(y, E),
|
|
4317
4481
|
Tt(e)
|
|
4318
4482
|
]);
|
|
4319
4483
|
if (t.aborted) {
|
|
4320
4484
|
v.dispose();
|
|
4321
4485
|
return;
|
|
4322
4486
|
}
|
|
4323
|
-
r = v,
|
|
4487
|
+
r = v, o = m, l = T;
|
|
4324
4488
|
} else if (i) {
|
|
4325
4489
|
const [v, m, T] = await Promise.all([
|
|
4326
|
-
|
|
4490
|
+
g ? ft(d) : ht(d, {
|
|
4327
4491
|
parent: this.shadow,
|
|
4328
4492
|
loop: this.shouldLoop,
|
|
4329
4493
|
muted: this.shouldMute
|
|
4330
4494
|
}),
|
|
4331
|
-
|
|
4495
|
+
dt(i, J, Q, h),
|
|
4332
4496
|
Tt(e)
|
|
4333
4497
|
]);
|
|
4334
4498
|
if (t.aborted) {
|
|
4335
4499
|
v.dispose(), m.dispose();
|
|
4336
4500
|
return;
|
|
4337
4501
|
}
|
|
4338
|
-
if (r = v,
|
|
4502
|
+
if (r = v, a = m, l = T, g || !r.isLive) {
|
|
4339
4503
|
const w = r.getImageSource();
|
|
4340
4504
|
if (w) {
|
|
4341
|
-
const A = await
|
|
4342
|
-
|
|
4343
|
-
meta: { frameCount: 1, fps: 1, width:
|
|
4505
|
+
const A = await a.submitFrameAndWait(w);
|
|
4506
|
+
o = {
|
|
4507
|
+
meta: { frameCount: 1, fps: 1, width: J, height: Q, sourceFps: 1 },
|
|
4344
4508
|
frames: [A]
|
|
4345
4509
|
};
|
|
4346
4510
|
} else
|
|
4347
|
-
|
|
4511
|
+
o = N(J, Q);
|
|
4348
4512
|
} else
|
|
4349
|
-
|
|
4513
|
+
o = N(J, Q);
|
|
4350
4514
|
} else
|
|
4351
4515
|
throw new Error("Either depth-src/depth-meta or depth-model must be provided.");
|
|
4352
4516
|
}
|
|
4353
|
-
this.source = r, this.depthEstimator =
|
|
4354
|
-
const
|
|
4355
|
-
let
|
|
4356
|
-
if (
|
|
4357
|
-
|
|
4517
|
+
this.source = r, this.depthEstimator = a, this.mesh = l, this.loopCount = 0, this.attachSourceEventListeners(r);
|
|
4518
|
+
const c = this.container?.clientWidth || r.width, f = this.parallaxMax / Math.max(c, 1);
|
|
4519
|
+
let u;
|
|
4520
|
+
if (a)
|
|
4521
|
+
u = () => a.getLatestDepth();
|
|
4358
4522
|
else {
|
|
4359
|
-
const d = new
|
|
4360
|
-
|
|
4523
|
+
const d = new Vt(o);
|
|
4524
|
+
u = (y) => d.sample(y);
|
|
4361
4525
|
}
|
|
4362
4526
|
const x = {
|
|
4363
4527
|
parallaxStrength: f,
|
|
@@ -4401,16 +4565,16 @@ class Et extends HTMLElement {
|
|
|
4401
4565
|
lightDirection: this.lightDirection3
|
|
4402
4566
|
};
|
|
4403
4567
|
if (t.aborted) return;
|
|
4404
|
-
this.renderer = new Je(this.container, x), this.renderer.initialize(r,
|
|
4405
|
-
const
|
|
4568
|
+
this.renderer = new Je(this.container, x), this.renderer.initialize(r, o.meta.width, o.meta.height, l);
|
|
4569
|
+
const p = a;
|
|
4406
4570
|
if (this.renderer.start(
|
|
4407
4571
|
r,
|
|
4408
|
-
|
|
4572
|
+
u,
|
|
4409
4573
|
() => ({ x: this._input.x, y: this._input.y }),
|
|
4410
4574
|
(d, y) => {
|
|
4411
|
-
if (
|
|
4575
|
+
if (p) {
|
|
4412
4576
|
const E = r.getImageSource();
|
|
4413
|
-
E &&
|
|
4577
|
+
E && p.submitFrame(E);
|
|
4414
4578
|
}
|
|
4415
4579
|
this.emit("layershift-portal:frame", {
|
|
4416
4580
|
currentTime: d,
|
|
@@ -4429,8 +4593,8 @@ class Et extends HTMLElement {
|
|
|
4429
4593
|
duration: r.duration
|
|
4430
4594
|
});
|
|
4431
4595
|
} catch (r) {
|
|
4432
|
-
const
|
|
4433
|
-
console.error("<layershift-portal>: Failed to initialize.", r), this.emit("layershift-portal:error", { message:
|
|
4596
|
+
const o = r instanceof Error ? r.message : "Failed to initialize.";
|
|
4597
|
+
console.error("<layershift-portal>: Failed to initialize.", r), this.emit("layershift-portal:error", { message: o });
|
|
4434
4598
|
}
|
|
4435
4599
|
}
|
|
4436
4600
|
// --- Cleanup ---
|
|
@@ -4438,8 +4602,8 @@ class Et extends HTMLElement {
|
|
|
4438
4602
|
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;
|
|
4439
4603
|
}
|
|
4440
4604
|
}
|
|
4441
|
-
function
|
|
4442
|
-
const t =
|
|
4605
|
+
function An(s) {
|
|
4606
|
+
const t = s.replace("#", "");
|
|
4443
4607
|
if (t.length === 3) {
|
|
4444
4608
|
const e = parseInt(t[0] + t[0], 16) / 255, n = parseInt(t[1] + t[1], 16) / 255, i = parseInt(t[2] + t[2], 16) / 255;
|
|
4445
4609
|
return [e, n, i];
|
|
@@ -4450,101 +4614,101 @@ function Rn(o) {
|
|
|
4450
4614
|
}
|
|
4451
4615
|
return [0, 0, 0];
|
|
4452
4616
|
}
|
|
4453
|
-
function V(
|
|
4454
|
-
return Math.min(e, Math.max(t,
|
|
4617
|
+
function V(s, t, e) {
|
|
4618
|
+
return Math.min(e, Math.max(t, s));
|
|
4455
4619
|
}
|
|
4456
|
-
function
|
|
4457
|
-
return
|
|
4620
|
+
function W(s, t, e) {
|
|
4621
|
+
return s + (t - s) * e;
|
|
4458
4622
|
}
|
|
4459
|
-
const
|
|
4460
|
-
function
|
|
4623
|
+
const X = 100, Kt = 0.06;
|
|
4624
|
+
function Pn(s, t) {
|
|
4461
4625
|
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08;
|
|
4462
|
-
let r = 0,
|
|
4463
|
-
const f = (
|
|
4464
|
-
const d =
|
|
4465
|
-
r = V(y, -1, 1),
|
|
4466
|
-
},
|
|
4467
|
-
r = 0,
|
|
4626
|
+
let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0;
|
|
4627
|
+
const f = (p) => {
|
|
4628
|
+
const d = s.getBoundingClientRect(), y = (p.clientX - d.left) / d.width * 2 - 1, E = (p.clientY - d.top) / d.height * 2 - 1;
|
|
4629
|
+
r = V(y, -1, 1), o = V(E, -1, 1);
|
|
4630
|
+
}, u = () => {
|
|
4631
|
+
r = 0, o = 0;
|
|
4468
4632
|
}, x = () => {
|
|
4469
|
-
|
|
4633
|
+
c && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, h = requestAnimationFrame(x));
|
|
4470
4634
|
};
|
|
4471
|
-
return
|
|
4472
|
-
|
|
4635
|
+
return s.addEventListener("mousemove", f), s.addEventListener("mouseleave", u), h = requestAnimationFrame(x), () => {
|
|
4636
|
+
c = !1, cancelAnimationFrame(h), s.removeEventListener("mousemove", f), s.removeEventListener("mouseleave", u);
|
|
4473
4637
|
};
|
|
4474
4638
|
}
|
|
4475
|
-
function
|
|
4639
|
+
function Dn(s, t) {
|
|
4476
4640
|
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08;
|
|
4477
|
-
let r = 0,
|
|
4641
|
+
let r = 0, o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = !0;
|
|
4478
4642
|
const x = (E) => {
|
|
4479
4643
|
const b = E.touches[0];
|
|
4480
|
-
b && (
|
|
4481
|
-
},
|
|
4644
|
+
b && (h = b.clientX - l * X, c = b.clientY - a * X, r = l, o = a);
|
|
4645
|
+
}, p = (E) => {
|
|
4482
4646
|
const b = E.touches[0];
|
|
4483
4647
|
if (!b) return;
|
|
4484
|
-
const
|
|
4485
|
-
r = V(
|
|
4648
|
+
const g = b.clientX - h, v = b.clientY - c;
|
|
4649
|
+
r = V(g / X, -1, 1), o = V(v / X, -1, 1);
|
|
4486
4650
|
}, d = () => {
|
|
4487
|
-
r = 0,
|
|
4651
|
+
r = 0, o = 0;
|
|
4488
4652
|
}, y = () => {
|
|
4489
|
-
|
|
4653
|
+
u && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, f = requestAnimationFrame(y));
|
|
4490
4654
|
};
|
|
4491
|
-
return
|
|
4492
|
-
|
|
4655
|
+
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), () => {
|
|
4656
|
+
u = !1, cancelAnimationFrame(f), s.removeEventListener("touchstart", x), s.removeEventListener("touchmove", p), s.removeEventListener("touchend", d), s.removeEventListener("touchcancel", d);
|
|
4493
4657
|
};
|
|
4494
4658
|
}
|
|
4495
|
-
function Fn(
|
|
4496
|
-
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ??
|
|
4497
|
-
let r = 0,
|
|
4498
|
-
const
|
|
4499
|
-
r = V((y.gamma ?? 0) / 45, -1, 1),
|
|
4659
|
+
function Fn(s, t) {
|
|
4660
|
+
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? Kt;
|
|
4661
|
+
let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0, f = !1;
|
|
4662
|
+
const u = (y) => {
|
|
4663
|
+
r = V((y.gamma ?? 0) / 45, -1, 1), o = V((y.beta ?? 0) / 45, -1, 1);
|
|
4500
4664
|
}, x = () => {
|
|
4501
|
-
|
|
4502
|
-
},
|
|
4503
|
-
|
|
4665
|
+
c && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, h = requestAnimationFrame(x));
|
|
4666
|
+
}, p = () => {
|
|
4667
|
+
c && !f && (window.addEventListener("deviceorientation", u), f = !0);
|
|
4504
4668
|
}, d = DeviceOrientationEvent;
|
|
4505
4669
|
return typeof d.requestPermission == "function" ? d.requestPermission().then((y) => {
|
|
4506
|
-
y === "granted" &&
|
|
4670
|
+
y === "granted" && p();
|
|
4507
4671
|
}).catch(() => {
|
|
4508
|
-
}) :
|
|
4509
|
-
|
|
4672
|
+
}) : p(), h = requestAnimationFrame(x), () => {
|
|
4673
|
+
c = !1, cancelAnimationFrame(h), f && (window.removeEventListener("deviceorientation", u), f = !1);
|
|
4510
4674
|
};
|
|
4511
4675
|
}
|
|
4512
|
-
function Cn(
|
|
4513
|
-
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08, r = t?.lerpFactor ??
|
|
4514
|
-
let
|
|
4676
|
+
function Cn(s, t) {
|
|
4677
|
+
const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08, r = t?.lerpFactor ?? Kt;
|
|
4678
|
+
let o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = 0, x = 0, p = !1, d = !1, y = !1, E = 0, b = 0, g = 0, v = !0;
|
|
4515
4679
|
const m = (S) => {
|
|
4516
|
-
const
|
|
4517
|
-
|
|
4680
|
+
const D = s.getBoundingClientRect(), U = (S.clientX - D.left) / D.width * 2 - 1, M = (S.clientY - D.top) / D.height * 2 - 1;
|
|
4681
|
+
o = V(U, -1, 1), l = V(M, -1, 1);
|
|
4518
4682
|
}, T = () => {
|
|
4519
|
-
|
|
4683
|
+
o = 0, l = 0;
|
|
4520
4684
|
}, w = (S) => {
|
|
4521
|
-
const
|
|
4522
|
-
|
|
4685
|
+
const D = S.touches[0];
|
|
4686
|
+
D && (p = !0, E = D.clientX - u * X, b = D.clientY - x * X, a = u, h = x, !d && !y && I());
|
|
4523
4687
|
}, A = (S) => {
|
|
4524
|
-
const
|
|
4525
|
-
if (!
|
|
4526
|
-
const U =
|
|
4527
|
-
|
|
4528
|
-
},
|
|
4529
|
-
|
|
4530
|
-
},
|
|
4531
|
-
|
|
4688
|
+
const D = S.touches[0];
|
|
4689
|
+
if (!D) return;
|
|
4690
|
+
const U = D.clientX - E, M = D.clientY - b;
|
|
4691
|
+
a = V(U / X, -1, 1), h = V(M / X, -1, 1);
|
|
4692
|
+
}, P = () => {
|
|
4693
|
+
p = !1, a = 0, h = 0;
|
|
4694
|
+
}, F = (S) => {
|
|
4695
|
+
c = V((S.gamma ?? 0) / 45, -1, 1), f = V((S.beta ?? 0) / 45, -1, 1);
|
|
4532
4696
|
}, _ = () => {
|
|
4533
|
-
v && !y && (window.addEventListener("deviceorientation",
|
|
4697
|
+
v && !y && (window.addEventListener("deviceorientation", F), y = !0, d = !0);
|
|
4534
4698
|
}, I = () => {
|
|
4535
4699
|
if (typeof DeviceOrientationEvent > "u") return;
|
|
4536
4700
|
const S = DeviceOrientationEvent;
|
|
4537
|
-
typeof S.requestPermission == "function" ? S.requestPermission().then((
|
|
4538
|
-
|
|
4701
|
+
typeof S.requestPermission == "function" ? S.requestPermission().then((D) => {
|
|
4702
|
+
D === "granted" && _();
|
|
4539
4703
|
}).catch(() => {
|
|
4540
4704
|
}) : _();
|
|
4541
4705
|
}, C = () => {
|
|
4542
4706
|
if (!v) return;
|
|
4543
|
-
let S,
|
|
4544
|
-
|
|
4707
|
+
let S, D, U;
|
|
4708
|
+
p ? (S = a, D = h, U = i) : d ? (S = c, D = f, U = r) : (S = o, D = l, U = i), u = W(u, S, U), x = W(x, D, U), s.input = { x: u * e, y: x * n }, g = requestAnimationFrame(C);
|
|
4545
4709
|
};
|
|
4546
|
-
return
|
|
4547
|
-
v = !1, cancelAnimationFrame(
|
|
4710
|
+
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), () => {
|
|
4711
|
+
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);
|
|
4548
4712
|
};
|
|
4549
4713
|
}
|
|
4550
4714
|
customElements.get(xt.TAG_NAME) || customElements.define(xt.TAG_NAME, xt);
|
|
@@ -4553,7 +4717,7 @@ export {
|
|
|
4553
4717
|
xt as LayershiftElement,
|
|
4554
4718
|
Et as LayershiftPortalElement,
|
|
4555
4719
|
Fn as connectGyro,
|
|
4556
|
-
|
|
4720
|
+
Pn as connectMouse,
|
|
4557
4721
|
Cn as connectPointer,
|
|
4558
|
-
|
|
4722
|
+
Dn as connectTouch
|
|
4559
4723
|
};
|