@vib3code/sdk 2.0.3-canary.91a95f3 → 2.0.3-canary.98b84da

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 (138) 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 +15 -0
  50. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -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 +11 -4
  56. package/src/agent/index.js +1 -3
  57. package/src/agent/mcp/MCPServer.js +542 -188
  58. package/src/agent/mcp/index.js +1 -1
  59. package/src/agent/mcp/tools.js +132 -32
  60. package/src/cli/index.js +431 -47
  61. package/src/core/VIB3Engine.js +55 -3
  62. package/src/core/index.js +18 -0
  63. package/src/core/renderers/FacetedRendererAdapter.js +10 -9
  64. package/src/core/renderers/HolographicRendererAdapter.js +11 -7
  65. package/src/core/renderers/QuantumRendererAdapter.js +11 -7
  66. package/src/creative/index.js +11 -0
  67. package/src/experimental/GameLoop.js +72 -0
  68. package/src/experimental/LatticePhysics.js +100 -0
  69. package/src/experimental/LiveDirector.js +143 -0
  70. package/src/experimental/PlayerController4D.js +154 -0
  71. package/src/experimental/VIB3Actor.js +138 -0
  72. package/src/experimental/VIB3Compositor.js +117 -0
  73. package/src/experimental/VIB3Link.js +122 -0
  74. package/src/experimental/VIB3Orchestrator.js +146 -0
  75. package/src/experimental/VIB3Universe.js +109 -0
  76. package/src/experimental/demos/CrystalLabyrinth.js +202 -0
  77. package/src/export/SVGExporter.js +9 -5
  78. package/src/export/index.js +11 -1
  79. package/src/faceted/FacetedSystem.js +27 -10
  80. package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
  81. package/src/geometry/generators/Crystal.js +2 -2
  82. package/src/geometry/warp/HypersphereCore.js +53 -24
  83. package/src/holograms/HolographicVisualizer.js +58 -89
  84. package/src/holograms/RealHolographicSystem.js +126 -31
  85. package/src/math/Mat4x4.js +372 -140
  86. package/src/math/Projection.js +39 -4
  87. package/src/math/Rotor4D.js +157 -67
  88. package/src/math/Vec4.js +265 -111
  89. package/src/math/index.js +7 -7
  90. package/src/quantum/QuantumVisualizer.js +24 -20
  91. package/src/reactivity/index.js +3 -5
  92. package/src/render/LayerPresetManager.js +372 -0
  93. package/src/render/LayerReactivityBridge.js +344 -0
  94. package/src/render/LayerRelationshipGraph.js +610 -0
  95. package/src/render/MultiCanvasBridge.js +148 -25
  96. package/src/render/ShaderLoader.js +38 -0
  97. package/src/render/ShaderProgram.js +4 -4
  98. package/src/render/UnifiedRenderBridge.js +1 -1
  99. package/src/render/backends/WebGPUBackend.js +8 -4
  100. package/src/render/index.js +27 -2
  101. package/src/scene/Node4D.js +74 -24
  102. package/src/scene/index.js +4 -4
  103. package/src/shaders/common/geometry24.glsl +65 -0
  104. package/src/shaders/common/geometry24.wgsl +54 -0
  105. package/src/shaders/common/rotation4d.glsl +4 -4
  106. package/src/shaders/common/rotation4d.wgsl +2 -2
  107. package/src/shaders/common/uniforms.wgsl +15 -8
  108. package/src/shaders/faceted/faceted.frag.wgsl +19 -6
  109. package/src/shaders/holographic/holographic.frag.wgsl +7 -5
  110. package/src/shaders/quantum/quantum.frag.wgsl +7 -5
  111. package/src/testing/ParallelTestFramework.js +2 -2
  112. package/src/testing/ProjectionClass.test.js +38 -0
  113. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
  114. package/src/viewer/GalleryUI.js +17 -0
  115. package/src/viewer/ViewerPortal.js +2 -2
  116. package/tools/shader-sync-verify.js +6 -4
  117. package/tools/update_projection.py +109 -0
  118. package/types/adaptive-sdk.d.ts +204 -5
  119. package/types/agent/cli.d.ts +78 -0
  120. package/types/agent/index.d.ts +18 -0
  121. package/types/agent/mcp.d.ts +87 -0
  122. package/types/agent/telemetry.d.ts +190 -0
  123. package/types/core/VIB3Engine.d.ts +26 -0
  124. package/types/core/index.d.ts +261 -0
  125. package/types/creative/AestheticMapper.d.ts +72 -0
  126. package/types/creative/ChoreographyPlayer.d.ts +96 -0
  127. package/types/creative/index.d.ts +17 -0
  128. package/types/export/index.d.ts +243 -0
  129. package/types/geometry/index.d.ts +164 -0
  130. package/types/math/index.d.ts +214 -0
  131. package/types/render/LayerPresetManager.d.ts +78 -0
  132. package/types/render/LayerReactivityBridge.d.ts +85 -0
  133. package/types/render/LayerRelationshipGraph.d.ts +174 -0
  134. package/types/render/index.d.ts +3 -0
  135. package/types/scene/index.d.ts +204 -0
  136. package/types/systems/index.d.ts +244 -0
  137. package/types/variations/index.d.ts +62 -0
  138. package/types/viewer/index.d.ts +225 -0
