@vib3code/sdk 2.0.3-canary.91a95f3 → 2.0.3-canary.ae15579

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 +488 -155
  86. package/src/math/Projection.js +57 -7
  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');
@@ -40,17 +48,25 @@ export class Mat4x4 {
40
48
  }
41
49
  }
42
50
 
51
+ /**
52
+ * Reset to identity matrix
53
+ * @returns {Mat4x4} this
54
+ */
55
+ identity() {
56
+ const d = this.data;
57
+ d[0] = 1; d[1] = 0; d[2] = 0; d[3] = 0;
58
+ d[4] = 0; d[5] = 1; d[6] = 0; d[7] = 0;
59
+ d[8] = 0; d[9] = 0; d[10] = 1; d[11] = 0;
60
+ d[12] = 0; d[13] = 0; d[14] = 0; d[15] = 1;
61
+ return this;
62
+ }
63
+
43
64
  /**
44
65
  * Create identity matrix
45
66
  * @returns {Mat4x4}
46
67
  */
47
68
  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
- ]);
69
+ return new Mat4x4();
54
70
  }
55
71
 
56
72
  /**
@@ -58,7 +74,7 @@ export class Mat4x4 {
58
74
  * @returns {Mat4x4}
59
75
  */
60
76
  static zero() {
61
- return new Mat4x4(new Float32Array(16));
77
+ return new Mat4x4(Mat4x4.UNINITIALIZED);
62
78
  }
63
79
 
64
80
  /**
@@ -157,24 +173,46 @@ export class Mat4x4 {
157
173
  /**
158
174
  * Multiply two matrices
159
175
  * @param {Mat4x4} m - Right operand
176
+ * @param {Mat4x4} [target=null] - Optional target matrix to store result
160
177
  * @returns {Mat4x4} New matrix = this * m
161
178
  */
