@vib3code/sdk 2.0.3-canary.20f0435 → 2.0.3-canary.3206d35

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 (58) 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 +2 -0
  11. package/DOCS/EXPANSION_DESIGN_ULTRA.md +2 -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 +2 -0
  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 +1 -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 +2 -0
  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 +2 -0
  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 -38
  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 +2 -0
  52. package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +2 -0
  53. package/DOCS/dev-tracks/README.md +2 -0
  54. package/package.json +1 -1
  55. package/src/math/Mat4x4.js +116 -86
  56. package/src/math/Rotor4D.js +31 -1
  57. package/src/math/Vec4.js +81 -25
  58. package/src/scene/Node4D.js +74 -24
@@ -1,38 +1 @@
1
- # WebGPU status and testing requirements
2
-
3
- This document records the current WebGPU backend state, what is implemented, and what is required
4
- to validate it in local development or CI.
5
-
6
- ## Current status
7
- - **Backend scaffold:** `WebGPUBackend` initializes adapter/device, configures the canvas, manages
8
- resize, and supports a clear-pass `renderFrame()` path.
9
- - **Async context creation:** `createRenderContextAsync()` can instantiate WebGPU contexts using
10
- `{ backend: 'webgpu' }`.
11
- - **Resource tracking:** depth textures are registered in the shared `RenderResourceRegistry`.
12
-
13
- ## What is still needed
14
- 1. **Pipeline parity:** implement basic shader pipelines (vertex/fragment) and buffer binding that
15
- match the WebGL backend command flow.
16
- 2. **Command buffer bridge:** map existing render commands to WebGPU render passes.
17
- 3. **Feature gating:** add host-app controls to toggle WebGPU via feature flags.
18
- 4. **Diagnostics:** add per-frame stats and resource delta reporting for WebGPU.
19
-
20
- ## Testing requirements
21
- ### Local smoke test
22
- Prerequisites:
23
- - A browser with WebGPU enabled (Chrome/Edge with `chrome://flags/#enable-unsafe-webgpu`, or a
24
- Chromium build with WebGPU support).
25
- - A device with WebGPU-capable GPU drivers.
26
-
27
- Suggested smoke flow:
28
- 1. Create a canvas and call `createRenderContextAsync(canvas, { backend: 'webgpu' })`.
29
- 2. Call `backend.renderFrame({ clearColor: [0.1, 0.1, 0.2, 1] })` and confirm the canvas clears.
30
- 3. Resize the canvas and ensure the clear pass still succeeds.
31
-
32
- ### CI validation
33
- - WebGPU cannot be reliably validated in headless CI without GPU support.
34
- - CI should instead run WebGL tests and lint/static checks; keep a manual WebGPU smoke checklist.
35
-
36
- ## File locations
37
- - `src/render/backends/WebGPUBackend.js`
38
- - `src/render/index.js` (`createRenderContextAsync`)
1
+ Last reviewed: 2026-02-17
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Dev Track Session — January 31, 2026
2
4
 
3
5
  **Branch**: `claude/review-project-status-BwVbr`
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Development Session — 2026-02-06
2
4
 
3
5
  **Session type**: Full codebase audit + hygiene + MCP server + agent docs + testing
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Development Session — 2026-02-13
2
4
 
3
5
  **Session type**: Agent Harness Implementation — MCP tools, ChoreographyPlayer, aesthetic mapping, headless rendering
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Development Session — 2026-02-15
2
4
 
3
5
  **Session type**: Layer Architecture Redesign, Codebase Audit, Preset/Reactivity Expansion
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Development Session — 2026-02-16
2
4
 
3
5
  **Session type**: Architecture Bug Fixes, Shader Consistency, Documentation Sweep
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Performance Upgrade Report — 2026-02-16
2
4
 
3
5
  **Type**: CPU-side math optimization (Rotor4D + Vec4)
@@ -1,3 +1,5 @@
1
+ Last reviewed: 2026-02-17
2
+
1
3
  # Development Track Logs
2
4
 
3
5
  Detailed, session-level implementation notes are stored here.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vib3code/sdk",