@@ -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,24 +160,46 @@ 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) {
166
+ multiply(m, target = null) {
167
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
168
+ const r = out.data;
163
169
  const a = this.data;
164
170
  const b = m.data;
165
- const result = new Float32Array(16);
166
-
167
- for (let col = 0; col < 4; col++) {
168
- for (let row = 0; row < 4; row++) {
169
- let sum = 0;
170
- for (let k = 0; k < 4; k++) {
171
- sum += a[k * 4 + row] * b[col * 4 + k];
172
- }
173
- result[col * 4 + row] = sum;
174
- }
175
- }
176
171
 
177
- return new Mat4x4(result);
172
+ const a00 = a[0], a01 = a[4], a02 = a[8], a03 = a[12];
173
+ const a10 = a[1], a11 = a[5], a12 = a[9], a13 = a[13];
174
+ const a20 = a[2], a21 = a[6], a22 = a[10], a23 = a[14];
175
+ const a30 = a[3], a31 = a[7], a32 = a[11], a33 = a[15];
176
+
177
+ const b00 = b[0], b01 = b[4], b02 = b[8], b03 = b[12];
178
+ const b10 = b[1], b11 = b[5], b12 = b[9], b13 = b[13];
179
+ const b20 = b[2], b21 = b[6], b22 = b[10], b23 = b[14];
180
+ const b30 = b[3], b31 = b[7], b32 = b[11], b33 = b[15];
181
+
182
+ r[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
183
+ r[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
184
+ r[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
185
+ r[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
186
+
187
+ r[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
188
+ r[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
189
+ r[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
190
+ r[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
191
+
192
+ r[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
193
+ r[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
194
+ r[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
195
+ r[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
196
+
197
+ r[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
198
+ r[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
199
+ r[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
200
+ r[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
201
+
202
+ return out;
178
203
  }
179
204
 
180
205
  /**
@@ -183,8 +208,44 @@ export class Mat4x4 {
183
208
  * @returns {Mat4x4} this
184
209
  */
185
210
  multiplyInPlace(m) {
186
- const result = this.multiply(m);
187
- this.data.set(result.data);
211
+ const a = this.data;
212
+ const b = m.data;
213
+
214
+ // Cache values to avoid aliasing issues and repeated array access
215
+ const a00 = a[0], a01 = a[4], a02 = a[8], a03 = a[12];
216
+ const a10 = a[1], a11 = a[5], a12 = a[9], a13 = a[13];
217
+ const a20 = a[2], a21 = a[6], a22 = a[10], a23 = a[14];
218
+ const a30 = a[3], a31 = a[7], a32 = a[11], a33 = a[15];
219
+
220
+ const b00 = b[0], b01 = b[4], b02 = b[8], b03 = b[12];
221
+ const b10 = b[1], b11 = b[5], b12 = b[9], b13 = b[13];
222
+ const b20 = b[2], b21 = b[6], b22 = b[10], b23 = b[14];
223
+ const b30 = b[3], b31 = b[7], b32 = b[11], b33 = b[15];
224
+
225
+ // Column 0
226
+ a[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
227
+ a[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
228
+ a[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
229
+ a[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
230
+
231
+ // Column 1
232
+ a[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
233
+ a[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
234
+ a[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
235
+ a[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
236
+
237
+ // Column 2
238
+ a[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
239
+ a[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
240
+ a[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
241
+ a[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
242
+
243
+ // Column 3
244
+ a[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
245
+ a[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
246
+ a[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
247
+ a[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
248
+
188
249
  return this;
189
250
  }
190
251
 
@@ -202,16 +263,22 @@ export class Mat4x4 {
202
263
  /**
203
264
  * Transform a Vec4 by this matrix
204
265
  * @param {Vec4} v
266
+ * @param {Vec4} [target=null] - Optional target vector to store result
205
267
  * @returns {Vec4} Transformed vector
206
268
  */
207
- multiplyVec4(v) {
269
+ multiplyVec4(v, target = null) {
208
270
  const m = this.data;
209
- return new Vec4(
210
- m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12] * v.w,
211
- m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13] * v.w,
212
- m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14] * v.w,
213
- m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15] * v.w
214
- );
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;
215
282
  }
216
283
 
217
284
  /**
@@ -253,41 +320,57 @@ export class Mat4x4 {
253
320
  /**
254
321
  * Add another matrix
255
322
  * @param {Mat4x4} m
323
+ * @param {Mat4x4} [target=null] - Optional target matrix
256
324
  * @returns {Mat4x4} New matrix
257
325
  */
258
- add(m) {
259
- 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
+
260
332
  for (let i = 0; i < 16; i++) {
261
- result[i] = this.data[i] + m.data[i];
333
+ r[i] = a[i] + b[i];
262
334
  }
263
- return new Mat4x4(result);
335
+ return out;
264
336
  }
265
337
 
266
338
  /**
267
339
  * Multiply by scalar
268
340
  * @param {number} s
341
+ * @param {Mat4x4} [target=null] - Optional target matrix
269
342
  * @returns {Mat4x4} New matrix
270
343
  */
271
- scale(s) {
272
- 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
+
273
349
  for (let i = 0; i < 16; i++) {
274
- result[i] = this.data[i] * s;
350
+ r[i] = a[i] * s;
275
351
  }
276
- return new Mat4x4(result);
352
+ return out;
277
353
  }
278
354
 
279
355
  /**
280
356
  * Transpose matrix
357
+ * @param {Mat4x4} [target=null] - Optional target matrix
281
358
  * @returns {Mat4x4} New transposed matrix
282
359
  */
283
- transpose() {
360
+ transpose(target = null) {
284
361
  const m = this.data;
285
- return new Mat4x4([
286
- m[0], m[4], m[8], m[12],
287
- m[1], m[5], m[9], m[13],
288
- m[2], m[6], m[10], m[14],
289
- m[3], m[7], m[11], m[15]
290
- ]);
362
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
363
+ const r = out.data;
364
+ // If target is same as source, use intermediate or careful swap
365
+ if (target === this) {
366
+ return this.transposeInPlace();
367
+ }
368
+
369
+ r[0] = m[0]; r[4] = m[1]; r[8] = m[2]; r[12] = m[3];
370
+ r[1] = m[4]; r[5] = m[5]; r[9] = m[6]; r[13] = m[7];
371
+ r[2] = m[8]; r[6] = m[9]; r[10] = m[10]; r[14] = m[11];
372
+ r[3] = m[12]; r[7] = m[13]; r[11] = m[14]; r[15] = m[15];
373
+ return out;
291
374
  }
292
375
 
293
376
  /**
@@ -338,61 +421,85 @@ export class Mat4x4 {
338
421
 
339
422
  /**
340
423
  * Calculate inverse matrix
424
+ * @param {Mat4x4} [target=null] - Optional target matrix
341
425
  * @returns {Mat4x4|null} Inverse matrix or null if singular
342
426
  */
343
- inverse() {
427
+ inverse(target = null) {
344
428
  const m = this.data;
345
- const inv = new Float32Array(16);
429
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
430
+ const inv = out.data;
431
+
432
+ // Note: For in-place inversion (target === this), we need to be careful.
433
+ // The standard algorithm uses input values for every output cell.
434
+ // We can check for aliasing or use local variables if we wanted full safety,
435
+ // but simplest is to compute to temp if aliased, or just computing to the array directly works
436
+ // IF we cache everything first. But here we are writing to `inv` index by index.
437
+ // If inv === m, writing inv[0] destroys m[0] which is needed for inv[5] etc.
438
+ // So aliasing is NOT safe with this direct write approach.
439
+
440
+ // Handle aliasing by cloning first if needed, or using temp array.
441
+ // Since we want performance, let's detect aliasing.
442
+ let sourceData = m;
443
+ if (target === this) {
444
+ // Copy source data to temp array so we can write to 'this.data' safely
445
+ // We can't avoid allocation entirely in this specific edge case easily without unrolling everything into locals,
446
+ // which is huge for 4x4 inverse.
447
+ // Using a static temp buffer would be unsafe for threading/recursion (not an issue in JS single thread usually but still).
448
+ // Let's just clone the source data for the calculation.
449
+ sourceData = new Float32Array(m);
450
+ }
451
+
452
+ const s = sourceData;
346
453
 
347
- inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
348
- m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
454
+ inv[0] = s[5] * s[10] * s[15] - s[5] * s[11] * s[14] - s[9] * s[6] * s[15] +
455
+ s[9] * s[7] * s[14] + s[13] * s[6] * s[11] - s[13] * s[7] * s[10];
349
456
 
350
- inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] -
351
- m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
457
+ inv[4] = -s[4] * s[10] * s[15] + s[4] * s[11] * s[14] + s[8] * s[6] * s[15] -
458
+ s[8] * s[7] * s[14] - s[12] * s[6] * s[11] + s[12] * s[7] * s[10];
352
459
 
353
- inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] +
354
- m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
460
+ inv[8] = s[4] * s[9] * s[15] - s[4] * s[11] * s[13] - s[8] * s[5] * s[15] +
461
+ s[8] * s[7] * s[13] + s[12] * s[5] * s[11] - s[12] * s[7] * s[9];
355
462
 
356
- inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] -
357
- m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
463
+ inv[12] = -s[4] * s[9] * s[14] + s[4] * s[10] * s[13] + s[8] * s[5] * s[14] -
464
+ s[8] * s[6] * s[13] - s[12] * s[5] * s[10] + s[12] * s[6] * s[9];
358
465
 
359
- inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] -
360
- m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
466
+ inv[1] = -s[1] * s[10] * s[15] + s[1] * s[11] * s[14] + s[9] * s[2] * s[15] -
467
+ s[9] * s[3] * s[14] - s[13] * s[2] * s[11] + s[13] * s[3] * s[10];
361
468
 
362
- inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] +
363
- m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
469
+ inv[5] = s[0] * s[10] * s[15] - s[0] * s[11] * s[14] - s[8] * s[2] * s[15] +
470
+ s[8] * s[3] * s[14] + s[12] * s[2] * s[11] - s[12] * s[3] * s[10];
364
471
 
365
- inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] -
366
- m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
472
+ inv[9] = -s[0] * s[9] * s[15] + s[0] * s[11] * s[13] + s[8] * s[1] * s[15] -
473
+ s[8] * s[3] * s[13] - s[12] * s[1] * s[11] + s[12] * s[3] * s[9];
367
474
 
368
- inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] +
369
- m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
475
+ inv[13] = s[0] * s[9] * s[14] - s[0] * s[10] * s[13] - s[8] * s[1] * s[14] +
476
+ s[8] * s[2] * s[13] + s[12] * s[1] * s[10] - s[12] * s[2] * s[9];
370
477
 
371
- inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] +
372
- m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
478
+ inv[2] = s[1] * s[6] * s[15] - s[1] * s[7] * s[14] - s[5] * s[2] * s[15] +
479
+ s[5] * s[3] * s[14] + s[13] * s[2] * s[7] - s[13] * s[3] * s[6];
373
480
 
374
- inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] -
375
- m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
481
+ inv[6] = -s[0] * s[6] * s[15] + s[0] * s[7] * s[14] + s[4] * s[2] * s[15] -
482
+ s[4] * s[3] * s[14] - s[12] * s[2] * s[7] + s[12] * s[3] * s[6];
376
483
 
377
- inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] +
378
- m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
484
+ inv[10] = s[0] * s[5] * s[15] - s[0] * s[7] * s[13] - s[4] * s[1] * s[15] +
485
+ s[4] * s[3] * s[13] + s[12] * s[1] * s[7] - s[12] * s[3] * s[5];
379
486
 
380
- inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] -
381
- m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
487
+ inv[14] = -s[0] * s[5] * s[14] + s[0] * s[6] * s[13] + s[4] * s[1] * s[14] -
488
+ s[4] * s[2] * s[13] - s[12] * s[1] * s[6] + s[12] * s[2] * s[5];
382
489
 
383
- inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] -
384
- m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
490
+ inv[3] = -s[1] * s[6] * s[11] + s[1] * s[7] * s[10] + s[5] * s[2] * s[11] -
491
+ s[5] * s[3] * s[10] - s[9] * s[2] * s[7] + s[9] * s[3] * s[6];
385
492
 
386
- inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] +
387
- m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
493
+ inv[7] = s[0] * s[6] * s[11] - s[0] * s[7] * s[10] - s[4] * s[2] * s[11] +
494
+ s[4] * s[3] * s[10] + s[8] * s[2] * s[7] - s[8] * s[3] * s[6];
388
495
 
389
- inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] -
390
- m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
496
+ inv[11] = -s[0] * s[5] * s[11] + s[0] * s[7] * s[9] + s[4] * s[1] * s[11] -
497
+ s[4] * s[3] * s[9] - s[8] * s[1] * s[7] + s[8] * s[3] * s[5];
391
498
 
392
- inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] +
393
- m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
499
+ inv[15] = s[0] * s[5] * s[10] - s[0] * s[6] * s[9] - s[4] * s[1] * s[10] +
500
+ s[4] * s[2] * s[9] + s[8] * s[1] * s[6] - s[8] * s[2] * s[5];
394
501
 
395
- const det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
502
+ const det = s[0] * inv[0] + s[1] * inv[4] + s[2] * inv[8] + s[3] * inv[12];
396
503
 
397
504
  if (Math.abs(det) < 1e-10) {
398
505
  return null; // Singular matrix
@@ -403,7 +510,7 @@ export class Mat4x4 {
403
510
  inv[i] *= invDet;
404
511
  }
405
512
 
406
- return new Mat4x4(inv);
513
+ return out;
407
514
  }
408
515
 
409
516
  /**
@@ -490,6 +597,122 @@ export class Mat4x4 {
490
597
  return new Mat4x4(json.data);
491
598
  }
492
599
 
600
+ // ========== IN-PLACE ROTATIONS ==========
601
+
602
+ /**
603
+ * Rotate in XY plane in place
604
+ * @param {number} angle
605
+ * @returns {Mat4x4} this
606
+ */
607
+ rotateXY(angle) {
608
+ const c = Math.cos(angle);
609
+ const s = Math.sin(angle);
610
+ const m = this.data;
611
+
612
+ for (let i = 0; i < 4; i++) {
613
+ const a0 = m[i]; // Col 0
614
+ const a1 = m[i + 4]; // Col 1
615
+ m[i] = a0 * c + a1 * s;
616
+ m[i + 4] = -a0 * s + a1 * c;
617
+ }
618
+ return this;
619
+ }
620
+
621
+ /**
622
+ * Rotate in XZ plane in place
623
+ * @param {number} angle
624
+ * @returns {Mat4x4} this
625
+ */
626
+ rotateXZ(angle) {
627
+ const c = Math.cos(angle);
628
+ const s = Math.sin(angle);
629
+ const m = this.data;
630
+
631
+ for (let i = 0; i < 4; i++) {
632
+ const a0 = m[i]; // Col 0
633
+ const a2 = m[i + 8]; // Col 2
634
+ m[i] = a0 * c - a2 * s;
635
+ m[i + 8] = a0 * s + a2 * c;
636
+ }
637
+ return this;
638
+ }
639
+
640
+ /**
641
+ * Rotate in YZ plane in place
642
+ * @param {number} angle
643
+ * @returns {Mat4x4} this
644
+ */
645
+ rotateYZ(angle) {
646
+ const c = Math.cos(angle);
647
+ const s = Math.sin(angle);
648
+ const m = this.data;
649
+
650
+ for (let i = 0; i < 4; i++) {
651
+ const a1 = m[i + 4]; // Col 1
652
+ const a2 = m[i + 8]; // Col 2
653
+ m[i + 4] = a1 * c + a2 * s;
654
+ m[i + 8] = -a1 * s + a2 * c;
655
+ }
656
+ return this;
657
+ }
658
+
659
+ /**
660
+ * Rotate in XW plane in place
661
+ * @param {number} angle
662
+ * @returns {Mat4x4} this
663
+ */
664
+ rotateXW(angle) {
665
+ const c = Math.cos(angle);
666
+ const s = Math.sin(angle);
667
+ const m = this.data;
668
+
669
+ for (let i = 0; i < 4; i++) {
670
+ const a0 = m[i]; // Col 0
671
+ const a3 = m[i + 12]; // Col 3
672
+ m[i] = a0 * c + a3 * s;
673
+ m[i + 12] = -a0 * s + a3 * c;
674
+ }
675
+ return this;
676
+ }
677
+
678
+ /**
679
+ * Rotate in YW plane in place
680
+ * @param {number} angle
681
+ * @returns {Mat4x4} this
682
+ */
683
+ rotateYW(angle) {
684
+ const c = Math.cos(angle);
685
+ const s = Math.sin(angle);
686
+ const m = this.data;
687
+
688
+ for (let i = 0; i < 4; i++) {
689
+ const a1 = m[i + 4]; // Col 1
690
+ const a3 = m[i + 12]; // Col 3
691
+ m[i + 4] = a1 * c + a3 * s;
692
+ m[i + 12] = -a1 * s + a3 * c;
693
+ }
694
+ return this;
695
+ }
696
+
697
+ /**
698
+ * Rotate in ZW plane in place
699
+ * @param {number} angle
700
+ * @returns {Mat4x4} this
701
+ */
702
+ rotateZW(angle) {
703
+ const c = Math.cos(angle);
704
+ const s = Math.sin(angle);
705
+ const m = this.data;
706
+
707
+ for (let i = 0; i < 4; i++) {
708
+ const a2 = m[i + 8]; // Col 2
709
+ const a3 = m[i + 12]; // Col 3
710
+ m[i + 8] = a2 * c + a3 * s;
711
+ m[i + 12] = -a2 * s + a3 * c;
712
+ }
713
+ return this;
714
+ }
715
+
493
716
  // ========== ROTATION MATRICES FOR ALL 6 PLANES ==========
494
717
 
495
718
  /**
@@ -500,12 +723,13 @@ export class Mat4x4 {
500
723
  static rotationXY(angle) {
501
724
  const c = Math.cos(angle);
502
725
  const s = Math.sin(angle);
503
- return new Mat4x4([
504
- c, s, 0, 0,
505
- -s, c, 0, 0,
506
- 0, 0, 1, 0,
507
- 0, 0, 0, 1
508
- ]);
726
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
727
+ const r = out.data;
728
+ r[0] = c; r[1] = s;
729
+ r[4] = -s; r[5] = c;
730
+ r[10] = 1;
731
+ r[15] = 1;
732
+ return out;
509
733
  }
510
734
 
511
735
  /**
@@ -516,12 +740,13 @@ export class Mat4x4 {
516
740
  static rotationXZ(angle) {
517
741
  const c = Math.cos(angle);
518
742
  const s = Math.sin(angle);
519
- return new Mat4x4([
520
- c, 0, -s, 0,
521
- 0, 1, 0, 0,
522
- s, 0, c, 0,
523
- 0, 0, 0, 1
524
- ]);
743
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
744
+ const r = out.data;
745
+ r[0] = c; r[2] = -s;
746
+ r[5] = 1;
747
+ r[8] = s; r[10] = c;
748
+ r[15] = 1;
749
+ return out;
525
750
  }
526
751
 
527
752
  /**
@@ -532,12 +757,13 @@ export class Mat4x4 {
532
757
  static rotationYZ(angle) {
533
758
  const c = Math.cos(angle);
534
759
  const s = Math.sin(angle);
535
- return new Mat4x4([
536
- 1, 0, 0, 0,
537
- 0, c, s, 0,
538
- 0, -s, c, 0,
539
- 0, 0, 0, 1
540
- ]);
760
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
761
+ const r = out.data;
762
+ r[0] = 1;
763
+ r[5] = c; r[6] = s;
764
+ r[9] = -s; r[10] = c;
765
+ r[15] = 1;
766
+ return out;
541
767
  }
542
768
 
543
769
  /**
@@ -549,12 +775,13 @@ export class Mat4x4 {
549
775
  static rotationXW(angle) {
550
776
  const c = Math.cos(angle);
551
777
  const s = Math.sin(angle);
552
- return new Mat4x4([
553
- c, 0, 0, s,
554
- 0, 1, 0, 0,
555
- 0, 0, 1, 0,
556
- -s, 0, 0, c
557
- ]);
778
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
779
+ const r = out.data;
780
+ r[0] = c; r[3] = s;
781
+ r[5] = 1;
782
+ r[10] = 1;
783
+ r[12] = -s; r[15] = c;
784
+ return out;
558
785
  }
559
786
 
560
787
  /**
@@ -565,12 +792,13 @@ export class Mat4x4 {
565
792
  static rotationYW(angle) {
566
793
  const c = Math.cos(angle);
567
794
  const s = Math.sin(angle);
568
- return new Mat4x4([
569
- 1, 0, 0, 0,
570
- 0, c, 0, s,
571
- 0, 0, 1, 0,
572
- 0, -s, 0, c
573
- ]);
795
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
796
+ const r = out.data;
797
+ r[0] = 1;
798
+ r[5] = c; r[7] = s;
799
+ r[10] = 1;
800
+ r[13] = -s; r[15] = c;
801
+ return out;
574
802
  }
575
803
 
576
804
  /**
@@ -581,12 +809,13 @@ export class Mat4x4 {
581
809
  static rotationZW(angle) {
582
810
  const c = Math.cos(angle);
583
811
  const s = Math.sin(angle);
584
- return new Mat4x4([
585
- 1, 0, 0, 0,
586
- 0, 1, 0, 0,
587
- 0, 0, c, s,
588
- 0, 0, -s, c
589
- ]);
812
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
813
+ const r = out.data;
814
+ r[0] = 1;
815
+ r[5] = 1;
816
+ r[10] = c; r[11] = s;
817
+ r[14] = -s; r[15] = c;
818
+ return out;
590
819
  }
591
820
 
592
821
  /**
@@ -624,12 +853,12 @@ export class Mat4x4 {
624
853
  static rotationFromAngles(angles) {
625
854
  let result = Mat4x4.identity();
626
855
 
627
- if (angles.xy) result = result.multiply(Mat4x4.rotationXY(angles.xy));
628
- if (angles.xz) result = result.multiply(Mat4x4.rotationXZ(angles.xz));
629
- if (angles.yz) result = result.multiply(Mat4x4.rotationYZ(angles.yz));
630
- if (angles.xw) result = result.multiply(Mat4x4.rotationXW(angles.xw));
631
- if (angles.yw) result = result.multiply(Mat4x4.rotationYW(angles.yw));
632
- if (angles.zw) result = result.multiply(Mat4x4.rotationZW(angles.zw));
856
+ if (angles.xy) result.rotateXY(angles.xy);
857
+ if (angles.xz) result.rotateXZ(angles.xz);
858
+ if (angles.yz) result.rotateYZ(angles.yz);
859
+ if (angles.xw) result.rotateXW(angles.xw);
860
+ if (angles.yw) result.rotateYW(angles.yw);
861
+ if (angles.zw) result.rotateZW(angles.zw);
633
862
 
634
863
  return result;
635
864
  }
@@ -658,12 +887,13 @@ export class Mat4x4 {
658
887
  * @returns {Mat4x4}
659
888
  */
660
889
  static uniformScale(s) {
661
- return new Mat4x4([
662
- s, 0, 0, 0,
663
- 0, s, 0, 0,
664
- 0, 0, s, 0,
665
- 0, 0, 0, s
666
- ]);
890
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
891
+ const r = out.data;
892
+ r[0] = s;
893
+ r[5] = s;
894
+ r[10] = s;
895
+ r[15] = s;
896
+ return out;
667
897
  }
668
898
 
669
899
  /**
@@ -675,12 +905,13 @@ export class Mat4x4 {
675
905
  * @returns {Mat4x4}
676
906
  */
677
907
  static scale(sx, sy, sz, sw = 1) {
678
- return new Mat4x4([
679
- sx, 0, 0, 0,
680
- 0, sy, 0, 0,
681
- 0, 0, sz, 0,
682
- 0, 0, 0, sw
683
- ]);
908
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
909
+ const r = out.data;
910
+ r[0] = sx;
911
+ r[5] = sy;
912
+ r[10] = sz;
913
+ r[15] = sw;
914
+ return out;
684
915
  }
685
916
 
686
917
  /**
@@ -696,12 +927,13 @@ export class Mat4x4 {
696
927
  static translation(tx, ty, tz, tw = 0) {
697
928
  // For true 4D translation, you need 5D homogeneous coordinates
698
929
  // This is a placeholder that adds the translation to the W column
699
- return new Mat4x4([
700
- 1, 0, 0, 0,
701
- 0, 1, 0, 0,
702
- 0, 0, 1, 0,
703
- tx, ty, tz, 1 + tw
704
- ]);
930
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
931
+ const r = out.data;
932
+ r[0] = 1;
933
+ r[5] = 1;
934
+ r[10] = 1;
935
+ r[12] = tx; r[13] = ty; r[14] = tz; r[15] = 1 + tw;
936
+ return out;
705
937
  }
706
938
  }
707
939