@vib3code/sdk 2.0.3-canary.0c55e5a → 2.0.3-canary.183c93e

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.
Files changed (89) hide show
  1. package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +2 -0
  2. package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
  3. package/DOCS/ARCHITECTURE.md +1 -0
  4. package/DOCS/CI_TESTING.md +2 -0
  5. package/DOCS/CLI_ONBOARDING.md +2 -0
  6. package/DOCS/CONTROL_REFERENCE.md +2 -0
  7. package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +2 -0
  8. package/DOCS/ENV_SETUP.md +2 -0
  9. package/DOCS/EPIC_SCROLL_EVENTS.md +2 -0
  10. package/DOCS/EXPANSION_DESIGN.md +979 -0
  11. package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
  12. package/DOCS/EXPORT_FORMATS.md +2 -0
  13. package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
  14. package/DOCS/HANDOFF_LANDING_PAGE.md +2 -0
  15. package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +2 -0
  16. package/DOCS/LICENSING_TIERS.md +2 -0
  17. package/DOCS/MASTER_PLAN_2026-01-31.md +4 -2
  18. package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +3 -1
  19. package/DOCS/OBS_SETUP_GUIDE.md +2 -0
  20. package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
  21. package/DOCS/PRODUCT_STRATEGY.md +2 -0
  22. package/DOCS/PROJECT_SETUP.md +2 -0
  23. package/DOCS/README.md +5 -3
  24. package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +2 -0
  25. package/DOCS/RENDERER_LIFECYCLE.md +2 -0
  26. package/DOCS/REPO_MANIFEST.md +2 -0
  27. package/DOCS/ROADMAP.md +2 -0
  28. package/DOCS/SCROLL_TIMELINE_v3.md +2 -0
  29. package/DOCS/SITE_REFACTOR_PLAN.md +2 -0
  30. package/DOCS/STATUS.md +2 -0
  31. package/DOCS/SYSTEM_INVENTORY.md +4 -2
  32. package/DOCS/TELEMETRY_EXPORTS.md +2 -0
  33. package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +2 -0
  34. package/DOCS/VISUAL_ANALYSIS_FACETAD.md +2 -0
  35. package/DOCS/VISUAL_ANALYSIS_SIMONE.md +2 -0
  36. package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +2 -0
  37. package/DOCS/WEBGPU_STATUS.md +121 -38
  38. package/DOCS/XR_BENCHMARKS.md +2 -0
  39. package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -34
  40. package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -80
  41. package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -42
  42. package/DOCS/archive/SESSION_014_PLAN.md +1 -195
  43. package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -56
  44. package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -72
  45. package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -741
  46. package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -0
  47. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-01-31.md +2 -0
  48. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +2 -0
  49. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +2 -0
  50. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +2 -0
  51. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
  52. package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
  53. package/DOCS/dev-tracks/README.md +2 -0
  54. package/docs/webgpu-live.html +1 -1
  55. package/package.json +1 -1
  56. package/src/agent/mcp/MCPServer.js +195 -136
  57. package/src/agent/mcp/tools.js +45 -32
  58. package/src/experimental/GameLoop.js +72 -0
  59. package/src/experimental/LatticePhysics.js +100 -0
  60. package/src/experimental/LiveDirector.js +143 -0
  61. package/src/experimental/PlayerController4D.js +154 -0
  62. package/src/experimental/VIB3Actor.js +138 -0
  63. package/src/experimental/VIB3Compositor.js +117 -0
  64. package/src/experimental/VIB3Link.js +122 -0
  65. package/src/experimental/VIB3Orchestrator.js +146 -0
  66. package/src/experimental/VIB3Universe.js +109 -0
  67. package/src/experimental/demos/CrystalLabyrinth.js +202 -0
  68. package/src/faceted/FacetedSystem.js +19 -6
  69. package/src/geometry/generators/Crystal.js +2 -2
  70. package/src/holograms/HolographicVisualizer.js +58 -89
  71. package/src/math/Mat4x4.js +155 -23
  72. package/src/math/Rotor4D.js +69 -46
  73. package/src/math/Vec4.js +200 -103
  74. package/src/quantum/QuantumVisualizer.js +24 -20
  75. package/src/render/ShaderLoader.js +38 -0
  76. package/src/render/ShaderProgram.js +4 -4
  77. package/src/render/UnifiedRenderBridge.js +1 -1
  78. package/src/render/backends/WebGPUBackend.js +8 -4
  79. package/src/scene/Node4D.js +74 -24
  80. package/src/shaders/common/geometry24.glsl +65 -0
  81. package/src/shaders/common/geometry24.wgsl +54 -0
  82. package/src/shaders/common/rotation4d.glsl +4 -4
  83. package/src/shaders/common/rotation4d.wgsl +2 -2
  84. package/src/shaders/common/uniforms.wgsl +15 -8
  85. package/src/shaders/faceted/faceted.frag.wgsl +19 -6
  86. package/src/shaders/holographic/holographic.frag.wgsl +7 -5
  87. package/src/shaders/quantum/quantum.frag.wgsl +7 -5
  88. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
  89. package/tools/shader-sync-verify.js +6 -4