3
- "version": "2.0.3-canary.20f0435",
3
+ "version": "2.0.3-canary.3206d35",
4
4
  "description": "VIB3+ 4D Visualization SDK - Unified engine with 6D rotation, MCP agentic integration, and cross-platform support",
5
5
  "type": "module",
6
6
  "main": "src/core/VIB3Engine.js",
@@ -18,6 +18,12 @@
18
18
  import { Vec4 } from './Vec4.js';
19
19
 
20
20
  export class Mat4x4 {
21
+ /**
22
+ * Internal token to skip initialization during construction
23
+ * @private
24
+ */
25
+ static UNINITIALIZED = {};
26
+
21
27
  /**
22
28
  * Create a new 4x4 matrix
23
29
  * Default is identity matrix
@@ -26,6 +32,8 @@ export class Mat4x4 {
26
32
  constructor(elements = null) {
27
33
  this.data = new Float32Array(16);
28
34
 
35
+ if (elements === Mat4x4.UNINITIALIZED) return;
36
+
29
37
  if (elements) {
30
38
  if (elements.length !== 16) {
31
39
  throw new Error('Mat4x4 requires exactly 16 elements');
@@ -45,12 +53,7 @@ export class Mat4x4 {
45
53
  * @returns {Mat4x4}
46
54
  */
47
55
  static identity() {
48
- return new Mat4x4([
49
- 1, 0, 0, 0,
50
- 0, 1, 0, 0,
51
- 0, 0, 1, 0,
52
- 0, 0, 0, 1
53
- ]);
56
+ return new Mat4x4();
54
57
  }
55
58
 
56
59
  /**
@@ -58,7 +61,7 @@ export class Mat4x4 {
58
61
  * @returns {Mat4x4}
59
62
  */
60
63
  static zero() {
61
- return new Mat4x4(new Float32Array(16));
64
+ return new Mat4x4(Mat4x4.UNINITIALIZED);
62
65
  }
63
66
 
64
67
  /**
@@ -157,10 +160,11 @@ export class Mat4x4 {
157
160
  /**
158
161
  * Multiply two matrices
159
162
  * @param {Mat4x4} m - Right operand
163
+ * @param {Mat4x4} [target=null] - Optional target matrix to store result
160
164
  * @returns {Mat4x4} New matrix = this * m
161
165
  */
162
- multiply(m) {
163
- const out = new Mat4x4();
166
+ multiply(m, target = null) {
167
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
164
168
  const r = out.data;
165
169
  const a = this.data;
166
170
  const b = m.data;
@@ -259,16 +263,22 @@ export class Mat4x4 {
259
263
  /**
260
264
  * Transform a Vec4 by this matrix
261
265
  * @param {Vec4} v
266
+ * @param {Vec4} [target=null] - Optional target vector to store result
262
267
  * @returns {Vec4} Transformed vector
263
268
  */
264
- multiplyVec4(v) {
269
+ multiplyVec4(v, target = null) {
265
270
  const m = this.data;
266
- return new Vec4(
267
- m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12] * v.w,
268
- m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13] * v.w,
269
- m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14] * v.w,
270
- m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15] * v.w
271
- );
271
+ const out = target || new Vec4();
272
+
273
+ // Cache components to support aliasing (target === v)
274
+ const x = v.x, y = v.y, z = v.z, w = v.w;
275
+
276
+ out.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
277
+ out.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
278
+ out.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
279
+ out.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
280
+
281
+ return out;
272
282
  }
273
283
 
274
284
  /**
@@ -310,27 +320,36 @@ export class Mat4x4 {
310
320
  /**
311
321
  * Add another matrix
312
322
  * @param {Mat4x4} m
323
+ * @param {Mat4x4} [target=null] - Optional target matrix
313
324
  * @returns {Mat4x4} New matrix
314
325
  */
315
- add(m) {
316
- const result = new Float32Array(16);
326
+ add(m, target = null) {
327
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
328
+ const r = out.data;
329
+ const a = this.data;
330
+ const b = m.data;
331
+
317
332
  for (let i = 0; i < 16; i++) {
318
- result[i] = this.data[i] + m.data[i];
333
+ r[i] = a[i] + b[i];
319
334
  }
320
- return new Mat4x4(result);
335
+ return out;
321
336
  }
322
337
 
323
338
  /**
324
339
  * Multiply by scalar
325
340
  * @param {number} s
341
+ * @param {Mat4x4} [target=null] - Optional target matrix
326
342
  * @returns {Mat4x4} New matrix
327
343
  */
328
- scale(s) {
329
- const result = new Float32Array(16);
344
+ scale(s, target = null) {
345
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
346
+ const r = out.data;
347
+ const a = this.data;
348
+
330
349
  for (let i = 0; i < 16; i++) {
331
- result[i] = this.data[i] * s;
350
+ r[i] = a[i] * s;
332
351
  }
333
- return new Mat4x4(result);
352
+ return out;
334
353
  }
335
354
 
336
355
  /**
@@ -339,12 +358,13 @@ export class Mat4x4 {
339
358
  */
340
359
  transpose() {
341
360
  const m = this.data;
342
- return new Mat4x4([
343
- m[0], m[4], m[8], m[12],
344
- m[1], m[5], m[9], m[13],
345
- m[2], m[6], m[10], m[14],
346
- m[3], m[7], m[11], m[15]
347
- ]);
361
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
362
+ const r = out.data;
363
+ r[0] = m[0]; r[4] = m[1]; r[8] = m[2]; r[12] = m[3];
364
+ r[1] = m[4]; r[5] = m[5]; r[9] = m[6]; r[13] = m[7];
365
+ r[2] = m[8]; r[6] = m[9]; r[10] = m[10]; r[14] = m[11];
366
+ r[3] = m[12]; r[7] = m[13]; r[11] = m[14]; r[15] = m[15];
367
+ return out;
348
368
  }
349
369
 
350
370
  /**
@@ -399,7 +419,8 @@ export class Mat4x4 {
399
419
  */
400
420
  inverse() {
401
421
  const m = this.data;
402
- const inv = new Float32Array(16);
422
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
423
+ const inv = out.data;
403
424
 
404
425
  inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
405
426
  m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
@@ -460,7 +481,7 @@ export class Mat4x4 {
460
481
  inv[i] *= invDet;
461
482
  }
462
483
 
463
- return new Mat4x4(inv);
484
+ return out;
464
485
  }
465
486
 
466
487
  /**
@@ -673,12 +694,13 @@ export class Mat4x4 {
673
694
  static rotationXY(angle) {
674
695
  const c = Math.cos(angle);
675
696
  const s = Math.sin(angle);
676
- return new Mat4x4([
677
- c, s, 0, 0,
678
- -s, c, 0, 0,
679
- 0, 0, 1, 0,
680
- 0, 0, 0, 1
681
- ]);
697
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
698
+ const r = out.data;
699
+ r[0] = c; r[1] = s;
700
+ r[4] = -s; r[5] = c;
701
+ r[10] = 1;
702
+ r[15] = 1;
703
+ return out;
682
704
  }
683
705
 
684
706
  /**
@@ -689,12 +711,13 @@ export class Mat4x4 {
689
711
  static rotationXZ(angle) {
690
712
  const c = Math.cos(angle);
691
713
  const s = Math.sin(angle);
692
- return new Mat4x4([
693
- c, 0, -s, 0,
694
- 0, 1, 0, 0,
695
- s, 0, c, 0,
696
- 0, 0, 0, 1
697
- ]);
714
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
715
+ const r = out.data;
716
+ r[0] = c; r[2] = -s;
717
+ r[5] = 1;
718
+ r[8] = s; r[10] = c;
719
+ r[15] = 1;
720
+ return out;
698
721
  }
699
722
 
700
723
  /**
@@ -705,12 +728,13 @@ export class Mat4x4 {
705
728
  static rotationYZ(angle) {
706
729
  const c = Math.cos(angle);
707
730
  const s = Math.sin(angle);
708
- return new Mat4x4([
709
- 1, 0, 0, 0,
710
- 0, c, s, 0,
711
- 0, -s, c, 0,
712
- 0, 0, 0, 1
713
- ]);
731
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
732
+ const r = out.data;
733
+ r[0] = 1;
734
+ r[5] = c; r[6] = s;
735
+ r[9] = -s; r[10] = c;
736
+ r[15] = 1;
737
+ return out;
714
738
  }
715
739
 
716
740
  /**
@@ -722,12 +746,13 @@ export class Mat4x4 {
722
746
  static rotationXW(angle) {
723
747
  const c = Math.cos(angle);
724
748
  const s = Math.sin(angle);
725
- return new Mat4x4([
726
- c, 0, 0, s,
727
- 0, 1, 0, 0,
728
- 0, 0, 1, 0,
729
- -s, 0, 0, c
730
- ]);
749
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
750
+ const r = out.data;
751
+ r[0] = c; r[3] = s;
752
+ r[5] = 1;
753
+ r[10] = 1;
754
+ r[12] = -s; r[15] = c;
755
+ return out;
731
756
  }
732
757
 
733
758
  /**
@@ -738,12 +763,13 @@ export class Mat4x4 {
738
763
  static rotationYW(angle) {
739
764
  const c = Math.cos(angle);
740
765
  const s = Math.sin(angle);
741
- return new Mat4x4([
742
- 1, 0, 0, 0,
743
- 0, c, 0, s,
744
- 0, 0, 1, 0,
745
- 0, -s, 0, c
746
- ]);
766
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
767
+ const r = out.data;
768
+ r[0] = 1;
769
+ r[5] = c; r[7] = s;
770
+ r[10] = 1;
771
+ r[13] = -s; r[15] = c;
772
+ return out;
747
773
  }
748
774
 
749
775
  /**
@@ -754,12 +780,13 @@ export class Mat4x4 {
754
780
  static rotationZW(angle) {
755
781
  const c = Math.cos(angle);
756
782
  const s = Math.sin(angle);
757
- return new Mat4x4([
758
- 1, 0, 0, 0,
759
- 0, 1, 0, 0,
760
- 0, 0, c, s,
761
- 0, 0, -s, c
762
- ]);
783
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
784
+ const r = out.data;
785
+ r[0] = 1;
786
+ r[5] = 1;
787
+ r[10] = c; r[11] = s;
788
+ r[14] = -s; r[15] = c;
789
+ return out;
763
790
  }
764
791
 
765
792
  /**
@@ -831,12 +858,13 @@ export class Mat4x4 {
831
858
  * @returns {Mat4x4}
832
859
  */
833
860
  static uniformScale(s) {
834
- return new Mat4x4([
835
- s, 0, 0, 0,
836
- 0, s, 0, 0,
837
- 0, 0, s, 0,
838
- 0, 0, 0, s
839
- ]);
861
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
862
+ const r = out.data;
863
+ r[0] = s;
864
+ r[5] = s;
865
+ r[10] = s;
866
+ r[15] = s;
867
+ return out;
840
868
  }
841
869
 
842
870
  /**
@@ -848,12 +876,13 @@ export class Mat4x4 {
848
876
  * @returns {Mat4x4}
849
877
  */
850
878
  static scale(sx, sy, sz, sw = 1) {
851
- return new Mat4x4([
852
- sx, 0, 0, 0,
853
- 0, sy, 0, 0,
854
- 0, 0, sz, 0,
855
- 0, 0, 0, sw
856
- ]);
879
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
880
+ const r = out.data;
881
+ r[0] = sx;
882
+ r[5] = sy;
883
+ r[10] = sz;
884
+ r[15] = sw;
885
+ return out;
857
886
  }
858
887
 
859
888
  /**
@@ -869,12 +898,13 @@ export class Mat4x4 {
869
898
  static translation(tx, ty, tz, tw = 0) {
870
899
  // For true 4D translation, you need 5D homogeneous coordinates
871
900
  // This is a placeholder that adds the translation to the W column
872
- return new Mat4x4([
873
- 1, 0, 0, 0,
874
- 0, 1, 0, 0,
875
- 0, 0, 1, 0,
876
- tx, ty, tz, 1 + tw
877
- ]);
901
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
902
+ const r = out.data;
903
+ r[0] = 1;
904
+ r[5] = 1;
905
+ r[10] = 1;
906
+ r[12] = tx; r[13] = ty; r[14] = tz; r[15] = 1 + tw;
907
+ return out;
878
908
  }
879
909
  }
880
910
 
@@ -429,9 +429,10 @@ export class Rotor4D {
429
429
 
430
430
  /**
431
431
  * Convert rotor to 4x4 rotation matrix (column-major for WebGL)
432
+ * @param {Float32Array|Array} [target] - Optional target array to write into
432
433
  * @returns {Float32Array} 16-element array in column-major order
433
434
  */
434
- toMatrix() {
435
+ toMatrix(target = null) {
435
436
  // Normalize first for numerical stability
436
437
  const n = this.norm();
437
438
  const invN = n > 1e-10 ? 1 / n : 1;
@@ -495,6 +496,35 @@ export class Rotor4D {
495
496
  // Formula derived from sandwich product R v R†
496
497
  // Diagonal: s² minus bivectors containing that axis, plus others
497
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
+
498
528
  return new Float32Array([
499
529
  // Column 0 (transformed X axis)
500
530
  s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
package/src/math/Vec4.js CHANGED
@@ -128,11 +128,19 @@ export class Vec4 {
128
128
  }
129
129
 
130
130
  /**
131
- * Add another vector (immutable)
131
+ * Add another vector (immutable unless target provided)
132
132
  * @param {Vec4} v
133
- * @returns {Vec4} New vector
134
- */
135
- 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
+ }
136
144
  return new Vec4(
137
145
  this._x + v._x,
138
146
  this._y + v._y,
@@ -155,11 +163,19 @@ export class Vec4 {
155
163
  }
156
164
 
157
165
  /**
158
- * Subtract another vector (immutable)
166
+ * Subtract another vector (immutable unless target provided)
159
167
  * @param {Vec4} v
160
- * @returns {Vec4} New vector
161
- */
162
- 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
+ }
163
179
  return new Vec4(
164
180
  this._x - v._x,
165
181
  this._y - v._y,
@@ -182,11 +198,19 @@ export class Vec4 {
182
198
  }
183
199
 
184
200
  /**
185
- * Multiply by scalar (immutable)
201
+ * Multiply by scalar (immutable unless target provided)
186
202
  * @param {number} s
187
- * @returns {Vec4} New vector
188
- */
189
- 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
+ }
190
214
  return new Vec4(
191
215
  this._x * s,
192
216
  this._y * s,
@@ -211,9 +235,17 @@ export class Vec4 {
211
235
  /**
212
236
  * Component-wise multiply (Hadamard product)
213
237
  * @param {Vec4} v
214
- * @returns {Vec4} New vector
215
- */
216
- 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
+ }
217
249
  return new Vec4(
218
250
  this._x * v._x,
219
251
  this._y * v._y,
@@ -223,10 +255,18 @@ export class Vec4 {
223
255
  }
224
256
 
225
257
  /**
226
- * Negate vector (immutable)
227
- * @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
228
261
  */
229
- negate() {
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
+ }
230
270
  return new Vec4(-this._x, -this._y, -this._z, -this._w);
231
271
  }
232
272
 
@@ -286,15 +326,23 @@ export class Vec4 {
286
326
  }
287
327
 
288
328
  /**
289
- * Normalize to unit length (immutable)
290
- * @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
291
332
  */
292
- normalize() {
333
+ normalize(target = null) {
293
334
  const len = this.length();
294
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
+ }
295
343
  return new Vec4(0, 0, 0, 0);
296
344
  }
297
- return this.scale(1 / len);
345
+ return this.scale(1 / len, target);
298
346
  }
299
347
 
300
348
  /**
@@ -314,9 +362,17 @@ export class Vec4 {
314
362
  * Linear interpolation to another vector
315
363
  * @param {Vec4} v - Target vector
316
364
  * @param {number} t - Interpolation factor (0-1)
317
- * @returns {Vec4} New interpolated vector
318
- */
319
- 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
+ }
320
376
  return new Vec4(
321
377
  this._x + (v._x - this._x) * t,
322
378
  this._y + (v._y - this._y) * t,