@vib3code/sdk 2.0.3-canary.45332e3 → 2.0.3-canary.4874bcf
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/DOCS/AGENT_HARNESS_ARCHITECTURE.md +2 -0
- package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
- package/DOCS/ARCHITECTURE.md +1 -0
- package/DOCS/CI_TESTING.md +2 -0
- package/DOCS/CLI_ONBOARDING.md +2 -0
- package/DOCS/CONTROL_REFERENCE.md +2 -0
- package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +2 -0
- package/DOCS/ENV_SETUP.md +2 -0
- package/DOCS/EPIC_SCROLL_EVENTS.md +2 -0
- package/DOCS/EXPANSION_DESIGN.md +979 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
- package/DOCS/EXPORT_FORMATS.md +2 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
- package/DOCS/HANDOFF_LANDING_PAGE.md +2 -0
- package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +2 -0
- package/DOCS/LICENSING_TIERS.md +2 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +2 -0
- package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +3 -1
- package/DOCS/OBS_SETUP_GUIDE.md +2 -0
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
- package/DOCS/PRODUCT_STRATEGY.md +2 -0
- package/DOCS/PROJECT_SETUP.md +2 -0
- package/DOCS/README.md +5 -3
- package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +2 -0
- package/DOCS/RENDERER_LIFECYCLE.md +2 -0
- package/DOCS/REPO_MANIFEST.md +2 -0
- package/DOCS/ROADMAP.md +2 -0
- package/DOCS/SCROLL_TIMELINE_v3.md +2 -0
- package/DOCS/SITE_REFACTOR_PLAN.md +2 -0
- package/DOCS/STATUS.md +2 -0
- package/DOCS/SYSTEM_INVENTORY.md +2 -0
- package/DOCS/TELEMETRY_EXPORTS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_FACETAD.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_SIMONE.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +2 -0
- package/DOCS/WEBGPU_STATUS.md +2 -0
- package/DOCS/XR_BENCHMARKS.md +2 -0
- package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -34
- package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -80
- package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -42
- package/DOCS/archive/SESSION_014_PLAN.md +1 -195
- package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -56
- package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -72
- package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -741
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -38
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-01-31.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +2 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
- package/DOCS/dev-tracks/README.md +2 -0
- package/package.json +2 -4
- package/src/cli/index.js +59 -5
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/export/SVGExporter.js +9 -5
- package/src/features/CollectionManager.js +27 -9
- package/src/gallery/CollectionManager.js +27 -9
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/geometry/warp/HypersphereCore.js +53 -24
- package/src/math/Mat4x4.js +418 -142
- package/src/math/Projection.js +57 -7
- package/src/math/Rotor4D.js +102 -73
- package/src/math/Vec4.js +265 -111
- package/src/quantum/QuantumVisualizer.js +28 -0
- package/src/scene/Node4D.js +74 -24
- package/src/testing/ProjectionClass.test.js +38 -0
- package/src/variations/VariationManager.js +6 -1
- package/src/wasm/WasmLoader.js +11 -6
- package/tools/update_projection.py +109 -0
package/src/math/Vec4.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Vec4 - 4D Vector Class
|
|
3
3
|
*
|
|
4
4
|
* Represents a point or direction in 4-dimensional space.
|
|
5
|
-
* Uses
|
|
5
|
+
* Uses plain numeric properties internally for minimal allocation overhead.
|
|
6
|
+
* GPU-compatible Float32Array created on demand via toFloat32Array().
|
|
6
7
|
*
|
|
7
8
|
* @example
|
|
8
9
|
* const v = new Vec4(1, 2, 3, 0.5);
|
|
@@ -19,26 +20,66 @@ export class Vec4 {
|
|
|
19
20
|
* @param {number} w - W component (4th dimension)
|
|
20
21
|
*/
|
|
21
22
|
constructor(x = 0, y = 0, z = 0, w = 0) {
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.data[2] = z;
|
|
27
|
-
this.data[3] = w;
|
|
23
|
+
this._x = x;
|
|
24
|
+
this._y = y;
|
|
25
|
+
this._z = z;
|
|
26
|
+
this._w = w;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
// Property accessors
|
|
31
|
-
get x() { return this.
|
|
32
|
-
set x(v) { this.
|
|
29
|
+
// Property accessors
|
|
30
|
+
get x() { return this._x; }
|
|
31
|
+
set x(v) { this._x = v; }
|
|
33
32
|
|
|
34
|
-
get y() { return this.
|
|
35
|
-
set y(v) { this.
|
|
33
|
+
get y() { return this._y; }
|
|
34
|
+
set y(v) { this._y = v; }
|
|
36
35
|
|
|
37
|
-
get z() { return this.
|
|
38
|
-
set z(v) { this.
|
|
36
|
+
get z() { return this._z; }
|
|
37
|
+
set z(v) { this._z = v; }
|
|
39
38
|
|
|
40
|
-
get w() { return this.
|
|
41
|
-
set w(v) { this.
|
|
39
|
+
get w() { return this._w; }
|
|
40
|
+
set w(v) { this._w = v; }
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Backward-compatible .data getter.
|
|
44
|
+
* Returns a Float32Array snapshot of current values.
|
|
45
|
+
* Note: writes to the returned array do NOT propagate back.
|
|
46
|
+
* Use setComponent(index, value) for index-based mutation.
|
|
47
|
+
* @returns {Float32Array}
|
|
48
|
+
*/
|
|
49
|
+
get data() {
|
|
50
|
+
return new Float32Array([this._x, this._y, this._z, this._w]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Set a component by index (0=x, 1=y, 2=z, 3=w)
|
|
55
|
+
* @param {number} index - Component index (0-3)
|
|
56
|
+
* @param {number} value - New value
|
|
57
|
+
* @returns {Vec4} this
|
|
58
|
+
*/
|
|
59
|
+
setComponent(index, value) {
|
|
60
|
+
switch (index) {
|
|
61
|
+
case 0: this._x = value; break;
|
|
62
|
+
case 1: this._y = value; break;
|
|
63
|
+
case 2: this._z = value; break;
|
|
64
|
+
case 3: this._w = value; break;
|
|
65
|
+
}
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get a component by index (0=x, 1=y, 2=z, 3=w)
|
|
71
|
+
* @param {number} index - Component index (0-3)
|
|
72
|
+
* @returns {number}
|
|
73
|
+
*/
|
|
74
|
+
getComponent(index) {
|
|
75
|
+
switch (index) {
|
|
76
|
+
case 0: return this._x;
|
|
77
|
+
case 1: return this._y;
|
|
78
|
+
case 2: return this._z;
|
|
79
|
+
case 3: return this._w;
|
|
80
|
+
default: return 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
42
83
|
|
|
43
84
|
/**
|
|
44
85
|
* Create a Vec4 from an array
|
|
@@ -54,7 +95,7 @@ export class Vec4 {
|
|
|
54
95
|
* @returns {Vec4}
|
|
55
96
|
*/
|
|
56
97
|
clone() {
|
|
57
|
-
return new Vec4(this.
|
|
98
|
+
return new Vec4(this._x, this._y, this._z, this._w);
|
|
58
99
|
}
|
|
59
100
|
|
|
60
101
|
/**
|
|
@@ -63,10 +104,10 @@ export class Vec4 {
|
|
|
63
104
|
* @returns {Vec4} this (for chaining)
|
|
64
105
|
*/
|
|
65
106
|
copy(v) {
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
107
|
+
this._x = v._x;
|
|
108
|
+
this._y = v._y;
|
|
109
|
+
this._z = v._z;
|
|
110
|
+
this._w = v._w;
|
|
70
111
|
return this;
|
|
71
112
|
}
|
|
72
113
|
|
|
@@ -79,24 +120,32 @@ export class Vec4 {
|
|
|
79
120
|
* @returns {Vec4} this
|
|
80
121
|
*/
|
|
81
122
|
set(x, y, z, w) {
|
|
82
|
-
this.
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
123
|
+
this._x = x;
|
|
124
|
+
this._y = y;
|
|
125
|
+
this._z = z;
|
|
126
|
+
this._w = w;
|
|
86
127
|
return this;
|
|
87
128
|
}
|
|
88
129
|
|
|
89
130
|
/**
|
|
90
|
-
* Add another vector (immutable)
|
|
131
|
+
* Add another vector (immutable unless target provided)
|
|
91
132
|
* @param {Vec4} v
|
|
92
|
-
* @
|
|
93
|
-
|
|
94
|
-
|
|
133
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
134
|
+
* @returns {Vec4} New vector or target
|
|
135
|
+
*/
|
|
136
|
+
add(v, target = null) {
|
|
137
|
+
if (target) {
|
|
138
|
+
target._x = this._x + v._x;
|
|
139
|
+
target._y = this._y + v._y;
|
|
140
|
+
target._z = this._z + v._z;
|
|
141
|
+
target._w = this._w + v._w;
|
|
142
|
+
return target;
|
|
143
|
+
}
|
|
95
144
|
return new Vec4(
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
145
|
+
this._x + v._x,
|
|
146
|
+
this._y + v._y,
|
|
147
|
+
this._z + v._z,
|
|
148
|
+
this._w + v._w
|
|
100
149
|
);
|
|
101
150
|
}
|
|
102
151
|
|
|
@@ -106,24 +155,32 @@ export class Vec4 {
|
|
|
106
155
|
* @returns {Vec4} this
|
|
107
156
|
*/
|
|
108
157
|
addInPlace(v) {
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
158
|
+
this._x += v._x;
|
|
159
|
+
this._y += v._y;
|
|
160
|
+
this._z += v._z;
|
|
161
|
+
this._w += v._w;
|
|
113
162
|
return this;
|
|
114
163
|
}
|
|
115
164
|
|
|
116
165
|
/**
|
|
117
|
-
* Subtract another vector (immutable)
|
|
166
|
+
* Subtract another vector (immutable unless target provided)
|
|
118
167
|
* @param {Vec4} v
|
|
119
|
-
* @
|
|
120
|
-
|
|
121
|
-
|
|
168
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
169
|
+
* @returns {Vec4} New vector or target
|
|
170
|
+
*/
|
|
171
|
+
sub(v, target = null) {
|
|
172
|
+
if (target) {
|
|
173
|
+
target._x = this._x - v._x;
|
|
174
|
+
target._y = this._y - v._y;
|
|
175
|
+
target._z = this._z - v._z;
|
|
176
|
+
target._w = this._w - v._w;
|
|
177
|
+
return target;
|
|
178
|
+
}
|
|
122
179
|
return new Vec4(
|
|
123
|
-
this.
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
180
|
+
this._x - v._x,
|
|
181
|
+
this._y - v._y,
|
|
182
|
+
this._z - v._z,
|
|
183
|
+
this._w - v._w
|
|
127
184
|
);
|
|
128
185
|
}
|
|
129
186
|
|
|
@@ -133,24 +190,32 @@ export class Vec4 {
|
|
|
133
190
|
* @returns {Vec4} this
|
|
134
191
|
*/
|
|
135
192
|
subInPlace(v) {
|
|
136
|
-
this.
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
139
|
-
this.
|
|
193
|
+
this._x -= v._x;
|
|
194
|
+
this._y -= v._y;
|
|
195
|
+
this._z -= v._z;
|
|
196
|
+
this._w -= v._w;
|
|
140
197
|
return this;
|
|
141
198
|
}
|
|
142
199
|
|
|
143
200
|
/**
|
|
144
|
-
* Multiply by scalar (immutable)
|
|
201
|
+
* Multiply by scalar (immutable unless target provided)
|
|
145
202
|
* @param {number} s
|
|
146
|
-
* @
|
|
147
|
-
|
|
148
|
-
|
|
203
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
204
|
+
* @returns {Vec4} New vector or target
|
|
205
|
+
*/
|
|
206
|
+
scale(s, target = null) {
|
|
207
|
+
if (target) {
|
|
208
|
+
target._x = this._x * s;
|
|
209
|
+
target._y = this._y * s;
|
|
210
|
+
target._z = this._z * s;
|
|
211
|
+
target._w = this._w * s;
|
|
212
|
+
return target;
|
|
213
|
+
}
|
|
149
214
|
return new Vec4(
|
|
150
|
-
this.
|
|
151
|
-
this.
|
|
152
|
-
this.
|
|
153
|
-
this.
|
|
215
|
+
this._x * s,
|
|
216
|
+
this._y * s,
|
|
217
|
+
this._z * s,
|
|
218
|
+
this._w * s
|
|
154
219
|
);
|
|
155
220
|
}
|
|
156
221
|
|
|
@@ -160,33 +225,49 @@ export class Vec4 {
|
|
|
160
225
|
* @returns {Vec4} this
|
|
161
226
|
*/
|
|
162
227
|
scaleInPlace(s) {
|
|
163
|
-
this.
|
|
164
|
-
this.
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
228
|
+
this._x *= s;
|
|
229
|
+
this._y *= s;
|
|
230
|
+
this._z *= s;
|
|
231
|
+
this._w *= s;
|
|
167
232
|
return this;
|
|
168
233
|
}
|
|
169
234
|
|
|
170
235
|
/**
|
|
171
236
|
* Component-wise multiply (Hadamard product)
|
|
172
237
|
* @param {Vec4} v
|
|
173
|
-
* @
|
|
174
|
-
|
|
175
|
-
|
|
238
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
239
|
+
* @returns {Vec4} New vector or target
|
|
240
|
+
*/
|
|
241
|
+
multiply(v, target = null) {
|
|
242
|
+
if (target) {
|
|
243
|
+
target._x = this._x * v._x;
|
|
244
|
+
target._y = this._y * v._y;
|
|
245
|
+
target._z = this._z * v._z;
|
|
246
|
+
target._w = this._w * v._w;
|
|
247
|
+
return target;
|
|
248
|
+
}
|
|
176
249
|
return new Vec4(
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
this.
|
|
250
|
+
this._x * v._x,
|
|
251
|
+
this._y * v._y,
|
|
252
|
+
this._z * v._z,
|
|
253
|
+
this._w * v._w
|
|
181
254
|
);
|
|
182
255
|
}
|
|
183
256
|
|
|
184
257
|
/**
|
|
185
|
-
* Negate vector (immutable)
|
|
186
|
-
* @
|
|
258
|
+
* Negate vector (immutable unless target provided)
|
|
259
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
260
|
+
* @returns {Vec4} New vector or target
|
|
187
261
|
*/
|
|
188
|
-
negate() {
|
|
189
|
-
|
|
262
|
+
negate(target = null) {
|
|
263
|
+
if (target) {
|
|
264
|
+
target._x = -this._x;
|
|
265
|
+
target._y = -this._y;
|
|
266
|
+
target._z = -this._z;
|
|
267
|
+
target._w = -this._w;
|
|
268
|
+
return target;
|
|
269
|
+
}
|
|
270
|
+
return new Vec4(-this._x, -this._y, -this._z, -this._w);
|
|
190
271
|
}
|
|
191
272
|
|
|
192
273
|
/**
|
|
@@ -194,10 +275,10 @@ export class Vec4 {
|
|
|
194
275
|
* @returns {Vec4} this
|
|
195
276
|
*/
|
|
196
277
|
negateInPlace() {
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
200
|
-
this.
|
|
278
|
+
this._x = -this._x;
|
|
279
|
+
this._y = -this._y;
|
|
280
|
+
this._z = -this._z;
|
|
281
|
+
this._w = -this._w;
|
|
201
282
|
return this;
|
|
202
283
|
}
|
|
203
284
|
|
|
@@ -207,7 +288,7 @@ export class Vec4 {
|
|
|
207
288
|
* @returns {number}
|
|
208
289
|
*/
|
|
209
290
|
dot(v) {
|
|
210
|
-
return this.
|
|
291
|
+
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
|
|
211
292
|
}
|
|
212
293
|
|
|
213
294
|
/**
|
|
@@ -215,7 +296,7 @@ export class Vec4 {
|
|
|
215
296
|
* @returns {number}
|
|
216
297
|
*/
|
|
217
298
|
lengthSquared() {
|
|
218
|
-
return this.
|
|
299
|
+
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
|
|
219
300
|
}
|
|
220
301
|
|
|
221
302
|
/**
|
|
@@ -232,7 +313,11 @@ export class Vec4 {
|
|
|
232
313
|
* @returns {number}
|
|
233
314
|
*/
|
|
234
315
|
distanceTo(v) {
|
|
235
|
-
|
|
316
|
+
const dx = this._x - v._x;
|
|
317
|
+
const dy = this._y - v._y;
|
|
318
|
+
const dz = this._z - v._z;
|
|
319
|
+
const dw = this._w - v._w;
|
|
320
|
+
return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
|
|
236
321
|
}
|
|
237
322
|
|
|
238
323
|
/**
|
|
@@ -241,19 +326,31 @@ export class Vec4 {
|
|
|
241
326
|
* @returns {number}
|
|
242
327
|
*/
|
|
243
328
|
distanceToSquared(v) {
|
|
244
|
-
|
|
329
|
+
const dx = this._x - v._x;
|
|
330
|
+
const dy = this._y - v._y;
|
|
331
|
+
const dz = this._z - v._z;
|
|
332
|
+
const dw = this._w - v._w;
|
|
333
|
+
return dx * dx + dy * dy + dz * dz + dw * dw;
|
|
245
334
|
}
|
|
246
335
|
|
|
247
336
|
/**
|
|
248
|
-
* Normalize to unit length (immutable)
|
|
249
|
-
* @
|
|
337
|
+
* Normalize to unit length (immutable unless target provided)
|
|
338
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
339
|
+
* @returns {Vec4} New normalized vector or target
|
|
250
340
|
*/
|
|
251
|
-
normalize() {
|
|
341
|
+
normalize(target = null) {
|
|
252
342
|
const len = this.length();
|
|
253
343
|
if (len < 1e-10) {
|
|
344
|
+
if (target) {
|
|
345
|
+
target._x = 0;
|
|
346
|
+
target._y = 0;
|
|
347
|
+
target._z = 0;
|
|
348
|
+
target._w = 0;
|
|
349
|
+
return target;
|
|
350
|
+
}
|
|
254
351
|
return new Vec4(0, 0, 0, 0);
|
|
255
352
|
}
|
|
256
|
-
return this.scale(1 / len);
|
|
353
|
+
return this.scale(1 / len, target);
|
|
257
354
|
}
|
|
258
355
|
|
|
259
356
|
/**
|
|
@@ -273,14 +370,22 @@ export class Vec4 {
|
|
|
273
370
|
* Linear interpolation to another vector
|
|
274
371
|
* @param {Vec4} v - Target vector
|
|
275
372
|
* @param {number} t - Interpolation factor (0-1)
|
|
276
|
-
* @
|
|
277
|
-
|
|
278
|
-
|
|
373
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
374
|
+
* @returns {Vec4} New interpolated vector or target
|
|
375
|
+
*/
|
|
376
|
+
lerp(v, t, target = null) {
|
|
377
|
+
if (target) {
|
|
378
|
+
target._x = this._x + (v._x - this._x) * t;
|
|
379
|
+
target._y = this._y + (v._y - this._y) * t;
|
|
380
|
+
target._z = this._z + (v._z - this._z) * t;
|
|
381
|
+
target._w = this._w + (v._w - this._w) * t;
|
|
382
|
+
return target;
|
|
383
|
+
}
|
|
279
384
|
return new Vec4(
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
283
|
-
this.
|
|
385
|
+
this._x + (v._x - this._x) * t,
|
|
386
|
+
this._y + (v._y - this._y) * t,
|
|
387
|
+
this._z + (v._z - this._z) * t,
|
|
388
|
+
this._w + (v._w - this._w) * t
|
|
284
389
|
);
|
|
285
390
|
}
|
|
286
391
|
|
|
@@ -292,10 +397,10 @@ export class Vec4 {
|
|
|
292
397
|
*/
|
|
293
398
|
equals(v, epsilon = 1e-6) {
|
|
294
399
|
return (
|
|
295
|
-
Math.abs(this.
|
|
296
|
-
Math.abs(this.
|
|
297
|
-
Math.abs(this.
|
|
298
|
-
Math.abs(this.
|
|
400
|
+
Math.abs(this._x - v._x) < epsilon &&
|
|
401
|
+
Math.abs(this._y - v._y) < epsilon &&
|
|
402
|
+
Math.abs(this._z - v._z) < epsilon &&
|
|
403
|
+
Math.abs(this._w - v._w) < epsilon
|
|
299
404
|
);
|
|
300
405
|
}
|
|
301
406
|
|
|
@@ -311,43 +416,92 @@ export class Vec4 {
|
|
|
311
416
|
/**
|
|
312
417
|
* Project 4D point to 3D using perspective projection
|
|
313
418
|
* Projects from 4D to 3D by dividing by (d - w)
|
|
314
|
-
* @param {number} d - Distance parameter (usually 2-5)
|
|
315
|
-
* @param {object} [options] - Projection options
|
|
419
|
+
* @param {number|object} d - Distance parameter (usually 2-5) or options object
|
|
420
|
+
* @param {object|Vec4} [options] - Projection options or target vector
|
|
421
|
+
* @param {Vec4} [target] - Target vector to store result
|
|
316
422
|
* @returns {Vec4} Projected point (w component is 0)
|
|
317
423
|
*/
|
|
318
|
-
projectPerspective(d = 2, options = {}) {
|
|
424
|
+
projectPerspective(d = 2, options = {}, target = null) {
|
|
319
425
|
if (typeof d === 'object') {
|
|
426
|
+
// usage: projectPerspective({ distance: 2, ... }, target?)
|
|
427
|
+
if (options instanceof Vec4) {
|
|
428
|
+
target = options;
|
|
429
|
+
}
|
|
320
430
|
options = d;
|
|
321
431
|
d = options.distance ?? options.d ?? 2;
|
|
432
|
+
} else {
|
|
433
|
+
// usage: projectPerspective(d, options?, target?)
|
|
434
|
+
// usage: projectPerspective(d, target?)
|
|
435
|
+
if (options instanceof Vec4) {
|
|
436
|
+
target = options;
|
|
437
|
+
options = {};
|
|
438
|
+
}
|
|
322
439
|
}
|
|
440
|
+
|
|
441
|
+
options = options || {};
|
|
442
|
+
|
|
323
443
|
const epsilon = options.epsilon ?? 1e-5;
|
|
324
|
-
const denom = d - this.
|
|
444
|
+
const denom = d - this._w;
|
|
325
445
|
const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
|
|
326
446
|
const scale = 1 / clamped;
|
|
327
|
-
|
|
447
|
+
|
|
448
|
+
if (target) {
|
|
449
|
+
target._x = this._x * scale;
|
|
450
|
+
target._y = this._y * scale;
|
|
451
|
+
target._z = this._z * scale;
|
|
452
|
+
target._w = 0;
|
|
453
|
+
return target;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
|
|
328
457
|
}
|
|
329
458
|
|
|
330
459
|
/**
|
|
331
460
|
* Project 4D point to 3D using stereographic projection
|
|
332
461
|
* Maps 4D hypersphere to 3D space
|
|
333
|
-
* @param {object} [options] - Projection options
|
|
462
|
+
* @param {object|Vec4} [options] - Projection options or target vector
|
|
463
|
+
* @param {Vec4} [target] - Target vector to store result
|
|
334
464
|
* @returns {Vec4} Projected point (w component is 0)
|
|
335
465
|
*/
|
|
336
|
-
projectStereographic(options = {}) {
|
|
466
|
+
projectStereographic(options = {}, target = null) {
|
|
467
|
+
if (options instanceof Vec4) {
|
|
468
|
+
target = options;
|
|
469
|
+
options = {};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
options = options || {};
|
|
473
|
+
|
|
337
474
|
const epsilon = options.epsilon ?? 1e-5;
|
|
338
|
-
const denom = 1 - this.
|
|
475
|
+
const denom = 1 - this._w;
|
|
339
476
|
const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
|
|
340
477
|
const scale = 1 / clamped;
|
|
341
|
-
|
|
478
|
+
|
|
479
|
+
if (target) {
|
|
480
|
+
target._x = this._x * scale;
|
|
481
|
+
target._y = this._y * scale;
|
|
482
|
+
target._z = this._z * scale;
|
|
483
|
+
target._w = 0;
|
|
484
|
+
return target;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
|
|
342
488
|
}
|
|
343
489
|
|
|
344
490
|
/**
|
|
345
491
|
* Project 4D point to 3D using orthographic projection
|
|
346
492
|
* Simply drops the W component
|
|
493
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
347
494
|
* @returns {Vec4} Projected point (w component is 0)
|
|
348
495
|
*/
|
|
349
|
-
projectOrthographic() {
|
|
350
|
-
|
|
496
|
+
projectOrthographic(target = null) {
|
|
497
|
+
if (target) {
|
|
498
|
+
target._x = this._x;
|
|
499
|
+
target._y = this._y;
|
|
500
|
+
target._z = this._z;
|
|
501
|
+
target._w = 0;
|
|
502
|
+
return target;
|
|
503
|
+
}
|
|
504
|
+
return new Vec4(this._x, this._y, this._z, 0);
|
|
351
505
|
}
|
|
352
506
|
|
|
353
507
|
/**
|
|
@@ -355,7 +509,7 @@ export class Vec4 {
|
|
|
355
509
|
* @returns {number[]}
|
|
356
510
|
*/
|
|
357
511
|
toArray() {
|
|
358
|
-
return [this.
|
|
512
|
+
return [this._x, this._y, this._z, this._w];
|
|
359
513
|
}
|
|
360
514
|
|
|
361
515
|
/**
|
|
@@ -363,7 +517,7 @@ export class Vec4 {
|
|
|
363
517
|
* @returns {Float32Array}
|
|
364
518
|
*/
|
|
365
519
|
toFloat32Array() {
|
|
366
|
-
return new Float32Array(this.
|
|
520
|
+
return new Float32Array([this._x, this._y, this._z, this._w]);
|
|
367
521
|
}
|
|
368
522
|
|
|
369
523
|
/**
|
|
@@ -371,7 +525,7 @@ export class Vec4 {
|
|
|
371
525
|
* @returns {number[]}
|
|
372
526
|
*/
|
|
373
527
|
toArray3() {
|
|
374
|
-
return [this.
|
|
528
|
+
return [this._x, this._y, this._z];
|
|
375
529
|
}
|
|
376
530
|
|
|
377
531
|
/**
|
|
@@ -380,7 +534,7 @@ export class Vec4 {
|
|
|
380
534
|
* @returns {string}
|
|
381
535
|
*/
|
|
382
536
|
toString(precision = 3) {
|
|
383
|
-
return `Vec4(${this.
|
|
537
|
+
return `Vec4(${this._x.toFixed(precision)}, ${this._y.toFixed(precision)}, ${this._z.toFixed(precision)}, ${this._w.toFixed(precision)})`;
|
|
384
538
|
}
|
|
385
539
|
|
|
386
540
|
/**
|
|
@@ -388,7 +542,7 @@ export class Vec4 {
|
|
|
388
542
|
* @returns {object}
|
|
389
543
|
*/
|
|
390
544
|
toJSON() {
|
|
391
|
-
return { x: this.
|
|
545
|
+
return { x: this._x, y: this._y, z: this._z, w: this._w };
|
|
392
546
|
}
|
|
393
547
|
|
|
394
548
|
// Static factory methods for common vectors
|
|
@@ -787,6 +787,11 @@ void main() {
|
|
|
787
787
|
}`;
|
|
788
788
|
|
|
789
789
|
this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
|
|
790
|
+
|
|
791
|
+
if (!this.program) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
|
|
790
795
|
this.uniforms = {
|
|
791
796
|
resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
|
|
792
797
|
time: this.gl.getUniformLocation(this.program, 'u_time'),
|
|
@@ -817,6 +822,18 @@ void main() {
|
|
|
817
822
|
* Create WebGL program from shaders
|
|
818
823
|
*/
|
|
819
824
|
createProgram(vertexSource, fragmentSource) {
|
|
825
|
+
// CRITICAL FIX: Check WebGL context state before shader operations
|
|
826
|
+
if (!this.gl) {
|
|
827
|
+
console.error('❌ Cannot create program: WebGL context is null');
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (this.gl.isContextLost()) {
|
|
832
|
+
console.error('❌ Cannot create program: WebGL context is lost');
|
|
833
|
+
this._contextLost = true;
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
|
|
820
837
|
const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
|
|
821
838
|
const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
|
|
822
839
|
|
|
@@ -860,6 +877,7 @@ void main() {
|
|
|
860
877
|
|
|
861
878
|
if (this.gl.isContextLost()) {
|
|
862
879
|
console.error('❌ Cannot create shader: WebGL context is lost');
|
|
880
|
+
this._contextLost = true;
|
|
863
881
|
if (window.mobileDebug) {
|
|
864
882
|
window.mobileDebug.log(`❌ ${this.canvas?.id}: Cannot create shader - WebGL context is lost`);
|
|
865
883
|
}
|
|
@@ -924,6 +942,11 @@ void main() {
|
|
|
924
942
|
* Initialize vertex buffers
|
|
925
943
|
*/
|
|
926
944
|
initBuffers() {
|
|
945
|
+
// CRITICAL FIX: Check WebGL context state before buffer operations
|
|
946
|
+
if (!this.gl || this.gl.isContextLost()) {
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
|
|
927
950
|
const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
|
|
928
951
|
|
|
929
952
|
this.buffer = this.gl.createBuffer();
|
|
@@ -939,6 +962,11 @@ void main() {
|
|
|
939
962
|
* Resize canvas and viewport
|
|
940
963
|
*/
|
|
941
964
|
resize() {
|
|
965
|
+
// CRITICAL FIX: Check WebGL context state before viewport operations
|
|
966
|
+
if (!this.gl || this.gl.isContextLost()) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
|
|
942
970
|
// Mobile-optimized canvas sizing
|
|
943
971
|
const dpr = Math.min(window.devicePixelRatio || 1, 2); // Cap at 2x for mobile performance
|
|
944
972
|
const width = this.canvas.clientWidth;
|