162
- multiply(m) {
179
+ multiply(m, target = null) {
180
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
181
+ const r = out.data;
163
182
  const a = this.data;
164
183
  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
184
 
177
- return new Mat4x4(result);
185
+ const a00 = a[0], a01 = a[4], a02 = a[8], a03 = a[12];
186
+ const a10 = a[1], a11 = a[5], a12 = a[9], a13 = a[13];
187
+ const a20 = a[2], a21 = a[6], a22 = a[10], a23 = a[14];
188
+ const a30 = a[3], a31 = a[7], a32 = a[11], a33 = a[15];
189
+
190
+ const b00 = b[0], b01 = b[4], b02 = b[8], b03 = b[12];
191
+ const b10 = b[1], b11 = b[5], b12 = b[9], b13 = b[13];
192
+ const b20 = b[2], b21 = b[6], b22 = b[10], b23 = b[14];
193
+ const b30 = b[3], b31 = b[7], b32 = b[11], b33 = b[15];
194
+
195
+ r[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
196
+ r[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
197
+ r[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
198
+ r[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
199
+
200
+ r[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
201
+ r[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
202
+ r[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
203
+ r[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
204
+
205
+ r[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
206
+ r[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
207
+ r[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
208
+ r[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
209
+
210
+ r[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
211
+ r[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
212
+ r[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
213
+ r[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
214
+
215
+ return out;
178
216
  }
179
217
 
180
218
  /**
@@ -183,8 +221,44 @@ export class Mat4x4 {
183
221
  * @returns {Mat4x4} this
184
222
  */
185
223
  multiplyInPlace(m) {
186
- const result = this.multiply(m);
187
- this.data.set(result.data);
224
+ const a = this.data;
225
+ const b = m.data;
226
+
227
+ // Cache values to avoid aliasing issues and repeated array access
228
+ const a00 = a[0], a01 = a[4], a02 = a[8], a03 = a[12];
229
+ const a10 = a[1], a11 = a[5], a12 = a[9], a13 = a[13];
230
+ const a20 = a[2], a21 = a[6], a22 = a[10], a23 = a[14];
231
+ const a30 = a[3], a31 = a[7], a32 = a[11], a33 = a[15];
232
+
233
+ const b00 = b[0], b01 = b[4], b02 = b[8], b03 = b[12];
234
+ const b10 = b[1], b11 = b[5], b12 = b[9], b13 = b[13];
235
+ const b20 = b[2], b21 = b[6], b22 = b[10], b23 = b[14];
236
+ const b30 = b[3], b31 = b[7], b32 = b[11], b33 = b[15];
237
+
238
+ // Column 0
239
+ a[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
240
+ a[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
241
+ a[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
242
+ a[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
243
+
244
+ // Column 1
245
+ a[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
246
+ a[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
247
+ a[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
248
+ a[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
249
+
250
+ // Column 2
251
+ a[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
252
+ a[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
253
+ a[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
254
+ a[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
255
+
256
+ // Column 3
257
+ a[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
258
+ a[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
259
+ a[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
260
+ a[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
261
+
188
262
  return this;
189
263
  }
190
264
 
@@ -202,16 +276,22 @@ export class Mat4x4 {
202
276
  /**
203
277
  * Transform a Vec4 by this matrix
204
278
  * @param {Vec4} v
279
+ * @param {Vec4} [target=null] - Optional target vector to store result
205
280
  * @returns {Vec4} Transformed vector
206
281
  */
207
- multiplyVec4(v) {
282
+ multiplyVec4(v, target = null) {
208
283
  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
- );
284
+ const out = target || new Vec4();
285
+
286
+ // Cache components to support aliasing (target === v)
287
+ const x = v.x, y = v.y, z = v.z, w = v.w;
288
+
289
+ out.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
290
+ out.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
291
+ out.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
292
+ out.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
293
+
294
+ return out;
215
295
  }
216
296
 
217
297
  /**
@@ -253,41 +333,57 @@ export class Mat4x4 {
253
333
  /**
254
334
  * Add another matrix
255
335
  * @param {Mat4x4} m
336
+ * @param {Mat4x4} [target=null] - Optional target matrix
256
337
  * @returns {Mat4x4} New matrix
257
338
  */
258
- add(m) {
259
- const result = new Float32Array(16);
339
+ add(m, target = null) {
340
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
341
+ const r = out.data;
342
+ const a = this.data;
343
+ const b = m.data;
344
+
260
345
  for (let i = 0; i < 16; i++) {
261
- result[i] = this.data[i] + m.data[i];
346
+ r[i] = a[i] + b[i];
262
347
  }
263
- return new Mat4x4(result);
348
+ return out;
264
349
  }
265
350
 
266
351
  /**
267
352
  * Multiply by scalar
268
353
  * @param {number} s
354
+ * @param {Mat4x4} [target=null] - Optional target matrix
269
355
  * @returns {Mat4x4} New matrix
270
356
  */
271
- scale(s) {
272
- const result = new Float32Array(16);
357
+ scale(s, target = null) {
358
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
359
+ const r = out.data;
360
+ const a = this.data;
361
+
273
362
  for (let i = 0; i < 16; i++) {
274
- result[i] = this.data[i] * s;
363
+ r[i] = a[i] * s;
275
364
  }
276
- return new Mat4x4(result);
365
+ return out;
277
366
  }
278
367
 
279
368
  /**
280
369
  * Transpose matrix
370
+ * @param {Mat4x4} [target=null] - Optional target matrix
281
371
  * @returns {Mat4x4} New transposed matrix
282
372
  */
283
- transpose() {
373
+ transpose(target = null) {
284
374
  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
- ]);
375
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
376
+ const r = out.data;
377
+ // If target is same as source, use intermediate or careful swap
378
+ if (target === this) {
379
+ return this.transposeInPlace();
380
+ }
381
+
382
+ r[0] = m[0]; r[4] = m[1]; r[8] = m[2]; r[12] = m[3];
383
+ r[1] = m[4]; r[5] = m[5]; r[9] = m[6]; r[13] = m[7];
384
+ r[2] = m[8]; r[6] = m[9]; r[10] = m[10]; r[14] = m[11];
385
+ r[3] = m[12]; r[7] = m[13]; r[11] = m[14]; r[15] = m[15];
386
+ return out;
291
387
  }
292
388
 
293
389
  /**
@@ -338,61 +434,85 @@ export class Mat4x4 {
338
434
 
339
435
  /**
340
436
  * Calculate inverse matrix
437
+ * @param {Mat4x4} [target=null] - Optional target matrix
341
438
  * @returns {Mat4x4|null} Inverse matrix or null if singular
342
439
  */
343
- inverse() {
440
+ inverse(target = null) {
344
441
  const m = this.data;
345
- const inv = new Float32Array(16);
442
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
443
+ const inv = out.data;
444
+
445
+ // Note: For in-place inversion (target === this), we need to be careful.
446
+ // The standard algorithm uses input values for every output cell.
447
+ // We can check for aliasing or use local variables if we wanted full safety,
448
+ // but simplest is to compute to temp if aliased, or just computing to the array directly works
449
+ // IF we cache everything first. But here we are writing to `inv` index by index.
450
+ // If inv === m, writing inv[0] destroys m[0] which is needed for inv[5] etc.
451
+ // So aliasing is NOT safe with this direct write approach.
452
+
453
+ // Handle aliasing by cloning first if needed, or using temp array.
454
+ // Since we want performance, let's detect aliasing.
455
+ let sourceData = m;
456
+ if (target === this) {
457
+ // Copy source data to temp array so we can write to 'this.data' safely
458
+ // We can't avoid allocation entirely in this specific edge case easily without unrolling everything into locals,
459
+ // which is huge for 4x4 inverse.
460
+ // Using a static temp buffer would be unsafe for threading/recursion (not an issue in JS single thread usually but still).
461
+ // Let's just clone the source data for the calculation.
462
+ sourceData = new Float32Array(m);
463
+ }
464
+
465
+ const s = sourceData;
346
466
 
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];
467
+ inv[0] = s[5] * s[10] * s[15] - s[5] * s[11] * s[14] - s[9] * s[6] * s[15] +
468
+ s[9] * s[7] * s[14] + s[13] * s[6] * s[11] - s[13] * s[7] * s[10];
349
469
 
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];
470
+ inv[4] = -s[4] * s[10] * s[15] + s[4] * s[11] * s[14] + s[8] * s[6] * s[15] -
471
+ s[8] * s[7] * s[14] - s[12] * s[6] * s[11] + s[12] * s[7] * s[10];
352
472
 
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];
473
+ inv[8] = s[4] * s[9] * s[15] - s[4] * s[11] * s[13] - s[8] * s[5] * s[15] +
474
+ s[8] * s[7] * s[13] + s[12] * s[5] * s[11] - s[12] * s[7] * s[9];
355
475
 
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];
476
+ inv[12] = -s[4] * s[9] * s[14] + s[4] * s[10] * s[13] + s[8] * s[5] * s[14] -
477
+ s[8] * s[6] * s[13] - s[12] * s[5] * s[10] + s[12] * s[6] * s[9];
358
478
 
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];
479
+ inv[1] = -s[1] * s[10] * s[15] + s[1] * s[11] * s[14] + s[9] * s[2] * s[15] -
480
+ s[9] * s[3] * s[14] - s[13] * s[2] * s[11] + s[13] * s[3] * s[10];
361
481
 
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];
482
+ inv[5] = s[0] * s[10] * s[15] - s[0] * s[11] * s[14] - s[8] * s[2] * s[15] +
483
+ s[8] * s[3] * s[14] + s[12] * s[2] * s[11] - s[12] * s[3] * s[10];
364
484
 
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];
485
+ inv[9] = -s[0] * s[9] * s[15] + s[0] * s[11] * s[13] + s[8] * s[1] * s[15] -
486
+ s[8] * s[3] * s[13] - s[12] * s[1] * s[11] + s[12] * s[3] * s[9];
367
487
 
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];
488
+ inv[13] = s[0] * s[9] * s[14] - s[0] * s[10] * s[13] - s[8] * s[1] * s[14] +
489
+ s[8] * s[2] * s[13] + s[12] * s[1] * s[10] - s[12] * s[2] * s[9];
370
490
 
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];
491
+ inv[2] = s[1] * s[6] * s[15] - s[1] * s[7] * s[14] - s[5] * s[2] * s[15] +
492
+ s[5] * s[3] * s[14] + s[13] * s[2] * s[7] - s[13] * s[3] * s[6];
373
493
 
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];
494
+ inv[6] = -s[0] * s[6] * s[15] + s[0] * s[7] * s[14] + s[4] * s[2] * s[15] -
495
+ s[4] * s[3] * s[14] - s[12] * s[2] * s[7] + s[12] * s[3] * s[6];
376
496
 
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];
497
+ inv[10] = s[0] * s[5] * s[15] - s[0] * s[7] * s[13] - s[4] * s[1] * s[15] +
498
+ s[4] * s[3] * s[13] + s[12] * s[1] * s[7] - s[12] * s[3] * s[5];
379
499
 
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];
500
+ inv[14] = -s[0] * s[5] * s[14] + s[0] * s[6] * s[13] + s[4] * s[1] * s[14] -
501
+ s[4] * s[2] * s[13] - s[12] * s[1] * s[6] + s[12] * s[2] * s[5];
382
502
 
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];
503
+ inv[3] = -s[1] * s[6] * s[11] + s[1] * s[7] * s[10] + s[5] * s[2] * s[11] -
504
+ s[5] * s[3] * s[10] - s[9] * s[2] * s[7] + s[9] * s[3] * s[6];
385
505
 
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];
506
+ inv[7] = s[0] * s[6] * s[11] - s[0] * s[7] * s[10] - s[4] * s[2] * s[11] +
507
+ s[4] * s[3] * s[10] + s[8] * s[2] * s[7] - s[8] * s[3] * s[6];
388
508
 
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];
509
+ inv[11] = -s[0] * s[5] * s[11] + s[0] * s[7] * s[9] + s[4] * s[1] * s[11] -
510
+ s[4] * s[3] * s[9] - s[8] * s[1] * s[7] + s[8] * s[3] * s[5];
391
511
 
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];
512
+ inv[15] = s[0] * s[5] * s[10] - s[0] * s[6] * s[9] - s[4] * s[1] * s[10] +
513
+ s[4] * s[2] * s[9] + s[8] * s[1] * s[6] - s[8] * s[2] * s[5];
394
514
 
395
- const det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
515
+ const det = s[0] * inv[0] + s[1] * inv[4] + s[2] * inv[8] + s[3] * inv[12];
396
516
 
397
517
  if (Math.abs(det) < 1e-10) {
398
518
  return null; // Singular matrix
@@ -403,7 +523,7 @@ export class Mat4x4 {
403
523
  inv[i] *= invDet;
404
524
  }
405
525
 
406
- return new Mat4x4(inv);
526
+ return out;
407
527
  }
408
528
 
409
529
  /**
@@ -490,103 +610,279 @@ export class Mat4x4 {
490
610
  return new Mat4x4(json.data);
491
611
  }
492
612
 
613
+ // ========== IN-PLACE ROTATIONS ==========
614
+
615
+ /**
616
+ * Rotate in XY plane in place
617
+ * @param {number} angle
618
+ * @returns {Mat4x4} this
619
+ */
620
+ rotateXY(angle) {
621
+ const c = Math.cos(angle);
622
+ const s = Math.sin(angle);
623
+ const m = this.data;
624
+
625
+ for (let i = 0; i < 4; i++) {
626
+ const a0 = m[i]; // Col 0
627
+ const a1 = m[i + 4]; // Col 1
628
+ m[i] = a0 * c + a1 * s;
629
+ m[i + 4] = -a0 * s + a1 * c;
630
+ }
631
+ return this;
632
+ }
633
+
634
+ /**
635
+ * Rotate in XZ plane in place
636
+ * @param {number} angle
637
+ * @returns {Mat4x4} this
638
+ */
639
+ rotateXZ(angle) {
640
+ const c = Math.cos(angle);
641
+ const s = Math.sin(angle);
642
+ const m = this.data;
643
+
644
+ for (let i = 0; i < 4; i++) {
645
+ const a0 = m[i]; // Col 0
646
+ const a2 = m[i + 8]; // Col 2
647
+ m[i] = a0 * c - a2 * s;
648
+ m[i + 8] = a0 * s + a2 * c;
649
+ }
650
+ return this;
651
+ }
652
+
653
+ /**
654
+ * Rotate in YZ plane in place
655
+ * @param {number} angle
656
+ * @returns {Mat4x4} this
657
+ */
658
+ rotateYZ(angle) {
659
+ const c = Math.cos(angle);
660
+ const s = Math.sin(angle);
661
+ const m = this.data;
662
+
663
+ for (let i = 0; i < 4; i++) {
664
+ const a1 = m[i + 4]; // Col 1
665
+ const a2 = m[i + 8]; // Col 2
666
+ m[i + 4] = a1 * c + a2 * s;
667
+ m[i + 8] = -a1 * s + a2 * c;
668
+ }
669
+ return this;
670
+ }
671
+
672
+ /**
673
+ * Rotate in XW plane in place
674
+ * @param {number} angle
675
+ * @returns {Mat4x4} this
676
+ */
677
+ rotateXW(angle) {
678
+ const c = Math.cos(angle);
679
+ const s = Math.sin(angle);
680
+ const m = this.data;
681
+
682
+ for (let i = 0; i < 4; i++) {
683
+ const a0 = m[i]; // Col 0
684
+ const a3 = m[i + 12]; // Col 3
685
+ m[i] = a0 * c + a3 * s;
686
+ m[i + 12] = -a0 * s + a3 * c;
687
+ }
688
+ return this;
689
+ }
690
+
691
+ /**
692
+ * Rotate in YW plane in place
693
+ * @param {number} angle
694
+ * @returns {Mat4x4} this
695
+ */
696
+ rotateYW(angle) {
697
+ const c = Math.cos(angle);
698
+ const s = Math.sin(angle);
699
+ const m = this.data;
700
+
701
+ for (let i = 0; i < 4; i++) {
702
+ const a1 = m[i + 4]; // Col 1
703
+ const a3 = m[i + 12]; // Col 3
704
+ m[i + 4] = a1 * c + a3 * s;
705
+ m[i + 12] = -a1 * s + a3 * c;
706
+ }
707
+ return this;
708
+ }
709
+
710
+ /**
711
+ * Rotate in ZW plane in place
712
+ * @param {number} angle
713
+ * @returns {Mat4x4} this
714
+ */
715
+ rotateZW(angle) {
716
+ const c = Math.cos(angle);
717
+ const s = Math.sin(angle);
718
+ const m = this.data;
719
+
720
+ for (let i = 0; i < 4; i++) {
721
+ const a2 = m[i + 8]; // Col 2
722
+ const a3 = m[i + 12]; // Col 3
723
+ m[i + 8] = a2 * c + a3 * s;
724
+ m[i + 12] = -a2 * s + a3 * c;
725
+ }
726
+ return this;
727
+ }
728
+
493
729
  // ========== ROTATION MATRICES FOR ALL 6 PLANES ==========
494
730
 
495
731
  /**
496
732
  * Create XY plane rotation matrix (standard Z-axis rotation in 3D)
497
733
  * @param {number} angle - Rotation angle in radians
734
+ * @param {Mat4x4} [target=null] - Optional target matrix
498
735
  * @returns {Mat4x4}
499
736
  */
500
- static rotationXY(angle) {
737
+ static rotationXY(angle, target = null) {
501
738
  const c = Math.cos(angle);
502
739
  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
- ]);
740
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
741
+ const r = out.data;
742
+
743
+ if (target) {
744
+ r[0] = c; r[1] = s; r[2] = 0; r[3] = 0;
745
+ r[4] = -s; r[5] = c; r[6] = 0; r[7] = 0;
746
+ r[8] = 0; r[9] = 0; r[10] = 1; r[11] = 0;
747
+ r[12] = 0; r[13] = 0; r[14] = 0; r[15] = 1;
748
+ } else {
749
+ r[0] = c; r[1] = s;
750
+ r[4] = -s; r[5] = c;
751
+ r[10] = 1;
752
+ r[15] = 1;
753
+ }
754
+ return out;
509
755
  }
510
756
 
511
757
  /**
512
758
  * Create XZ plane rotation matrix (standard Y-axis rotation in 3D)
513
759
  * @param {number} angle - Rotation angle in radians
760
+ * @param {Mat4x4} [target=null] - Optional target matrix
514
761
  * @returns {Mat4x4}
515
762
  */
516
- static rotationXZ(angle) {
763
+ static rotationXZ(angle, target = null) {
517
764
  const c = Math.cos(angle);
518
765
  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
- ]);
766
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
767
+ const r = out.data;
768
+
769
+ if (target) {
770
+ r[0] = c; r[1] = 0; r[2] = -s; r[3] = 0;
771
+ r[4] = 0; r[5] = 1; r[6] = 0; r[7] = 0;
772
+ r[8] = s; r[9] = 0; r[10] = c; r[11] = 0;
773
+ r[12] = 0; r[13] = 0; r[14] = 0; r[15] = 1;
774
+ } else {
775
+ r[0] = c; r[2] = -s;
776
+ r[5] = 1;
777
+ r[8] = s; r[10] = c;
778
+ r[15] = 1;
779
+ }
780
+ return out;
525
781
  }
526
782
 
527
783
  /**
528
784
  * Create YZ plane rotation matrix (standard X-axis rotation in 3D)
529
785
  * @param {number} angle - Rotation angle in radians
786
+ * @param {Mat4x4} [target=null] - Optional target matrix
530
787
  * @returns {Mat4x4}
531
788
  */
532
- static rotationYZ(angle) {
789
+ static rotationYZ(angle, target = null) {
533
790
  const c = Math.cos(angle);
534
791
  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
- ]);
792
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
793
+ const r = out.data;
794
+
795
+ if (target) {
796
+ r[0] = 1; r[1] = 0; r[2] = 0; r[3] = 0;
797
+ r[4] = 0; r[5] = c; r[6] = s; r[7] = 0;
798
+ r[8] = 0; r[9] = -s; r[10] = c; r[11] = 0;
799
+ r[12] = 0; r[13] = 0; r[14] = 0; r[15] = 1;
800
+ } else {
801
+ r[0] = 1;
802
+ r[5] = c; r[6] = s;
803
+ r[9] = -s; r[10] = c;
804
+ r[15] = 1;
805
+ }
806
+ return out;
541
807
  }
542
808
 
543
809
  /**
544
810
  * Create XW plane rotation matrix (4D hyperspace rotation)
545
811
  * Creates "inside-out" effect when w approaches viewer
546
812
  * @param {number} angle - Rotation angle in radians
813
+ * @param {Mat4x4} [target=null] - Optional target matrix
547
814
  * @returns {Mat4x4}
548
815
  */
549
- static rotationXW(angle) {
816
+ static rotationXW(angle, target = null) {
550
817
  const c = Math.cos(angle);
551
818
  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
- ]);
819
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
820
+ const r = out.data;
821
+
822
+ if (target) {
823
+ r[0] = c; r[1] = 0; r[2] = 0; r[3] = s;
824
+ r[4] = 0; r[5] = 1; r[6] = 0; r[7] = 0;
825
+ r[8] = 0; r[9] = 0; r[10] = 1; r[11] = 0;
826
+ r[12] = -s; r[13] = 0; r[14] = 0; r[15] = c;
827
+ } else {
828
+ r[0] = c; r[3] = s;
829
+ r[5] = 1;
830
+ r[10] = 1;
831
+ r[12] = -s; r[15] = c;
832
+ }
833
+ return out;
558
834
  }
559
835
 
560
836
  /**
561
837
  * Create YW plane rotation matrix (4D hyperspace rotation)
562
838
  * @param {number} angle - Rotation angle in radians
839
+ * @param {Mat4x4} [target=null] - Optional target matrix
563
840
  * @returns {Mat4x4}
564
841
  */
565
- static rotationYW(angle) {
842
+ static rotationYW(angle, target = null) {
566
843
  const c = Math.cos(angle);
567
844
  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
- ]);
845
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
846
+ const r = out.data;
847
+
848
+ if (target) {
849
+ r[0] = 1; r[1] = 0; r[2] = 0; r[3] = 0;
850
+ r[4] = 0; r[5] = c; r[6] = 0; r[7] = s;
851
+ r[8] = 0; r[9] = 0; r[10] = 1; r[11] = 0;
852
+ r[12] = 0; r[13] = -s; r[14] = 0; r[15] = c;
853
+ } else {
854
+ r[0] = 1;
855
+ r[5] = c; r[7] = s;
856
+ r[10] = 1;
857
+ r[13] = -s; r[15] = c;
858
+ }
859
+ return out;
574
860
  }
575
861
 
576
862
  /**
577
863
  * Create ZW plane rotation matrix (4D hyperspace rotation)
578
864
  * @param {number} angle - Rotation angle in radians
865
+ * @param {Mat4x4} [target=null] - Optional target matrix
579
866
  * @returns {Mat4x4}
580
867
  */
581
- static rotationZW(angle) {
868
+ static rotationZW(angle, target = null) {
582
869
  const c = Math.cos(angle);
583
870
  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
- ]);
871
+ const out = target || new Mat4x4(Mat4x4.UNINITIALIZED);
872
+ const r = out.data;
873
+
874
+ if (target) {
875
+ r[0] = 1; r[1] = 0; r[2] = 0; r[3] = 0;
876
+ r[4] = 0; r[5] = 1; r[6] = 0; r[7] = 0;
877
+ r[8] = 0; r[9] = 0; r[10] = c; r[11] = s;
878
+ r[12] = 0; r[13] = 0; r[14] = -s; r[15] = c;
879
+ } else {
880
+ r[0] = 1;
881
+ r[5] = 1;
882
+ r[10] = c; r[11] = s;
883
+ r[14] = -s; r[15] = c;
884
+ }
885
+ return out;
590
886
  }
591
887
 
592
888
  /**
@@ -612,24 +908,58 @@ export class Mat4x4 {
612
908
  * Create combined rotation matrix from all 6 angles
613
909
  * Order: XY, XZ, YZ, XW, YW, ZW
614
910
  *
615
- * @param {object} angles - Rotation angles
616
- * @param {number} [angles.xy=0] - XY plane rotation
617
- * @param {number} [angles.xz=0] - XZ plane rotation
618
- * @param {number} [angles.yz=0] - YZ plane rotation
619
- * @param {number} [angles.xw=0] - XW plane rotation
620
- * @param {number} [angles.yw=0] - YW plane rotation
621
- * @param {number} [angles.zw=0] - ZW plane rotation
911
+ * Supports two signatures:
912
+ * 1. rotationFromAngles(angles, target?)
913
+ * 2. rotationFromAngles(xy, xz, yz, xw, yw, zw, target?)
914
+ *
915
+ * @param {object|number} anglesOrXY - Rotation angles object OR XY angle
916
+ * @param {number|Mat4x4} [xzOrTarget] - XZ angle OR target matrix
917
+ * @param {number} [yz=0] - YZ angle
918
+ * @param {number} [xw=0] - XW angle
919
+ * @param {number} [yw=0] - YW angle
920
+ * @param {number} [zw=0] - ZW angle
921
+ * @param {Mat4x4} [target=null] - Target matrix (if using 6-arg signature)
622
922
  * @returns {Mat4x4}
623
923
  */
624
- static rotationFromAngles(angles) {
625
- let result = Mat4x4.identity();
924
+ static rotationFromAngles(anglesOrXY, xzOrTarget, yz, xw, yw, zw, target) {
925
+ let xy = 0, xz = 0;
926
+ let _yz = 0, _xw = 0, _yw = 0, _zw = 0;
927
+ let out = null;
928
+
929
+ if (typeof anglesOrXY === 'number') {
930
+ // Signature: (xy, xz, yz, xw, yw, zw, target)
931
+ xy = anglesOrXY;
932
+ xz = typeof xzOrTarget === 'number' ? xzOrTarget : 0;
933
+ _yz = yz || 0;
934
+ _xw = xw || 0;
935
+ _yw = yw || 0;
936
+ _zw = zw || 0;
937
+ out = target || null;
938
+ } else {
939
+ // Signature: (angles, target)
940
+ const angles = anglesOrXY || {};
941
+ xy = angles.xy || 0;
942
+ xz = angles.xz || 0;
943
+ _yz = angles.yz || 0;
944
+ _xw = angles.xw || 0;
945
+ _yw = angles.yw || 0;
946
+ _zw = angles.zw || 0;
947
+ // The second argument is the target in this case
948
+ // Use duck typing or check constructor name to avoid circular dependency issues if any
949
+ if (xzOrTarget && typeof xzOrTarget === 'object' && xzOrTarget.data) {
950
+ out = xzOrTarget;
951
+ }
952
+ }
953
+
954
+ const result = out || new Mat4x4(); // Default constructor is identity
955
+ if (out) result.identity(); // Reset if reused
626
956
 
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));
957
+ if (xy) result.rotateXY(xy);
958
+ if (xz) result.rotateXZ(xz);
959
+ if (_yz) result.rotateYZ(_yz);
960
+ if (_xw) result.rotateXW(_xw);
961
+ if (_yw) result.rotateYW(_yw);
962
+ if (_zw) result.rotateZW(_zw);
633
963
 
634
964
  return result;
635
965
  }
@@ -658,12 +988,13 @@ export class Mat4x4 {
658
988
  * @returns {Mat4x4}
659
989
  */
660
990
  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
- ]);
991
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
992
+ const r = out.data;
993
+ r[0] = s;
994
+ r[5] = s;
995
+ r[10] = s;
996
+ r[15] = s;
997
+ return out;
667
998
  }
668
999
 
669
1000
  /**
@@ -675,12 +1006,13 @@ export class Mat4x4 {
675
1006
  * @returns {Mat4x4}
676
1007
  */
677
1008
  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
- ]);
1009
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
1010
+ const r = out.data;
1011
+ r[0] = sx;
1012
+ r[5] = sy;
1013
+ r[10] = sz;
1014
+ r[15] = sw;
1015
+ return out;
684
1016
  }
685
1017
 
686
1018
  /**
@@ -696,12 +1028,13 @@ export class Mat4x4 {
696
1028
  static translation(tx, ty, tz, tw = 0) {
697
1029
  // For true 4D translation, you need 5D homogeneous coordinates
698
1030
  // 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
- ]);
1031
+ const out = new Mat4x4(Mat4x4.UNINITIALIZED);
1032
+ const r = out.data;
1033
+ r[0] = 1;
1034
+ r[5] = 1;
1035
+ r[10] = 1;
1036
+ r[12] = tx; r[13] = ty; r[14] = tz; r[15] = 1 + tw;
1037
+ return out;
705
1038
  }
706
1039
  }
707
1040