@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.
- 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 +4 -2
- 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 +4 -2
- 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 +121 -38
- 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 -0
- 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 +15 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
- package/DOCS/dev-tracks/README.md +2 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +11 -4
- package/src/agent/index.js +1 -3
- package/src/agent/mcp/MCPServer.js +542 -188
- package/src/agent/mcp/index.js +1 -1
- package/src/agent/mcp/tools.js +132 -32
- package/src/cli/index.js +431 -47
- package/src/core/VIB3Engine.js +55 -3
- package/src/core/index.js +18 -0
- package/src/core/renderers/FacetedRendererAdapter.js +10 -9
- package/src/core/renderers/HolographicRendererAdapter.js +11 -7
- package/src/core/renderers/QuantumRendererAdapter.js +11 -7
- package/src/creative/index.js +11 -0
- 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/export/SVGExporter.js +9 -5
- package/src/export/index.js +11 -1
- package/src/faceted/FacetedSystem.js +27 -10
- package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/geometry/warp/HypersphereCore.js +53 -24
- package/src/holograms/HolographicVisualizer.js +58 -89
- package/src/holograms/RealHolographicSystem.js +126 -31
- package/src/math/Mat4x4.js +372 -140
- package/src/math/Projection.js +39 -4
- package/src/math/Rotor4D.js +157 -67
- package/src/math/Vec4.js +265 -111
- package/src/math/index.js +7 -7
- package/src/quantum/QuantumVisualizer.js +24 -20
- package/src/reactivity/index.js +3 -5
- package/src/render/LayerPresetManager.js +372 -0
- package/src/render/LayerReactivityBridge.js +344 -0
- package/src/render/LayerRelationshipGraph.js +610 -0
- package/src/render/MultiCanvasBridge.js +148 -25
- package/src/render/ShaderLoader.js +38 -0
- package/src/render/ShaderProgram.js +4 -4
- package/src/render/UnifiedRenderBridge.js +1 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/render/index.js +27 -2
- package/src/scene/Node4D.js +74 -24
- package/src/scene/index.js +4 -4
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +4 -4
- package/src/shaders/common/rotation4d.wgsl +2 -2
- package/src/shaders/common/uniforms.wgsl +15 -8
- package/src/shaders/faceted/faceted.frag.wgsl +19 -6
- package/src/shaders/holographic/holographic.frag.wgsl +7 -5
- package/src/shaders/quantum/quantum.frag.wgsl +7 -5
- package/src/testing/ParallelTestFramework.js +2 -2
- package/src/testing/ProjectionClass.test.js +38 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
- package/src/viewer/GalleryUI.js +17 -0
- package/src/viewer/ViewerPortal.js +2 -2
- package/tools/shader-sync-verify.js +6 -4
- package/tools/update_projection.py +109 -0
- package/types/adaptive-sdk.d.ts +204 -5
- package/types/agent/cli.d.ts +78 -0
- package/types/agent/index.d.ts +18 -0
- package/types/agent/mcp.d.ts +87 -0
- package/types/agent/telemetry.d.ts +190 -0
- package/types/core/VIB3Engine.d.ts +26 -0
- package/types/core/index.d.ts +261 -0
- package/types/creative/AestheticMapper.d.ts +72 -0
- package/types/creative/ChoreographyPlayer.d.ts +96 -0
- package/types/creative/index.d.ts +17 -0
- package/types/export/index.d.ts +243 -0
- package/types/geometry/index.d.ts +164 -0
- package/types/math/index.d.ts +214 -0
- package/types/render/LayerPresetManager.d.ts +78 -0
- package/types/render/LayerReactivityBridge.d.ts +85 -0
- package/types/render/LayerRelationshipGraph.d.ts +174 -0
- package/types/render/index.d.ts +3 -0
- package/types/scene/index.d.ts +204 -0
- package/types/systems/index.d.ts +244 -0
- package/types/variations/index.d.ts +62 -0
- package/types/viewer/index.d.ts +225 -0
package/src/math/Projection.js
CHANGED
|
@@ -36,16 +36,28 @@ export class Projection {
|
|
|
36
36
|
*
|
|
37
37
|
* @param {Vec4} v - 4D point
|
|
38
38
|
* @param {number} d - Distance parameter (typically 1.5-5)
|
|
39
|
+
* @param {object} [options] - Projection options
|
|
40
|
+
* @param {Vec4} [target] - Optional target vector to write result to
|
|
39
41
|
* @returns {Vec4} Projected point (w=0)
|
|
40
42
|
*/
|
|
41
|
-
static perspective(v, d = 2, options = {}) {
|
|
43
|
+
static perspective(v, d = 2, options = {}, target = null) {
|
|
42
44
|
if (typeof d === 'object') {
|
|
43
45
|
options = d;
|
|
44
46
|
d = options.d ?? 2;
|
|
45
47
|
}
|
|
46
|
-
|
|
48
|
+
|
|
49
|
+
// Handle options overload or direct target argument
|
|
50
|
+
if (!target && options && options.target) {
|
|
51
|
+
target = options.target;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const epsilon = (options && options.epsilon) ?? DEFAULT_EPSILON;
|
|
47
55
|
const denom = clampDenominator(d - v.w, epsilon);
|
|
48
56
|
const scale = 1 / denom;
|
|
57
|
+
|
|
58
|
+
if (target) {
|
|
59
|
+
return target.set(v.x * scale, v.y * scale, v.z * scale, 0);
|
|
60
|
+
}
|
|
49
61
|
return new Vec4(v.x * scale, v.y * scale, v.z * scale, 0);
|
|
50
62
|
}
|
|
51
63
|
|
|
@@ -126,10 +138,33 @@ export class Projection {
|
|
|
126
138
|
* Project array of Vec4s using perspective projection
|
|
127
139
|
* @param {Vec4[]} vectors
|
|
128
140
|
* @param {number} d
|
|
141
|
+
* @param {object} [options]
|
|
142
|
+
* @param {Vec4[]} [target] - Optional target array to write results to
|
|
129
143
|
* @returns {Vec4[]}
|
|
130
144
|
*/
|
|
131
|
-
static perspectiveArray(vectors, d = 2, options = {}) {
|
|
132
|
-
|
|
145
|
+
static perspectiveArray(vectors, d = 2, options = {}, target = null) {
|
|
146
|
+
// Handle options overload for 'd'
|
|
147
|
+
if (typeof d === 'object') {
|
|
148
|
+
options = d;
|
|
149
|
+
d = options.d ?? 2;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!target) {
|
|
153
|
+
return vectors.map(v => Projection.perspective(v, d, options));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const count = vectors.length;
|
|
157
|
+
// Iterate and reuse
|
|
158
|
+
for (let i = 0; i < count; i++) {
|
|
159
|
+
const out = target[i];
|
|
160
|
+
if (out) {
|
|
161
|
+
Projection.perspective(vectors[i], d, options, out);
|
|
162
|
+
} else {
|
|
163
|
+
target[i] = Projection.perspective(vectors[i], d, options);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return target;
|
|
133
168
|
}
|
|
134
169
|
|
|
135
170
|
/**
|
package/src/math/Rotor4D.js
CHANGED
|
@@ -276,108 +276,169 @@ export class Rotor4D {
|
|
|
276
276
|
* The result applies this rotation, then r's rotation
|
|
277
277
|
*
|
|
278
278
|
* @param {Rotor4D} r - Right operand
|
|
279
|
+
* @param {Rotor4D} [target=null] - Optional target rotor to write result into
|
|
279
280
|
* @returns {Rotor4D} Composed rotor
|
|
280
281
|
*/
|
|
281
|
-
multiply(r) {
|
|
282
|
+
multiply(r, target = null) {
|
|
282
283
|
// Full geometric product of two rotors in 4D
|
|
283
284
|
// This is derived from the geometric algebra product rules
|
|
284
285
|
|
|
285
286
|
const a = this;
|
|
286
287
|
const b = r;
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
a.
|
|
291
|
-
a.xw * b.xw - a.yw * b.yw - a.zw * b.zw - a.xyzw * b.xyzw,
|
|
289
|
+
// Compute all components first to ensure safety if target aliases a or b
|
|
290
|
+
const s = a.s * b.s - a.xy * b.xy - a.xz * b.xz - a.yz * b.yz -
|
|
291
|
+
a.xw * b.xw - a.yw * b.yw - a.zw * b.zw - a.xyzw * b.xyzw;
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
a.
|
|
295
|
-
a.xw * b.yw - a.yw * b.xw - a.zw * b.xyzw - a.xyzw * b.zw,
|
|
293
|
+
const xy = a.s * b.xy + a.xy * b.s + a.xz * b.yz - a.yz * b.xz +
|
|
294
|
+
a.xw * b.yw - a.yw * b.xw - a.zw * b.xyzw - a.xyzw * b.zw;
|
|
296
295
|
|
|
297
|
-
|
|
298
|
-
a.
|
|
299
|
-
a.xw * b.zw + a.yw * b.xyzw - a.zw * b.xw + a.xyzw * b.yw,
|
|
296
|
+
const xz = a.s * b.xz + a.xz * b.s - a.xy * b.yz + a.yz * b.xy +
|
|
297
|
+
a.xw * b.zw + a.yw * b.xyzw - a.zw * b.xw + a.xyzw * b.yw;
|
|
300
298
|
|
|
301
|
-
|
|
302
|
-
a.
|
|
303
|
-
a.xw * b.xyzw + a.yw * b.zw - a.zw * b.yw - a.xyzw * b.xw,
|
|
299
|
+
const yz = a.s * b.yz + a.yz * b.s + a.xy * b.xz - a.xz * b.xy -
|
|
300
|
+
a.xw * b.xyzw + a.yw * b.zw - a.zw * b.yw - a.xyzw * b.xw;
|
|
304
301
|
|
|
305
|
-
|
|
306
|
-
a.
|
|
307
|
-
a.yz * b.xyzw + a.yw * b.xy - a.zw * b.xz + a.xyzw * b.yz,
|
|
302
|
+
const xw = a.s * b.xw + a.xw * b.s - a.xy * b.yw + a.xz * b.zw +
|
|
303
|
+
a.yz * b.xyzw + a.yw * b.xy - a.zw * b.xz + a.xyzw * b.yz;
|
|
308
304
|
|
|
309
|
-
|
|
310
|
-
a.
|
|
311
|
-
a.yz * b.zw - a.xw * b.xy + a.zw * b.yz - a.xyzw * b.xz,
|
|
305
|
+
const yw = a.s * b.yw + a.yw * b.s + a.xy * b.xw - a.xz * b.xyzw -
|
|
306
|
+
a.yz * b.zw - a.xw * b.xy + a.zw * b.yz - a.xyzw * b.xz;
|
|
312
307
|
|
|
313
|
-
|
|
314
|
-
a.
|
|
315
|
-
a.yz * b.yw - a.xw * b.xz - a.yw * b.yz + a.xyzw * b.xy,
|
|
308
|
+
const zw = a.s * b.zw + a.zw * b.s + a.xy * b.xyzw + a.xz * b.xw +
|
|
309
|
+
a.yz * b.yw - a.xw * b.xz - a.yw * b.yz + a.xyzw * b.xy;
|
|
316
310
|
|
|
317
|
-
|
|
318
|
-
a.
|
|
319
|
-
|
|
320
|
-
)
|
|
311
|
+
const xyzw = a.s * b.xyzw + a.xyzw * b.s + a.xy * b.zw - a.xz * b.yw +
|
|
312
|
+
a.yz * b.xw + a.xw * b.yz - a.yw * b.xz + a.zw * b.xy;
|
|
313
|
+
|
|
314
|
+
if (target) {
|
|
315
|
+
target.s = s;
|
|
316
|
+
target.xy = xy;
|
|
317
|
+
target.xz = xz;
|
|
318
|
+
target.yz = yz;
|
|
319
|
+
target.xw = xw;
|
|
320
|
+
target.yw = yw;
|
|
321
|
+
target.zw = zw;
|
|
322
|
+
target.xyzw = xyzw;
|
|
323
|
+
return target;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return new Rotor4D(s, xy, xz, yz, xw, yw, zw, xyzw);
|
|
321
327
|
}
|
|
322
328
|
|
|
323
329
|
/**
|
|
324
330
|
* Rotate a 4D vector using sandwich product: v' = R v R†
|
|
325
331
|
*
|
|
332
|
+
* Matrix math is inlined to avoid allocating a temporary Float32Array(16).
|
|
333
|
+
* Pass an optional target Vec4 to eliminate all allocations.
|
|
334
|
+
*
|
|
326
335
|
* @param {Vec4} v - Vector to rotate
|
|
327
|
-
* @
|
|
336
|
+
* @param {Vec4} [target] - Optional pre-allocated Vec4 to write result into
|
|
337
|
+
* @returns {Vec4} Rotated vector (target if provided, otherwise new Vec4)
|
|
328
338
|
*/
|
|
329
|
-
rotate(v) {
|
|
330
|
-
// For efficiency, we expand the sandwich product directly
|
|
331
|
-
// rather than doing two rotor multiplications
|
|
332
|
-
|
|
339
|
+
rotate(v, target) {
|
|
333
340
|
const x = v.x, y = v.y, z = v.z, w = v.w;
|
|
334
341
|
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
// Then multiply by R† (reverse of rotor)
|
|
340
|
-
// Extract the vector part of the result
|
|
342
|
+
// Normalize for numerical stability (same as toMatrix)
|
|
343
|
+
const n = this.norm();
|
|
344
|
+
const invN = n > 1e-10 ? 1 / n : 1;
|
|
341
345
|
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
const
|
|
345
|
-
const
|
|
346
|
-
const
|
|
346
|
+
const s = this.s * invN;
|
|
347
|
+
const xy = this.xy * invN;
|
|
348
|
+
const xz = this.xz * invN;
|
|
349
|
+
const yz = this.yz * invN;
|
|
350
|
+
const xw = this.xw * invN;
|
|
351
|
+
const yw = this.yw * invN;
|
|
352
|
+
const zw = this.zw * invN;
|
|
353
|
+
const xyzw = this.xyzw * invN;
|
|
347
354
|
|
|
348
|
-
// Squared terms
|
|
355
|
+
// Squared terms
|
|
349
356
|
const s2 = s * s;
|
|
350
|
-
const xy2 = xy * xy
|
|
351
|
-
const
|
|
357
|
+
const xy2 = xy * xy;
|
|
358
|
+
const xz2 = xz * xz;
|
|
359
|
+
const yz2 = yz * yz;
|
|
360
|
+
const xw2 = xw * xw;
|
|
361
|
+
const yw2 = yw * yw;
|
|
362
|
+
const zw2 = zw * zw;
|
|
352
363
|
const xyzw2 = xyzw * xyzw;
|
|
353
364
|
|
|
354
|
-
//
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
365
|
+
// Cross terms (pre-multiplied by 2)
|
|
366
|
+
const sxy = 2 * s * xy;
|
|
367
|
+
const sxz = 2 * s * xz;
|
|
368
|
+
const syz = 2 * s * yz;
|
|
369
|
+
const sxw = 2 * s * xw;
|
|
370
|
+
const syw = 2 * s * yw;
|
|
371
|
+
const szw = 2 * s * zw;
|
|
372
|
+
|
|
373
|
+
const xzyz = 2 * xz * yz;
|
|
374
|
+
const xyyz = 2 * xy * yz;
|
|
375
|
+
const xyxz = 2 * xy * xz;
|
|
376
|
+
const xyxw = 2 * xy * xw;
|
|
377
|
+
const xyyw = 2 * xy * yw;
|
|
378
|
+
|
|
379
|
+
const xzxw = 2 * xz * xw;
|
|
380
|
+
const xzyw = 2 * xz * yw;
|
|
381
|
+
const xzzw = 2 * xz * zw;
|
|
382
|
+
|
|
383
|
+
const yzxw = 2 * yz * xw;
|
|
384
|
+
const yzyw = 2 * yz * yw;
|
|
385
|
+
const yzzw = 2 * yz * zw;
|
|
386
|
+
|
|
387
|
+
const xwyw = 2 * xw * yw;
|
|
388
|
+
const xwzw = 2 * xw * zw;
|
|
389
|
+
const ywzw = 2 * yw * zw;
|
|
390
|
+
|
|
391
|
+
const xyxyzw = 2 * xy * xyzw;
|
|
392
|
+
const xzxyzw = 2 * xz * xyzw;
|
|
393
|
+
const yzxyzw = 2 * yz * xyzw;
|
|
394
|
+
const xwxyzw = 2 * xw * xyzw;
|
|
395
|
+
const ywxyzw = 2 * yw * xyzw;
|
|
396
|
+
const zwxyzw = 2 * zw * xyzw;
|
|
397
|
+
|
|
398
|
+
// Column-major 4x4 rotation matrix entries (inlined from toMatrix)
|
|
399
|
+
// Column 0
|
|
400
|
+
const m0 = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
|
|
401
|
+
const m1 = sxy + xzyz + xwyw - zwxyzw;
|
|
402
|
+
const m2 = sxz - xyyz + xwzw + ywxyzw;
|
|
403
|
+
const m3 = sxw - xyyw - xzzw - yzxyzw;
|
|
404
|
+
// Column 1
|
|
405
|
+
const m4 = -sxy + xzyz + xwyw + zwxyzw;
|
|
406
|
+
const m5 = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
|
|
407
|
+
const m6 = syz + xyxz + ywzw - xwxyzw;
|
|
408
|
+
const m7 = syw + xyxw - yzzw + xzxyzw;
|
|
409
|
+
// Column 2
|
|
410
|
+
const m8 = -sxz - xyyz + xwzw - ywxyzw;
|
|
411
|
+
const m9 = -syz + xyxz + ywzw + xwxyzw;
|
|
412
|
+
const m10 = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
|
|
413
|
+
const m11 = szw + xzxw + yzyw - xyxyzw;
|
|
414
|
+
// Column 3
|
|
415
|
+
const m12 = -sxw - xyyw - xzzw + yzxyzw;
|
|
416
|
+
const m13 = -syw + xyxw - yzzw - xzxyzw;
|
|
417
|
+
const m14 = -szw + xzxw + yzyw + xyxyzw;
|
|
418
|
+
const m15 = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
|
|
419
|
+
|
|
420
|
+
// Matrix-vector multiply
|
|
421
|
+
const rx = m0 * x + m4 * y + m8 * z + m12 * w;
|
|
422
|
+
const ry = m1 * x + m5 * y + m9 * z + m13 * w;
|
|
423
|
+
const rz = m2 * x + m6 * y + m10 * z + m14 * w;
|
|
424
|
+
const rw = m3 * x + m7 * y + m11 * z + m15 * w;
|
|
425
|
+
|
|
426
|
+
if (target) {
|
|
427
|
+
target.x = rx;
|
|
428
|
+
target.y = ry;
|
|
429
|
+
target.z = rz;
|
|
430
|
+
target.w = rw;
|
|
431
|
+
return target;
|
|
432
|
+
}
|
|
433
|
+
return new Vec4(rx, ry, rz, rw);
|
|
374
434
|
}
|
|
375
435
|
|
|
376
436
|
/**
|
|
377
437
|
* Convert rotor to 4x4 rotation matrix (column-major for WebGL)
|
|
438
|
+
* @param {Float32Array|Array} [target] - Optional target array to write into
|
|
378
439
|
* @returns {Float32Array} 16-element array in column-major order
|
|
379
440
|
*/
|
|
380
|
-
toMatrix() {
|
|
441
|
+
toMatrix(target = null) {
|
|
381
442
|
// Normalize first for numerical stability
|
|
382
443
|
const n = this.norm();
|
|
383
444
|
const invN = n > 1e-10 ? 1 / n : 1;
|
|
@@ -441,6 +502,35 @@ export class Rotor4D {
|
|
|
441
502
|
// Formula derived from sandwich product R v R†
|
|
442
503
|
// Diagonal: s² minus bivectors containing that axis, plus others
|
|
443
504
|
// Off-diagonal: 2*s*bivector terms for single-plane contributions
|
|
505
|
+
|
|
506
|
+
if (target) {
|
|
507
|
+
// Column 0 (transformed X axis)
|
|
508
|
+
target[0] = s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2;
|
|
509
|
+
target[1] = sxy + xzyz + xwyw - zwxyzw;
|
|
510
|
+
target[2] = sxz - xyyz + xwzw + ywxyzw;
|
|
511
|
+
target[3] = sxw - xyyw - xzzw - yzxyzw;
|
|
512
|
+
|
|
513
|
+
// Column 1 (transformed Y axis)
|
|
514
|
+
target[4] = -sxy + xzyz + xwyw + zwxyzw;
|
|
515
|
+
target[5] = s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2;
|
|
516
|
+
target[6] = syz + xyxz + ywzw - xwxyzw;
|
|
517
|
+
target[7] = syw + xyxw - yzzw + xzxyzw;
|
|
518
|
+
|
|
519
|
+
// Column 2 (transformed Z axis)
|
|
520
|
+
target[8] = -sxz - xyyz + xwzw - ywxyzw;
|
|
521
|
+
target[9] = -syz + xyxz + ywzw + xwxyzw;
|
|
522
|
+
target[10] = s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2;
|
|
523
|
+
target[11] = szw + xzxw + yzyw - xyxyzw;
|
|
524
|
+
|
|
525
|
+
// Column 3 (transformed W axis)
|
|
526
|
+
target[12] = -sxw - xyyw - xzzw + yzxyzw;
|
|
527
|
+
target[13] = -syw + xyxw - yzzw - xzxyzw;
|
|
528
|
+
target[14] = -szw + xzxw + yzyw + xyxyzw;
|
|
529
|
+
target[15] = s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2;
|
|
530
|
+
|
|
531
|
+
return target;
|
|
532
|
+
}
|
|
533
|
+
|
|
444
534
|
return new Float32Array([
|
|
445
535
|
// Column 0 (transformed X axis)
|
|
446
536
|
s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
|