@@ -323,14 +323,17 @@ export class Rotor4D {
323
323
  /**
324
324
  * Rotate a 4D vector using sandwich product: v' = R v R†
325
325
  *
326
+ * Matrix math is inlined to avoid allocating a temporary Float32Array(16).
327
+ * Pass an optional target Vec4 to eliminate all allocations.
328
+ *
326
329
  * @param {Vec4} v - Vector to rotate
327
- * @param {Vec4} [target] - Optional target vector to write result to
328
- * @returns {Vec4} Rotated vector
330
+ * @param {Vec4} [target] - Optional pre-allocated Vec4 to write result into
331
+ * @returns {Vec4} Rotated vector (target if provided, otherwise new Vec4)
329
332
  */
330
333
  rotate(v, target) {
331
- // Direct matrix multiplication without allocation
334
+ const x = v.x, y = v.y, z = v.z, w = v.w;
332
335
 
333
- // Normalize components for stability (same as toMatrix)
336
+ // Normalize for numerical stability (same as toMatrix)
334
337
  const n = this.norm();
335
338
  const invN = n > 1e-10 ? 1 / n : 1;
336
339
 
@@ -343,7 +346,7 @@ export class Rotor4D {
343
346
  const zw = this.zw * invN;
344
347
  const xyzw = this.xyzw * invN;
345
348
 
346
- // Pre-compute products
349
+ // Squared terms
347
350
  const s2 = s * s;
348
351
  const xy2 = xy * xy;
349
352
  const xz2 = xz * xz;
@@ -353,22 +356,20 @@ export class Rotor4D {
353
356
  const zw2 = zw * zw;
354
357
  const xyzw2 = xyzw * xyzw;
355
358
 
356
- // Cross terms
359
+ // Cross terms (pre-multiplied by 2)
357
360
  const sxy = 2 * s * xy;
358
361
  const sxz = 2 * s * xz;
359
362
  const syz = 2 * s * yz;
360
363
  const sxw = 2 * s * xw;
361
364
  const syw = 2 * s * yw;
362
365
  const szw = 2 * s * zw;
363
- // const sxyzw = 2 * s * xyzw; // Unused in rotation matrix
364
366
 
365
- const xyxz = 2 * xy * xz;
367
+ const xzyz = 2 * xz * yz;
366
368
  const xyyz = 2 * xy * yz;
369
+ const xyxz = 2 * xy * xz;
367
370
  const xyxw = 2 * xy * xw;
368
371
  const xyyw = 2 * xy * yw;
369
- // const xyzw_c = 2 * xy * zw; // Unused in rotation matrix
370
372
 
371
- const xzyz = 2 * xz * yz;
372
373
  const xzxw = 2 * xz * xw;
373
374
  const xzyw = 2 * xz * yw;
374
375
  const xzzw = 2 * xz * zw;
@@ -388,40 +389,33 @@ export class Rotor4D {
388
389
  const ywxyzw = 2 * yw * xyzw;
389
390
  const zwxyzw = 2 * zw * xyzw;
390
391
 
391
- // Matrix elements
392
- // Col 0
393
- const m00 = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
394
- const m01 = sxy + xzyz + xwyw - zwxyzw;
395
- const m02 = sxz - xyyz + xwzw + ywxyzw;
396
- const m03 = sxw - xyyw - xzzw - yzxyzw;
397
-
398
- // Col 1
399
- const m10 = -sxy + xzyz + xwyw + zwxyzw;
400
- const m11 = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
401
- const m12 = syz + xyxz + ywzw - xwxyzw;
402
- const m13 = syw + xyxw - yzzw + xzxyzw;
403
-
404
- // Col 2
405
- const m20 = -sxz - xyyz + xwzw - ywxyzw;
406
- const m21 = -syz + xyxz + ywzw + xwxyzw;
407
- const m22 = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
408
- const m23 = szw + xzxw + yzyw - xyxyzw;
409
-
410
- // Col 3
411
- const m30 = -sxw - xyyw - xzzw + yzxyzw;
412
- const m31 = -syw + xyxw - yzzw - xzxyzw;
413
- const m32 = -szw + xzxw + yzyw + xyxyzw;
414
- const m33 = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
415
-
416
- const x = v.x;
417
- const y = v.y;
418
- const z = v.z;
419
- const w = v.w;
420
-
421
- const rx = m00 * x + m10 * y + m20 * z + m30 * w;
422
- const ry = m01 * x + m11 * y + m21 * z + m31 * w;
423
- const rz = m02 * x + m12 * y + m22 * z + m32 * w;
424
- const rw = m03 * x + m13 * y + m23 * z + m33 * w;
392
+ // Column-major 4x4 rotation matrix entries (inlined from toMatrix)
393
+ // Column 0
394
+ const m0 = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
395
+ const m1 = sxy + xzyz + xwyw - zwxyzw;
396
+ const m2 = sxz - xyyz + xwzw + ywxyzw;
397
+ const m3 = sxw - xyyw - xzzw - yzxyzw;
398
+ // Column 1
399
+ const m4 = -sxy + xzyz + xwyw + zwxyzw;
400
+ const m5 = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
401
+ const m6 = syz + xyxz + ywzw - xwxyzw;
402
+ const m7 = syw + xyxw - yzzw + xzxyzw;
403
+ // Column 2
404
+ const m8 = -sxz - xyyz + xwzw - ywxyzw;
405
+ const m9 = -syz + xyxz + ywzw + xwxyzw;
406
+ const m10 = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
407
+ const m11 = szw + xzxw + yzyw - xyxyzw;
408
+ // Column 3
409
+ const m12 = -sxw - xyyw - xzzw + yzxyzw;
410
+ const m13 = -syw + xyxw - yzzw - xzxyzw;
411
+ const m14 = -szw + xzxw + yzyw + xyxyzw;
412
+ const m15 = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
413
+
414
+ // Matrix-vector multiply
415
+ const rx = m0 * x + m4 * y + m8 * z + m12 * w;
416
+ const ry = m1 * x + m5 * y + m9 * z + m13 * w;
417
+ const rz = m2 * x + m6 * y + m10 * z + m14 * w;
418
+ const rw = m3 * x + m7 * y + m11 * z + m15 * w;
425
419
 
426
420
  if (target) {
427
421
  target.x = rx;
@@ -430,15 +424,15 @@ export class Rotor4D {
430
424
  target.w = rw;
431
425
  return target;
432
426
  }
433
-
434
427
  return new Vec4(rx, ry, rz, rw);
435
428
  }
436
429
 
437
430
  /**
438
431
  * Convert rotor to 4x4 rotation matrix (column-major for WebGL)
432
+ * @param {Float32Array|Array} [target] - Optional target array to write into
439
433
  * @returns {Float32Array} 16-element array in column-major order
440
434
  */
441
- toMatrix() {
435
+ toMatrix(target = null) {
442
436
  // Normalize first for numerical stability
443
437
  const n = this.norm();
444
438
  const invN = n > 1e-10 ? 1 / n : 1;
@@ -502,6 +496,35 @@ export class Rotor4D {
502
496
  // Formula derived from sandwich product R v R†
503
497
  // Diagonal: s² minus bivectors containing that axis, plus others
504
498
  // Off-diagonal: 2*s*bivector terms for single-plane contributions
499
+
500
+ if (target) {
501
+ // Column 0 (transformed X axis)
502
+ target[0] = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
503
+ target[1] = sxy + xzyz + xwyw - zwxyzw;
504
+ target[2] = sxz - xyyz + xwzw + ywxyzw;
505
+ target[3] = sxw - xyyw - xzzw - yzxyzw;
506
+
507
+ // Column 1 (transformed Y axis)
508
+ target[4] = -sxy + xzyz + xwyw + zwxyzw;
509
+ target[5] = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
510
+ target[6] = syz + xyxz + ywzw - xwxyzw;
511
+ target[7] = syw + xyxw - yzzw + xzxyzw;
512
+
513
+ // Column 2 (transformed Z axis)
514
+ target[8] = -sxz - xyyz + xwzw - ywxyzw;
515
+ target[9] = -syz + xyxz + ywzw + xwxyzw;
516
+ target[10] = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
517
+ target[11] = szw + xzxw + yzyw - xyxyzw;
518
+
519
+ // Column 3 (transformed W axis)
520
+ target[12] = -sxw - xyyw - xzzw + yzxyzw;
521
+ target[13] = -syw + xyxw - yzzw - xzxyzw;
522
+ target[14] = -szw + xzxw + yzyw + xyxyzw;
523
+ target[15] = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
524
+
525
+ return target;
526
+ }
527
+
505
528
  return new Float32Array([
506
529
  // Column 0 (transformed X axis)
507
530
  s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
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 Float32Array for GPU compatibility and potential SIMD optimization.
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
- // Use Float32Array for GPU compatibility
23
- this.data = new Float32Array(4);
24
- this.data[0] = x;
25
- this.data[1] = y;
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 for readability
31
- get x() { return this.data[0]; }
32
- set x(v) { this.data[0] = v; }
29
+ // Property accessors
30
+ get x() { return this._x; }
31
+ set x(v) { this._x = v; }
33
32
 
34
- get y() { return this.data[1]; }
35
- set y(v) { this.data[1] = v; }
33
+ get y() { return this._y; }
34
+ set y(v) { this._y = v; }
36
35
 
37
- get z() { return this.data[2]; }
38
- set z(v) { this.data[2] = v; }
36
+ get z() { return this._z; }
37
+ set z(v) { this._z = v; }
39
38
 
40
- get w() { return this.data[3]; }
41
- set w(v) { this.data[3] = v; }
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.x, this.y, this.z, this.w);
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.data[0] = v.data[0];
67
- this.data[1] = v.data[1];
68
- this.data[2] = v.data[2];
69
- this.data[3] = v.data[3];
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.data[0] = x;
83
- this.data[1] = y;
84
- this.data[2] = z;
85
- this.data[3] = w;
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
- * @returns {Vec4} New vector
93
- */
94
- add(v) {
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.x + v.x,
97
- this.y + v.y,
98
- this.z + v.z,
99
- this.w + v.w
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.data[0] += v.data[0];
110
- this.data[1] += v.data[1];
111
- this.data[2] += v.data[2];
112
- this.data[3] += v.data[3];
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
- * @returns {Vec4} New vector
120
- */
121
- sub(v) {
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.x - v.x,
124
- this.y - v.y,
125
- this.z - v.z,
126
- this.w - v.w
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.data[0] -= v.data[0];
137
- this.data[1] -= v.data[1];
138
- this.data[2] -= v.data[2];
139
- this.data[3] -= v.data[3];
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
- * @returns {Vec4} New vector
147
- */
148
- scale(s) {
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.x * s,
151
- this.y * s,
152
- this.z * s,
153
- this.w * s
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.data[0] *= s;
164
- this.data[1] *= s;
165
- this.data[2] *= s;
166
- this.data[3] *= s;
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
- * @returns {Vec4} New vector
174
- */
175
- multiply(v) {
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.x * v.x,
178
- this.y * v.y,
179
- this.z * v.z,
180
- this.w * v.w
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
- * @returns {Vec4} New vector
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
- return new Vec4(-this.x, -this.y, -this.z, -this.w);
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.data[0] = -this.data[0];
198
- this.data[1] = -this.data[1];
199
- this.data[2] = -this.data[2];
200
- this.data[3] = -this.data[3];
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.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
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.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
299
+ return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
219
300
  }
220
301
 
221
302
  /**
@@ -245,15 +326,23 @@ export class Vec4 {
245
326
  }
246
327
 
247
328
  /**
248
- * Normalize to unit length (immutable)
249
- * @returns {Vec4} New normalized vector
329
+ * Normalize to unit length (immutable unless target provided)
330
+ * @param {Vec4} [target=null] - Optional target vector
331
+ * @returns {Vec4} New normalized vector or target
250
332
  */
251
- normalize() {
333
+ normalize(target = null) {
252
334
  const len = this.length();
253
335
  if (len < 1e-10) {
336
+ if (target) {
337
+ target._x = 0;
338
+ target._y = 0;
339
+ target._z = 0;
340
+ target._w = 0;
341
+ return target;
342
+ }
254
343
  return new Vec4(0, 0, 0, 0);
255
344
  }
256
- return this.scale(1 / len);
345
+ return this.scale(1 / len, target);
257
346
  }
258
347
 
259
348
  /**
@@ -273,14 +362,22 @@ export class Vec4 {
273
362
  * Linear interpolation to another vector
274
363
  * @param {Vec4} v - Target vector
275
364
  * @param {number} t - Interpolation factor (0-1)
276
- * @returns {Vec4} New interpolated vector
277
- */
278
- lerp(v, t) {
365
+ * @param {Vec4} [target=null] - Optional target vector
366
+ * @returns {Vec4} New interpolated vector or target
367
+ */
368
+ lerp(v, t, target = null) {
369
+ if (target) {
370
+ target._x = this._x + (v._x - this._x) * t;
371
+ target._y = this._y + (v._y - this._y) * t;
372
+ target._z = this._z + (v._z - this._z) * t;
373
+ target._w = this._w + (v._w - this._w) * t;
374
+ return target;
375
+ }
279
376
  return new Vec4(
280
- this.x + (v.x - this.x) * t,
281
- this.y + (v.y - this.y) * t,
282
- this.z + (v.z - this.z) * t,
283
- this.w + (v.w - this.w) * t
377
+ this._x + (v._x - this._x) * t,
378
+ this._y + (v._y - this._y) * t,
379
+ this._z + (v._z - this._z) * t,
380
+ this._w + (v._w - this._w) * t
284
381
  );
285
382
  }
286
383
 
@@ -292,10 +389,10 @@ export class Vec4 {
292
389
  */
293
390
  equals(v, epsilon = 1e-6) {
294
391
  return (
295
- Math.abs(this.x - v.x) < epsilon &&
296
- Math.abs(this.y - v.y) < epsilon &&
297
- Math.abs(this.z - v.z) < epsilon &&
298
- Math.abs(this.w - v.w) < epsilon
392
+ Math.abs(this._x - v._x) < epsilon &&
393
+ Math.abs(this._y - v._y) < epsilon &&
394
+ Math.abs(this._z - v._z) < epsilon &&
395
+ Math.abs(this._w - v._w) < epsilon
299
396
  );
300
397
  }
301
398
 
@@ -321,10 +418,10 @@ export class Vec4 {
321
418
  d = options.distance ?? options.d ?? 2;
322
419
  }
323
420
  const epsilon = options.epsilon ?? 1e-5;
324
- const denom = d - this.w;
421
+ const denom = d - this._w;
325
422
  const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
326
423
  const scale = 1 / clamped;
327
- return new Vec4(this.x * scale, this.y * scale, this.z * scale, 0);
424
+ return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
328
425
  }
329
426
 
330
427
  /**
@@ -335,10 +432,10 @@ export class Vec4 {
335
432
  */
336
433
  projectStereographic(options = {}) {
337
434
  const epsilon = options.epsilon ?? 1e-5;
338
- const denom = 1 - this.w;
435
+ const denom = 1 - this._w;
339
436
  const clamped = Math.abs(denom) < epsilon ? (denom >= 0 ? epsilon : -epsilon) : denom;
340
437
  const scale = 1 / clamped;
341
- return new Vec4(this.x * scale, this.y * scale, this.z * scale, 0);
438
+ return new Vec4(this._x * scale, this._y * scale, this._z * scale, 0);
342
439
  }
343
440
 
344
441
  /**
@@ -347,7 +444,7 @@ export class Vec4 {
347
444
  * @returns {Vec4} Projected point (w component is 0)
348
445
  */
349
446
  projectOrthographic() {
350
- return new Vec4(this.x, this.y, this.z, 0);
447
+ return new Vec4(this._x, this._y, this._z, 0);
351
448
  }
352
449
 
353
450
  /**
@@ -355,7 +452,7 @@ export class Vec4 {
355
452
  * @returns {number[]}
356
453
  */
357
454
  toArray() {
358
- return [this.x, this.y, this.z, this.w];
455
+ return [this._x, this._y, this._z, this._w];
359
456
  }
360
457
 
361
458
  /**
@@ -363,7 +460,7 @@ export class Vec4 {
363
460
  * @returns {Float32Array}
364
461
  */
365
462
  toFloat32Array() {
366
- return new Float32Array(this.data);
463
+ return new Float32Array([this._x, this._y, this._z, this._w]);
367
464
  }
368
465
 
369
466
  /**
@@ -371,7 +468,7 @@ export class Vec4 {
371
468
  * @returns {number[]}
372
469
  */
373
470
  toArray3() {
374
- return [this.x, this.y, this.z];
471
+ return [this._x, this._y, this._z];
375
472
  }
376
473
 
377
474
  /**
@@ -380,7 +477,7 @@ export class Vec4 {
380
477
  * @returns {string}
381
478
  */
382
479
  toString(precision = 3) {
383
- return `Vec4(${this.x.toFixed(precision)}, ${this.y.toFixed(precision)}, ${this.z.toFixed(precision)}, ${this.w.toFixed(precision)})`;
480
+ return `Vec4(${this._x.toFixed(precision)}, ${this._y.toFixed(precision)}, ${this._z.toFixed(precision)}, ${this._w.toFixed(precision)})`;
384
481
  }
385
482
 
386
483
  /**
@@ -388,7 +485,7 @@ export class Vec4 {
388
485
  * @returns {object}
389
486
  */
390
487
  toJSON() {
391
- return { x: this.x, y: this.y, z: this.z, w: this.w };
488
+ return { x: this._x, y: this._y, z: this._z, w: this._w };
392
489
  }
393
490
 
394
491
  // Static factory methods for common vectors