@vib3code/sdk 2.0.3-canary.590fbae → 2.0.3-canary.69d53b3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +2 -0
- package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
- package/DOCS/ARCHITECTURE.md +1 -0
- package/DOCS/CI_TESTING.md +2 -0
- package/DOCS/CLI_ONBOARDING.md +2 -0
- package/DOCS/CONTROL_REFERENCE.md +2 -0
- package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +2 -0
- package/DOCS/ENV_SETUP.md +2 -0
- package/DOCS/EPIC_SCROLL_EVENTS.md +2 -0
- package/DOCS/EXPANSION_DESIGN.md +979 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
- package/DOCS/EXPORT_FORMATS.md +2 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
- package/DOCS/HANDOFF_LANDING_PAGE.md +2 -0
- package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +2 -0
- package/DOCS/LICENSING_TIERS.md +2 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +2 -0
- package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +3 -1
- package/DOCS/OBS_SETUP_GUIDE.md +2 -0
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
- package/DOCS/PRODUCT_STRATEGY.md +2 -0
- package/DOCS/PROJECT_SETUP.md +2 -0
- package/DOCS/README.md +5 -3
- package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +2 -0
- package/DOCS/RENDERER_LIFECYCLE.md +2 -0
- package/DOCS/REPO_MANIFEST.md +2 -0
- package/DOCS/ROADMAP.md +2 -0
- package/DOCS/SCROLL_TIMELINE_v3.md +2 -0
- package/DOCS/SITE_REFACTOR_PLAN.md +2 -0
- package/DOCS/STATUS.md +2 -0
- package/DOCS/SYSTEM_INVENTORY.md +2 -0
- package/DOCS/TELEMETRY_EXPORTS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_FACETAD.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_SIMONE.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +2 -0
- package/DOCS/WEBGPU_STATUS.md +2 -0
- package/DOCS/XR_BENCHMARKS.md +2 -0
- package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -34
- package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -80
- package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -42
- package/DOCS/archive/SESSION_014_PLAN.md +1 -195
- package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -56
- package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -72
- package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -741
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -38
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-01-31.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +2 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +2 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +2 -0
- package/DOCS/dev-tracks/README.md +2 -0
- package/package.json +1 -1
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/math/Mat4x4.js +238 -92
- package/src/math/Rotor4D.js +69 -46
- package/src/math/Vec4.js +200 -103
- package/src/scene/Node4D.js +74 -24
package/src/math/Mat4x4.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
|
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
|
-
|
|
333
|
+
r[i] = a[i] + b[i];
|
|
319
334
|
}
|
|
320
|
-
return
|
|
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
|
|
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
|
-
|
|
350
|
+
r[i] = a[i] * s;
|
|
332
351
|
}
|
|
333
|
-
return
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
|
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
|
|
484
|
+
return out;
|
|
464
485
|
}
|
|
465
486
|
|
|
466
487
|
/**
|
|
@@ -547,6 +568,122 @@ export class Mat4x4 {
|
|
|
547
568
|
return new Mat4x4(json.data);
|
|
548
569
|
}
|
|
549
570
|
|
|
571
|
+
// ========== IN-PLACE ROTATIONS ==========
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Rotate in XY plane in place
|
|
575
|
+
* @param {number} angle
|
|
576
|
+
* @returns {Mat4x4} this
|
|
577
|
+
*/
|
|
578
|
+
rotateXY(angle) {
|
|
579
|
+
const c = Math.cos(angle);
|
|
580
|
+
const s = Math.sin(angle);
|
|
581
|
+
const m = this.data;
|
|
582
|
+
|
|
583
|
+
for (let i = 0; i < 4; i++) {
|
|
584
|
+
const a0 = m[i]; // Col 0
|
|
585
|
+
const a1 = m[i + 4]; // Col 1
|
|
586
|
+
m[i] = a0 * c + a1 * s;
|
|
587
|
+
m[i + 4] = -a0 * s + a1 * c;
|
|
588
|
+
}
|
|
589
|
+
return this;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Rotate in XZ plane in place
|
|
594
|
+
* @param {number} angle
|
|
595
|
+
* @returns {Mat4x4} this
|
|
596
|
+
*/
|
|
597
|
+
rotateXZ(angle) {
|
|
598
|
+
const c = Math.cos(angle);
|
|
599
|
+
const s = Math.sin(angle);
|
|
600
|
+
const m = this.data;
|
|
601
|
+
|
|
602
|
+
for (let i = 0; i < 4; i++) {
|
|
603
|
+
const a0 = m[i]; // Col 0
|
|
604
|
+
const a2 = m[i + 8]; // Col 2
|
|
605
|
+
m[i] = a0 * c - a2 * s;
|
|
606
|
+
m[i + 8] = a0 * s + a2 * c;
|
|
607
|
+
}
|
|
608
|
+
return this;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Rotate in YZ plane in place
|
|
613
|
+
* @param {number} angle
|
|
614
|
+
* @returns {Mat4x4} this
|
|
615
|
+
*/
|
|
616
|
+
rotateYZ(angle) {
|
|
617
|
+
const c = Math.cos(angle);
|
|
618
|
+
const s = Math.sin(angle);
|
|
619
|
+
const m = this.data;
|
|
620
|
+
|
|
621
|
+
for (let i = 0; i < 4; i++) {
|
|
622
|
+
const a1 = m[i + 4]; // Col 1
|
|
623
|
+
const a2 = m[i + 8]; // Col 2
|
|
624
|
+
m[i + 4] = a1 * c + a2 * s;
|
|
625
|
+
m[i + 8] = -a1 * s + a2 * c;
|
|
626
|
+
}
|
|
627
|
+
return this;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Rotate in XW plane in place
|
|
632
|
+
* @param {number} angle
|
|
633
|
+
* @returns {Mat4x4} this
|
|
634
|
+
*/
|
|
635
|
+
rotateXW(angle) {
|
|
636
|
+
const c = Math.cos(angle);
|
|
637
|
+
const s = Math.sin(angle);
|
|
638
|
+
const m = this.data;
|
|
639
|
+
|
|
640
|
+
for (let i = 0; i < 4; i++) {
|
|
641
|
+
const a0 = m[i]; // Col 0
|
|
642
|
+
const a3 = m[i + 12]; // Col 3
|
|
643
|
+
m[i] = a0 * c + a3 * s;
|
|
644
|
+
m[i + 12] = -a0 * s + a3 * c;
|
|
645
|
+
}
|
|
646
|
+
return this;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Rotate in YW plane in place
|
|
651
|
+
* @param {number} angle
|
|
652
|
+
* @returns {Mat4x4} this
|
|
653
|
+
*/
|
|
654
|
+
rotateYW(angle) {
|
|
655
|
+
const c = Math.cos(angle);
|
|
656
|
+
const s = Math.sin(angle);
|
|
657
|
+
const m = this.data;
|
|
658
|
+
|
|
659
|
+
for (let i = 0; i < 4; i++) {
|
|
660
|
+
const a1 = m[i + 4]; // Col 1
|
|
661
|
+
const a3 = m[i + 12]; // Col 3
|
|
662
|
+
m[i + 4] = a1 * c + a3 * s;
|
|
663
|
+
m[i + 12] = -a1 * s + a3 * c;
|
|
664
|
+
}
|
|
665
|
+
return this;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Rotate in ZW plane in place
|
|
670
|
+
* @param {number} angle
|
|
671
|
+
* @returns {Mat4x4} this
|
|
672
|
+
*/
|
|
673
|
+
rotateZW(angle) {
|
|
674
|
+
const c = Math.cos(angle);
|
|
675
|
+
const s = Math.sin(angle);
|
|
676
|
+
const m = this.data;
|
|
677
|
+
|
|
678
|
+
for (let i = 0; i < 4; i++) {
|
|
679
|
+
const a2 = m[i + 8]; // Col 2
|
|
680
|
+
const a3 = m[i + 12]; // Col 3
|
|
681
|
+
m[i + 8] = a2 * c + a3 * s;
|
|
682
|
+
m[i + 12] = -a2 * s + a3 * c;
|
|
683
|
+
}
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
|
|
550
687
|
// ========== ROTATION MATRICES FOR ALL 6 PLANES ==========
|
|
551
688
|
|
|
552
689
|
/**
|
|
@@ -557,12 +694,13 @@ export class Mat4x4 {
|
|
|
557
694
|
static rotationXY(angle) {
|
|
558
695
|
const c = Math.cos(angle);
|
|
559
696
|
const s = Math.sin(angle);
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
]
|
|
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;
|
|
566
704
|
}
|
|
567
705
|
|
|
568
706
|
/**
|
|
@@ -573,12 +711,13 @@ export class Mat4x4 {
|
|
|
573
711
|
static rotationXZ(angle) {
|
|
574
712
|
const c = Math.cos(angle);
|
|
575
713
|
const s = Math.sin(angle);
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
]
|
|
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;
|
|
582
721
|
}
|
|
583
722
|
|
|
584
723
|
/**
|
|
@@ -589,12 +728,13 @@ export class Mat4x4 {
|
|
|
589
728
|
static rotationYZ(angle) {
|
|
590
729
|
const c = Math.cos(angle);
|
|
591
730
|
const s = Math.sin(angle);
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
]
|
|
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;
|
|
598
738
|
}
|
|
599
739
|
|
|
600
740
|
/**
|
|
@@ -606,12 +746,13 @@ export class Mat4x4 {
|
|
|
606
746
|
static rotationXW(angle) {
|
|
607
747
|
const c = Math.cos(angle);
|
|
608
748
|
const s = Math.sin(angle);
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
]
|
|
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;
|
|
615
756
|
}
|
|
616
757
|
|
|
617
758
|
/**
|
|
@@ -622,12 +763,13 @@ export class Mat4x4 {
|
|
|
622
763
|
static rotationYW(angle) {
|
|
623
764
|
const c = Math.cos(angle);
|
|
624
765
|
const s = Math.sin(angle);
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
]
|
|
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;
|
|
631
773
|
}
|
|
632
774
|
|
|
633
775
|
/**
|
|
@@ -638,12 +780,13 @@ export class Mat4x4 {
|
|
|
638
780
|
static rotationZW(angle) {
|
|
639
781
|
const c = Math.cos(angle);
|
|
640
782
|
const s = Math.sin(angle);
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
]
|
|
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;
|
|
647
790
|
}
|
|
648
791
|
|
|
649
792
|
/**
|
|
@@ -681,12 +824,12 @@ export class Mat4x4 {
|
|
|
681
824
|
static rotationFromAngles(angles) {
|
|
682
825
|
let result = Mat4x4.identity();
|
|
683
826
|
|
|
684
|
-
if (angles.xy) result
|
|
685
|
-
if (angles.xz) result
|
|
686
|
-
if (angles.yz) result
|
|
687
|
-
if (angles.xw) result
|
|
688
|
-
if (angles.yw) result
|
|
689
|
-
if (angles.zw) result
|
|
827
|
+
if (angles.xy) result.rotateXY(angles.xy);
|
|
828
|
+
if (angles.xz) result.rotateXZ(angles.xz);
|
|
829
|
+
if (angles.yz) result.rotateYZ(angles.yz);
|
|
830
|
+
if (angles.xw) result.rotateXW(angles.xw);
|
|
831
|
+
if (angles.yw) result.rotateYW(angles.yw);
|
|
832
|
+
if (angles.zw) result.rotateZW(angles.zw);
|
|
690
833
|
|
|
691
834
|
return result;
|
|
692
835
|
}
|
|
@@ -715,12 +858,13 @@ export class Mat4x4 {
|
|
|
715
858
|
* @returns {Mat4x4}
|
|
716
859
|
*/
|
|
717
860
|
static uniformScale(s) {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
]
|
|
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;
|
|
724
868
|
}
|
|
725
869
|
|
|
726
870
|
/**
|
|
@@ -732,12 +876,13 @@ export class Mat4x4 {
|
|
|
732
876
|
* @returns {Mat4x4}
|
|
733
877
|
*/
|
|
734
878
|
static scale(sx, sy, sz, sw = 1) {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
]
|
|
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;
|
|
741
886
|
}
|
|
742
887
|
|
|
743
888
|
/**
|
|
@@ -753,12 +898,13 @@ export class Mat4x4 {
|
|
|
753
898
|
static translation(tx, ty, tz, tw = 0) {
|
|
754
899
|
// For true 4D translation, you need 5D homogeneous coordinates
|
|
755
900
|
// This is a placeholder that adds the translation to the W column
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
]
|
|
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;
|
|
762
908
|
}
|
|
763
909
|
}
|
|
764
910
|
|
package/src/math/Rotor4D.js
CHANGED
|
@@ -323,14 +323,17 @@ export class Rotor4D {
|
|
|
323
323
|
/**
|
|
324
324
|
* Rotate a 4D vector using sandwich product: v' = R v R†
|
|
325
325
|
*
|
|
326
|
+
* Matrix math is inlined to avoid allocating a temporary Float32Array(16).
|
|
327
|
+
* Pass an optional target Vec4 to eliminate all allocations.
|
|
328
|
+
*
|
|
326
329
|
* @param {Vec4} v - Vector to rotate
|
|
327
|
-
* @param {Vec4} [target] - Optional
|
|
328
|
-
* @returns {Vec4} Rotated vector
|
|
330
|
+
* @param {Vec4} [target] - Optional pre-allocated Vec4 to write result into
|
|
331
|
+
* @returns {Vec4} Rotated vector (target if provided, otherwise new Vec4)
|
|
329
332
|
*/
|
|
330
333
|
rotate(v, target) {
|
|
331
|
-
|
|
334
|
+
const x = v.x, y = v.y, z = v.z, w = v.w;
|
|
332
335
|
|
|
333
|
-
// Normalize
|
|
336
|
+
// Normalize for numerical stability (same as toMatrix)
|
|
334
337
|
const n = this.norm();
|
|
335
338
|
const invN = n > 1e-10 ? 1 / n : 1;
|
|
336
339
|
|
|
@@ -343,7 +346,7 @@ export class Rotor4D {
|
|
|
343
346
|
const zw = this.zw * invN;
|
|
344
347
|
const xyzw = this.xyzw * invN;
|
|
345
348
|
|
|
346
|
-
//
|
|
349
|
+
// Squared terms
|
|
347
350
|
const s2 = s * s;
|
|
348
351
|
const xy2 = xy * xy;
|
|
349
352
|
const xz2 = xz * xz;
|
|
@@ -353,22 +356,20 @@ export class Rotor4D {
|
|
|
353
356
|
const zw2 = zw * zw;
|
|
354
357
|
const xyzw2 = xyzw * xyzw;
|
|
355
358
|
|
|
356
|
-
// Cross terms
|
|
359
|
+
// Cross terms (pre-multiplied by 2)
|
|
357
360
|
const sxy = 2 * s * xy;
|
|
358
361
|
const sxz = 2 * s * xz;
|
|
359
362
|
const syz = 2 * s * yz;
|
|
360
363
|
const sxw = 2 * s * xw;
|
|
361
364
|
const syw = 2 * s * yw;
|
|
362
365
|
const szw = 2 * s * zw;
|
|
363
|
-
// const sxyzw = 2 * s * xyzw; // Unused in rotation matrix
|
|
364
366
|
|
|
365
|
-
const
|
|
367
|
+
const xzyz = 2 * xz * yz;
|
|
366
368
|
const xyyz = 2 * xy * yz;
|
|
369
|
+
const xyxz = 2 * xy * xz;
|
|
367
370
|
const xyxw = 2 * xy * xw;
|
|
368
371
|
const xyyw = 2 * xy * yw;
|
|
369
|
-
// const xyzw_c = 2 * xy * zw; // Unused in rotation matrix
|
|
370
372
|
|
|
371
|
-
const xzyz = 2 * xz * yz;
|
|
372
373
|
const xzxw = 2 * xz * xw;
|
|
373
374
|
const xzyw = 2 * xz * yw;
|
|
374
375
|
const xzzw = 2 * xz * zw;
|
|
@@ -388,40 +389,33 @@ export class Rotor4D {
|
|
|
388
389
|
const ywxyzw = 2 * yw * xyzw;
|
|
389
390
|
const zwxyzw = 2 * zw * xyzw;
|
|
390
391
|
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
const
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const
|
|
400
|
-
const
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
const z = v.z;
|
|
419
|
-
const w = v.w;
|
|
420
|
-
|
|
421
|
-
const rx = m00 * x + m10 * y + m20 * z + m30 * w;
|
|
422
|
-
const ry = m01 * x + m11 * y + m21 * z + m31 * w;
|
|
423
|
-
const rz = m02 * x + m12 * y + m22 * z + m32 * w;
|
|
424
|
-
const rw = m03 * x + m13 * y + m23 * z + m33 * w;
|
|
392
|
+
// Column-major 4x4 rotation matrix entries (inlined from toMatrix)
|
|
393
|
+
// Column 0
|
|
394
|
+
const m0 = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
|
|
395
|
+
const m1 = sxy + xzyz + xwyw - zwxyzw;
|
|
396
|
+
const m2 = sxz - xyyz + xwzw + ywxyzw;
|
|
397
|
+
const m3 = sxw - xyyw - xzzw - yzxyzw;
|
|
398
|
+
// Column 1
|
|
399
|
+
const m4 = -sxy + xzyz + xwyw + zwxyzw;
|
|
400
|
+
const m5 = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
|
|
401
|
+
const m6 = syz + xyxz + ywzw - xwxyzw;
|
|
402
|
+
const m7 = syw + xyxw - yzzw + xzxyzw;
|
|
403
|
+
// Column 2
|
|
404
|
+
const m8 = -sxz - xyyz + xwzw - ywxyzw;
|
|
405
|
+
const m9 = -syz + xyxz + ywzw + xwxyzw;
|
|
406
|
+
const m10 = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
|
|
407
|
+
const m11 = szw + xzxw + yzyw - xyxyzw;
|
|
408
|
+
// Column 3
|
|
409
|
+
const m12 = -sxw - xyyw - xzzw + yzxyzw;
|
|
410
|
+
const m13 = -syw + xyxw - yzzw - xzxyzw;
|
|
411
|
+
const m14 = -szw + xzxw + yzyw + xyxyzw;
|
|
412
|
+
const m15 = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
|
|
413
|
+
|
|
414
|
+
// Matrix-vector multiply
|
|
415
|
+
const rx = m0 * x + m4 * y + m8 * z + m12 * w;
|
|
416
|
+
const ry = m1 * x + m5 * y + m9 * z + m13 * w;
|
|
417
|
+
const rz = m2 * x + m6 * y + m10 * z + m14 * w;
|
|
418
|
+
const rw = m3 * x + m7 * y + m11 * z + m15 * w;
|
|
425
419
|
|
|
426
420
|
if (target) {
|
|
427
421
|
target.x = rx;
|
|
@@ -430,15 +424,15 @@ export class Rotor4D {
|
|
|
430
424
|
target.w = rw;
|
|
431
425
|
return target;
|
|
432
426
|
}
|
|
433
|
-
|
|
434
427
|
return new Vec4(rx, ry, rz, rw);
|
|
435
428
|
}
|
|
436
429
|
|
|
437
430
|
/**
|
|
438
431
|
* Convert rotor to 4x4 rotation matrix (column-major for WebGL)
|
|
432
|
+
* @param {Float32Array|Array} [target] - Optional target array to write into
|
|
439
433
|
* @returns {Float32Array} 16-element array in column-major order
|
|
440
434
|
*/
|
|
441
|
-
toMatrix() {
|
|
435
|
+
toMatrix(target = null) {
|
|
442
436
|
// Normalize first for numerical stability
|
|
443
437
|
const n = this.norm();
|
|
444
438
|
const invN = n > 1e-10 ? 1 / n : 1;
|
|
@@ -502,6 +496,35 @@ export class Rotor4D {
|
|
|
502
496
|
// Formula derived from sandwich product R v R†
|
|
503
497
|
// Diagonal: s² minus bivectors containing that axis, plus others
|
|
504
498
|
// Off-diagonal: 2*s*bivector terms for single-plane contributions
|
|
499
|
+
|
|
500
|
+
if (target) {
|
|
501
|
+
// Column 0 (transformed X axis)
|
|
502
|
+
target[0] = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
|
|
503
|
+
target[1] = sxy + xzyz + xwyw - zwxyzw;
|
|
504
|
+
target[2] = sxz - xyyz + xwzw + ywxyzw;
|
|
505
|
+
target[3] = sxw - xyyw - xzzw - yzxyzw;
|
|
506
|
+
|
|
507
|
+
// Column 1 (transformed Y axis)
|
|
508
|
+
target[4] = -sxy + xzyz + xwyw + zwxyzw;
|
|
509
|
+
target[5] = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
|
|
510
|
+
target[6] = syz + xyxz + ywzw - xwxyzw;
|
|
511
|
+
target[7] = syw + xyxw - yzzw + xzxyzw;
|
|
512
|
+
|
|
513
|
+
// Column 2 (transformed Z axis)
|
|
514
|
+
target[8] = -sxz - xyyz + xwzw - ywxyzw;
|
|
515
|
+
target[9] = -syz + xyxz + ywzw + xwxyzw;
|
|
516
|
+
target[10] = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
|
|
517
|
+
target[11] = szw + xzxw + yzyw - xyxyzw;
|
|
518
|
+
|
|
519
|
+
// Column 3 (transformed W axis)
|
|
520
|
+
target[12] = -sxw - xyyw - xzzw + yzxyzw;
|
|
521
|
+
target[13] = -syw + xyxw - yzzw - xzxyzw;
|
|
522
|
+
target[14] = -szw + xzxw + yzyw + xyxyzw;
|
|
523
|
+
target[15] = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
|
|
524
|
+
|
|
525
|
+
return target;
|
|
526
|
+
}
|
|
527
|
+
|
|
505
528
|
return new Float32Array([
|
|
506
529
|
// Column 0 (transformed X axis)
|
|
507
530
|
s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
|