@vib3code/sdk 2.0.3-canary.20f0435 → 2.0.3-canary.3206d35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +2 -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 +1 -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/math/Mat4x4.js +116 -86
- package/src/math/Rotor4D.js +31 -1
- package/src/math/Vec4.js +81 -25
- package/src/scene/Node4D.js +74 -24
|
@@ -1,38 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
This document records the current WebGPU backend state, what is implemented, and what is required
|
|
4
|
-
to validate it in local development or CI.
|
|
5
|
-
|
|
6
|
-
## Current status
|
|
7
|
-
- **Backend scaffold:** `WebGPUBackend` initializes adapter/device, configures the canvas, manages
|
|
8
|
-
resize, and supports a clear-pass `renderFrame()` path.
|
|
9
|
-
- **Async context creation:** `createRenderContextAsync()` can instantiate WebGPU contexts using
|
|
10
|
-
`{ backend: 'webgpu' }`.
|
|
11
|
-
- **Resource tracking:** depth textures are registered in the shared `RenderResourceRegistry`.
|
|
12
|
-
|
|
13
|
-
## What is still needed
|
|
14
|
-
1. **Pipeline parity:** implement basic shader pipelines (vertex/fragment) and buffer binding that
|
|
15
|
-
match the WebGL backend command flow.
|
|
16
|
-
2. **Command buffer bridge:** map existing render commands to WebGPU render passes.
|
|
17
|
-
3. **Feature gating:** add host-app controls to toggle WebGPU via feature flags.
|
|
18
|
-
4. **Diagnostics:** add per-frame stats and resource delta reporting for WebGPU.
|
|
19
|
-
|
|
20
|
-
## Testing requirements
|
|
21
|
-
### Local smoke test
|
|
22
|
-
Prerequisites:
|
|
23
|
-
- A browser with WebGPU enabled (Chrome/Edge with `chrome://flags/#enable-unsafe-webgpu`, or a
|
|
24
|
-
Chromium build with WebGPU support).
|
|
25
|
-
- A device with WebGPU-capable GPU drivers.
|
|
26
|
-
|
|
27
|
-
Suggested smoke flow:
|
|
28
|
-
1. Create a canvas and call `createRenderContextAsync(canvas, { backend: 'webgpu' })`.
|
|
29
|
-
2. Call `backend.renderFrame({ clearColor: [0.1, 0.1, 0.2, 1] })` and confirm the canvas clears.
|
|
30
|
-
3. Resize the canvas and ensure the clear pass still succeeds.
|
|
31
|
-
|
|
32
|
-
### CI validation
|
|
33
|
-
- WebGPU cannot be reliably validated in headless CI without GPU support.
|
|
34
|
-
- CI should instead run WebGL tests and lint/static checks; keep a manual WebGPU smoke checklist.
|
|
35
|
-
|
|
36
|
-
## File locations
|
|
37
|
-
- `src/render/backends/WebGPUBackend.js`
|
|
38
|
-
- `src/render/index.js` (`createRenderContextAsync`)
|
|
1
|
+
Last reviewed: 2026-02-17
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vib3code/sdk",
|
|
3
|
-
"version": "2.0.3-canary.
|
|
3
|
+
"version": "2.0.3-canary.3206d35",
|
|
4
4
|
"description": "VIB3+ 4D Visualization SDK - Unified engine with 6D rotation, MCP agentic integration, and cross-platform support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/core/VIB3Engine.js",
|
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
|
/**
|
|
@@ -673,12 +694,13 @@ export class Mat4x4 {
|
|
|
673
694
|
static rotationXY(angle) {
|
|
674
695
|
const c = Math.cos(angle);
|
|
675
696
|
const s = Math.sin(angle);
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
]
|
|
697
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
698
|
+
const r = out.data;
|
|
699
|
+
r[0] = c; r[1] = s;
|
|
700
|
+
r[4] = -s; r[5] = c;
|
|
701
|
+
r[10] = 1;
|
|
702
|
+
r[15] = 1;
|
|
703
|
+
return out;
|
|
682
704
|
}
|
|
683
705
|
|
|
684
706
|
/**
|
|
@@ -689,12 +711,13 @@ export class Mat4x4 {
|
|
|
689
711
|
static rotationXZ(angle) {
|
|
690
712
|
const c = Math.cos(angle);
|
|
691
713
|
const s = Math.sin(angle);
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
]
|
|
714
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
715
|
+
const r = out.data;
|
|
716
|
+
r[0] = c; r[2] = -s;
|
|
717
|
+
r[5] = 1;
|
|
718
|
+
r[8] = s; r[10] = c;
|
|
719
|
+
r[15] = 1;
|
|
720
|
+
return out;
|
|
698
721
|
}
|
|
699
722
|
|
|
700
723
|
/**
|
|
@@ -705,12 +728,13 @@ export class Mat4x4 {
|
|
|
705
728
|
static rotationYZ(angle) {
|
|
706
729
|
const c = Math.cos(angle);
|
|
707
730
|
const s = Math.sin(angle);
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
]
|
|
731
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
732
|
+
const r = out.data;
|
|
733
|
+
r[0] = 1;
|
|
734
|
+
r[5] = c; r[6] = s;
|
|
735
|
+
r[9] = -s; r[10] = c;
|
|
736
|
+
r[15] = 1;
|
|
737
|
+
return out;
|
|
714
738
|
}
|
|
715
739
|
|
|
716
740
|
/**
|
|
@@ -722,12 +746,13 @@ export class Mat4x4 {
|
|
|
722
746
|
static rotationXW(angle) {
|
|
723
747
|
const c = Math.cos(angle);
|
|
724
748
|
const s = Math.sin(angle);
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
]
|
|
749
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
750
|
+
const r = out.data;
|
|
751
|
+
r[0] = c; r[3] = s;
|
|
752
|
+
r[5] = 1;
|
|
753
|
+
r[10] = 1;
|
|
754
|
+
r[12] = -s; r[15] = c;
|
|
755
|
+
return out;
|
|
731
756
|
}
|
|
732
757
|
|
|
733
758
|
/**
|
|
@@ -738,12 +763,13 @@ export class Mat4x4 {
|
|
|
738
763
|
static rotationYW(angle) {
|
|
739
764
|
const c = Math.cos(angle);
|
|
740
765
|
const s = Math.sin(angle);
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
]
|
|
766
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
767
|
+
const r = out.data;
|
|
768
|
+
r[0] = 1;
|
|
769
|
+
r[5] = c; r[7] = s;
|
|
770
|
+
r[10] = 1;
|
|
771
|
+
r[13] = -s; r[15] = c;
|
|
772
|
+
return out;
|
|
747
773
|
}
|
|
748
774
|
|
|
749
775
|
/**
|
|
@@ -754,12 +780,13 @@ export class Mat4x4 {
|
|
|
754
780
|
static rotationZW(angle) {
|
|
755
781
|
const c = Math.cos(angle);
|
|
756
782
|
const s = Math.sin(angle);
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
]
|
|
783
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
784
|
+
const r = out.data;
|
|
785
|
+
r[0] = 1;
|
|
786
|
+
r[5] = 1;
|
|
787
|
+
r[10] = c; r[11] = s;
|
|
788
|
+
r[14] = -s; r[15] = c;
|
|
789
|
+
return out;
|
|
763
790
|
}
|
|
764
791
|
|
|
765
792
|
/**
|
|
@@ -831,12 +858,13 @@ export class Mat4x4 {
|
|
|
831
858
|
* @returns {Mat4x4}
|
|
832
859
|
*/
|
|
833
860
|
static uniformScale(s) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
]
|
|
861
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
862
|
+
const r = out.data;
|
|
863
|
+
r[0] = s;
|
|
864
|
+
r[5] = s;
|
|
865
|
+
r[10] = s;
|
|
866
|
+
r[15] = s;
|
|
867
|
+
return out;
|
|
840
868
|
}
|
|
841
869
|
|
|
842
870
|
/**
|
|
@@ -848,12 +876,13 @@ export class Mat4x4 {
|
|
|
848
876
|
* @returns {Mat4x4}
|
|
849
877
|
*/
|
|
850
878
|
static scale(sx, sy, sz, sw = 1) {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
]
|
|
879
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
880
|
+
const r = out.data;
|
|
881
|
+
r[0] = sx;
|
|
882
|
+
r[5] = sy;
|
|
883
|
+
r[10] = sz;
|
|
884
|
+
r[15] = sw;
|
|
885
|
+
return out;
|
|
857
886
|
}
|
|
858
887
|
|
|
859
888
|
/**
|
|
@@ -869,12 +898,13 @@ export class Mat4x4 {
|
|
|
869
898
|
static translation(tx, ty, tz, tw = 0) {
|
|
870
899
|
// For true 4D translation, you need 5D homogeneous coordinates
|
|
871
900
|
// This is a placeholder that adds the translation to the W column
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
]
|
|
901
|
+
const out = new Mat4x4(Mat4x4.UNINITIALIZED);
|
|
902
|
+
const r = out.data;
|
|
903
|
+
r[0] = 1;
|
|
904
|
+
r[5] = 1;
|
|
905
|
+
r[10] = 1;
|
|
906
|
+
r[12] = tx; r[13] = ty; r[14] = tz; r[15] = 1 + tw;
|
|
907
|
+
return out;
|
|
878
908
|
}
|
|
879
909
|
}
|
|
880
910
|
|
package/src/math/Rotor4D.js
CHANGED
|
@@ -429,9 +429,10 @@ export class Rotor4D {
|
|
|
429
429
|
|
|
430
430
|
/**
|
|
431
431
|
* Convert rotor to 4x4 rotation matrix (column-major for WebGL)
|
|
432
|
+
* @param {Float32Array|Array} [target] - Optional target array to write into
|
|
432
433
|
* @returns {Float32Array} 16-element array in column-major order
|
|
433
434
|
*/
|
|
434
|
-
toMatrix() {
|
|
435
|
+
toMatrix(target = null) {
|
|
435
436
|
// Normalize first for numerical stability
|
|
436
437
|
const n = this.norm();
|
|
437
438
|
const invN = n > 1e-10 ? 1 / n : 1;
|
|
@@ -495,6 +496,35 @@ export class Rotor4D {
|
|
|
495
496
|
// Formula derived from sandwich product R v R†
|
|
496
497
|
// Diagonal: s² minus bivectors containing that axis, plus others
|
|
497
498
|
// Off-diagonal: 2*s*bivector terms for single-plane contributions
|
|
499
|
+
|
|
500
|
+
if (target) {
|
|
501
|
+
// Column 0 (transformed X axis)
|
|
502
|
+
target[0] = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
|
|
503
|
+
target[1] = sxy + xzyz + xwyw - zwxyzw;
|
|
504
|
+
target[2] = sxz - xyyz + xwzw + ywxyzw;
|
|
505
|
+
target[3] = sxw - xyyw - xzzw - yzxyzw;
|
|
506
|
+
|
|
507
|
+
// Column 1 (transformed Y axis)
|
|
508
|
+
target[4] = -sxy + xzyz + xwyw + zwxyzw;
|
|
509
|
+
target[5] = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
|
|
510
|
+
target[6] = syz + xyxz + ywzw - xwxyzw;
|
|
511
|
+
target[7] = syw + xyxw - yzzw + xzxyzw;
|
|
512
|
+
|
|
513
|
+
// Column 2 (transformed Z axis)
|
|
514
|
+
target[8] = -sxz - xyyz + xwzw - ywxyzw;
|
|
515
|
+
target[9] = -syz + xyxz + ywzw + xwxyzw;
|
|
516
|
+
target[10] = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
|
|
517
|
+
target[11] = szw + xzxw + yzyw - xyxyzw;
|
|
518
|
+
|
|
519
|
+
// Column 3 (transformed W axis)
|
|
520
|
+
target[12] = -sxw - xyyw - xzzw + yzxyzw;
|
|
521
|
+
target[13] = -syw + xyxw - yzzw - xzxyzw;
|
|
522
|
+
target[14] = -szw + xzxw + yzyw + xyxyzw;
|
|
523
|
+
target[15] = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
|
|
524
|
+
|
|
525
|
+
return target;
|
|
526
|
+
}
|
|
527
|
+
|
|
498
528
|
return new Float32Array([
|
|
499
529
|
// Column 0 (transformed X axis)
|
|
500
530
|
s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
|
package/src/math/Vec4.js
CHANGED
|
@@ -128,11 +128,19 @@ export class Vec4 {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Add another vector (immutable)
|
|
131
|
+
* Add another vector (immutable unless target provided)
|
|
132
132
|
* @param {Vec4} v
|
|
133
|
-
* @
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
134
|
+
* @returns {Vec4} New vector or target
|
|
135
|
+
*/
|
|
136
|
+
add(v, target = null) {
|
|
137
|
+
if (target) {
|
|
138
|
+
target._x = this._x + v._x;
|
|
139
|
+
target._y = this._y + v._y;
|
|
140
|
+
target._z = this._z + v._z;
|
|
141
|
+
target._w = this._w + v._w;
|
|
142
|
+
return target;
|
|
143
|
+
}
|
|
136
144
|
return new Vec4(
|
|
137
145
|
this._x + v._x,
|
|
138
146
|
this._y + v._y,
|
|
@@ -155,11 +163,19 @@ export class Vec4 {
|
|
|
155
163
|
}
|
|
156
164
|
|
|
157
165
|
/**
|
|
158
|
-
* Subtract another vector (immutable)
|
|
166
|
+
* Subtract another vector (immutable unless target provided)
|
|
159
167
|
* @param {Vec4} v
|
|
160
|
-
* @
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
169
|
+
* @returns {Vec4} New vector or target
|
|
170
|
+
*/
|
|
171
|
+
sub(v, target = null) {
|
|
172
|
+
if (target) {
|
|
173
|
+
target._x = this._x - v._x;
|
|
174
|
+
target._y = this._y - v._y;
|
|
175
|
+
target._z = this._z - v._z;
|
|
176
|
+
target._w = this._w - v._w;
|
|
177
|
+
return target;
|
|
178
|
+
}
|
|
163
179
|
return new Vec4(
|
|
164
180
|
this._x - v._x,
|
|
165
181
|
this._y - v._y,
|
|
@@ -182,11 +198,19 @@ export class Vec4 {
|
|
|
182
198
|
}
|
|
183
199
|
|
|
184
200
|
/**
|
|
185
|
-
* Multiply by scalar (immutable)
|
|
201
|
+
* Multiply by scalar (immutable unless target provided)
|
|
186
202
|
* @param {number} s
|
|
187
|
-
* @
|
|
188
|
-
|
|
189
|
-
|
|
203
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
204
|
+
* @returns {Vec4} New vector or target
|
|
205
|
+
*/
|
|
206
|
+
scale(s, target = null) {
|
|
207
|
+
if (target) {
|
|
208
|
+
target._x = this._x * s;
|
|
209
|
+
target._y = this._y * s;
|
|
210
|
+
target._z = this._z * s;
|
|
211
|
+
target._w = this._w * s;
|
|
212
|
+
return target;
|
|
213
|
+
}
|
|
190
214
|
return new Vec4(
|
|
191
215
|
this._x * s,
|
|
192
216
|
this._y * s,
|
|
@@ -211,9 +235,17 @@ export class Vec4 {
|
|
|
211
235
|
/**
|
|
212
236
|
* Component-wise multiply (Hadamard product)
|
|
213
237
|
* @param {Vec4} v
|
|
214
|
-
* @
|
|
215
|
-
|
|
216
|
-
|
|
238
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
239
|
+
* @returns {Vec4} New vector or target
|
|
240
|
+
*/
|
|
241
|
+
multiply(v, target = null) {
|
|
242
|
+
if (target) {
|
|
243
|
+
target._x = this._x * v._x;
|
|
244
|
+
target._y = this._y * v._y;
|
|
245
|
+
target._z = this._z * v._z;
|
|
246
|
+
target._w = this._w * v._w;
|
|
247
|
+
return target;
|
|
248
|
+
}
|
|
217
249
|
return new Vec4(
|
|
218
250
|
this._x * v._x,
|
|
219
251
|
this._y * v._y,
|
|
@@ -223,10 +255,18 @@ export class Vec4 {
|
|
|
223
255
|
}
|
|
224
256
|
|
|
225
257
|
/**
|
|
226
|
-
* Negate vector (immutable)
|
|
227
|
-
* @
|
|
258
|
+
* Negate vector (immutable unless target provided)
|
|
259
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
260
|
+
* @returns {Vec4} New vector or target
|
|
228
261
|
*/
|
|
229
|
-
negate() {
|
|
262
|
+
negate(target = null) {
|
|
263
|
+
if (target) {
|
|
264
|
+
target._x = -this._x;
|
|
265
|
+
target._y = -this._y;
|
|
266
|
+
target._z = -this._z;
|
|
267
|
+
target._w = -this._w;
|
|
268
|
+
return target;
|
|
269
|
+
}
|
|
230
270
|
return new Vec4(-this._x, -this._y, -this._z, -this._w);
|
|
231
271
|
}
|
|
232
272
|
|
|
@@ -286,15 +326,23 @@ export class Vec4 {
|
|
|
286
326
|
}
|
|
287
327
|
|
|
288
328
|
/**
|
|
289
|
-
* Normalize to unit length (immutable)
|
|
290
|
-
* @
|
|
329
|
+
* Normalize to unit length (immutable unless target provided)
|
|
330
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
331
|
+
* @returns {Vec4} New normalized vector or target
|
|
291
332
|
*/
|
|
292
|
-
normalize() {
|
|
333
|
+
normalize(target = null) {
|
|
293
334
|
const len = this.length();
|
|
294
335
|
if (len < 1e-10) {
|
|
336
|
+
if (target) {
|
|
337
|
+
target._x = 0;
|
|
338
|
+
target._y = 0;
|
|
339
|
+
target._z = 0;
|
|
340
|
+
target._w = 0;
|
|
341
|
+
return target;
|
|
342
|
+
}
|
|
295
343
|
return new Vec4(0, 0, 0, 0);
|
|
296
344
|
}
|
|
297
|
-
return this.scale(1 / len);
|
|
345
|
+
return this.scale(1 / len, target);
|
|
298
346
|
}
|
|
299
347
|
|
|
300
348
|
/**
|
|
@@ -314,9 +362,17 @@ export class Vec4 {
|
|
|
314
362
|
* Linear interpolation to another vector
|
|
315
363
|
* @param {Vec4} v - Target vector
|
|
316
364
|
* @param {number} t - Interpolation factor (0-1)
|
|
317
|
-
* @
|
|
318
|
-
|
|
319
|
-
|
|
365
|
+
* @param {Vec4} [target=null] - Optional target vector
|
|
366
|
+
* @returns {Vec4} New interpolated vector or target
|
|
367
|
+
*/
|
|
368
|
+
lerp(v, t, target = null) {
|
|
369
|
+
if (target) {
|
|
370
|
+
target._x = this._x + (v._x - this._x) * t;
|
|
371
|
+
target._y = this._y + (v._y - this._y) * t;
|
|
372
|
+
target._z = this._z + (v._z - this._z) * t;
|
|
373
|
+
target._w = this._w + (v._w - this._w) * t;
|
|
374
|
+
return target;
|
|
375
|
+
}
|
|
320
376
|
return new Vec4(
|
|
321
377
|
this._x + (v._x - this._x) * t,
|
|
322
378
|
this._y + (v._y - this._y) * t,
|