@vib3code/sdk 2.0.1

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Rotor4D - 4D Rotation using Geometric Algebra
3
+ *
4
+ * A rotor represents a rotation in 4D space using 8 components:
5
+ * - 1 scalar (s)
6
+ * - 6 bivector components (one per rotation plane: xy, xz, yz, xw, yw, zw)
7
+ * - 1 pseudoscalar (xyzw)
8
+ *
9
+ * Unlike quaternions (which only work for 3D), rotors properly handle
10
+ * all 6 rotation planes in 4D. Rotation is applied via sandwich product:
11
+ * v' = R v R†
12
+ *
13
+ * @example
14
+ * // Create rotor for 45° rotation in XW plane
15
+ * const rotor = Rotor4D.fromAxisAngle('XW', Math.PI / 4);
16
+ * const rotated = rotor.rotate(vec4);
17
+ *
18
+ * // Compose rotations
19
+ * const combined = rotor1.multiply(rotor2);
20
+ */
21
+
22
+ import { Vec4 } from './Vec4.js';
23
+
24
+ export class Rotor4D {
25
+ /**
26
+ * Create a new 4D rotor
27
+ * Default is identity rotor (no rotation)
28
+ *
29
+ * @param {number} s - Scalar component
30
+ * @param {number} xy - XY bivector (rotation in XY plane)
31
+ * @param {number} xz - XZ bivector
32
+ * @param {number} yz - YZ bivector
33
+ * @param {number} xw - XW bivector (4D rotation plane)
34
+ * @param {number} yw - YW bivector
35
+ * @param {number} zw - ZW bivector
36
+ * @param {number} xyzw - Pseudoscalar (4D volume element)
37
+ */
38
+ constructor(s = 1, xy = 0, xz = 0, yz = 0, xw = 0, yw = 0, zw = 0, xyzw = 0) {
39
+ this.s = s;
40
+ this.xy = xy;
41
+ this.xz = xz;
42
+ this.yz = yz;
43
+ this.xw = xw;
44
+ this.yw = yw;
45
+ this.zw = zw;
46
+ this.xyzw = xyzw;
47
+ }
48
+
49
+ /**
50
+ * Create identity rotor (no rotation)
51
+ * @returns {Rotor4D}
52
+ */
53
+ static identity() {
54
+ return new Rotor4D(1, 0, 0, 0, 0, 0, 0, 0);
55
+ }
56
+
57
+ /**
58
+ * Create a copy of this rotor
59
+ * @returns {Rotor4D}
60
+ */
61
+ clone() {
62
+ return new Rotor4D(
63
+ this.s, this.xy, this.xz, this.yz,
64
+ this.xw, this.yw, this.zw, this.xyzw
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Copy values from another rotor
70
+ * @param {Rotor4D} r
71
+ * @returns {Rotor4D} this
72
+ */
73
+ copy(r) {
74
+ this.s = r.s;
75
+ this.xy = r.xy;
76
+ this.xz = r.xz;
77
+ this.yz = r.yz;
78
+ this.xw = r.xw;
79
+ this.yw = r.yw;
80
+ this.zw = r.zw;
81
+ this.xyzw = r.xyzw;
82
+ return this;
83
+ }
84
+
85
+ /**
86
+ * Create rotor from rotation in a single plane
87
+ *
88
+ * @param {string} plane - One of 'XY', 'XZ', 'YZ', 'XW', 'YW', 'ZW'
89
+ * @param {number} angle - Rotation angle in radians
90
+ * @returns {Rotor4D}
91
+ */
92
+ static fromPlaneAngle(plane, angle) {
93
+ const halfAngle = angle / 2;
94
+ const c = Math.cos(halfAngle);
95
+ const s = Math.sin(halfAngle);
96
+
97
+ const rotor = new Rotor4D();
98
+ rotor.s = c;
99
+
100
+ // Set the appropriate bivector component
101
+ // Positive bivector for counterclockwise rotation convention
102
+ switch (plane.toUpperCase()) {
103
+ case 'XY': rotor.xy = s; break;
104
+ case 'XZ': rotor.xz = s; break;
105
+ case 'YZ': rotor.yz = s; break;
106
+ case 'XW': rotor.xw = s; break;
107
+ case 'YW': rotor.yw = s; break;
108
+ case 'ZW': rotor.zw = s; break;
109
+ default:
110
+ throw new Error(`Invalid rotation plane: ${plane}. Use XY, XZ, YZ, XW, YW, or ZW.`);
111
+ }
112
+
113
+ return rotor;
114
+ }
115
+
116
+ /**
117
+ * Create rotor from all 6 rotation angles
118
+ * Composes rotations in order: XY, XZ, YZ, XW, YW, ZW
119
+ *
120
+ * @param {object} angles - Object with rotation angles
121
+ * @param {number} angles.xy - XY plane rotation
122
+ * @param {number} angles.xz - XZ plane rotation
123
+ * @param {number} angles.yz - YZ plane rotation
124
+ * @param {number} angles.xw - XW plane rotation
125
+ * @param {number} angles.yw - YW plane rotation
126
+ * @param {number} angles.zw - ZW plane rotation
127
+ * @returns {Rotor4D}
128
+ */
129
+ static fromEuler6(angles) {
130
+ let result = Rotor4D.identity();
131
+
132
+ // Apply rotations in consistent order
133
+ if (angles.xy) result = result.multiply(Rotor4D.fromPlaneAngle('XY', angles.xy));
134
+ if (angles.xz) result = result.multiply(Rotor4D.fromPlaneAngle('XZ', angles.xz));
135
+ if (angles.yz) result = result.multiply(Rotor4D.fromPlaneAngle('YZ', angles.yz));
136
+ if (angles.xw) result = result.multiply(Rotor4D.fromPlaneAngle('XW', angles.xw));
137
+ if (angles.yw) result = result.multiply(Rotor4D.fromPlaneAngle('YW', angles.yw));
138
+ if (angles.zw) result = result.multiply(Rotor4D.fromPlaneAngle('ZW', angles.zw));
139
+
140
+ return result.normalizeInPlace();
141
+ }
142
+
143
+ /**
144
+ * Create rotor from parameter format (rot4dXY, rot4dXZ, etc.)
145
+ * @param {object} params - Parameters object
146
+ * @returns {Rotor4D}
147
+ */
148
+ static fromParameters(params) {
149
+ return Rotor4D.fromEuler6({
150
+ xy: params.rot4dXY || 0,
151
+ xz: params.rot4dXZ || 0,
152
+ yz: params.rot4dYZ || 0,
153
+ xw: params.rot4dXW || 0,
154
+ yw: params.rot4dYW || 0,
155
+ zw: params.rot4dZW || 0
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Squared norm of the rotor
161
+ * @returns {number}
162
+ */
163
+ normSquared() {
164
+ return (
165
+ this.s * this.s +
166
+ this.xy * this.xy +
167
+ this.xz * this.xz +
168
+ this.yz * this.yz +
169
+ this.xw * this.xw +
170
+ this.yw * this.yw +
171
+ this.zw * this.zw +
172
+ this.xyzw * this.xyzw
173
+ );
174
+ }
175
+
176
+ /**
177
+ * Norm (magnitude) of the rotor
178
+ * @returns {number}
179
+ */
180
+ norm() {
181
+ return Math.sqrt(this.normSquared());
182
+ }
183
+
184
+ /**
185
+ * Normalize rotor to unit length (immutable)
186
+ * CRITICAL: Call this regularly to prevent drift!
187
+ * @returns {Rotor4D}
188
+ */
189
+ normalize() {
190
+ const n = this.norm();
191
+ if (n < 1e-10) {
192
+ return Rotor4D.identity();
193
+ }
194
+ const invN = 1 / n;
195
+ return new Rotor4D(
196
+ this.s * invN,
197
+ this.xy * invN,
198
+ this.xz * invN,
199
+ this.yz * invN,
200
+ this.xw * invN,
201
+ this.yw * invN,
202
+ this.zw * invN,
203
+ this.xyzw * invN
204
+ );
205
+ }
206
+
207
+ /**
208
+ * Normalize rotor in place (mutable)
209
+ * @returns {Rotor4D} this
210
+ */
211
+ normalizeInPlace() {
212
+ const n = this.norm();
213
+ if (n < 1e-10) {
214
+ this.s = 1;
215
+ this.xy = this.xz = this.yz = 0;
216
+ this.xw = this.yw = this.zw = 0;
217
+ this.xyzw = 0;
218
+ return this;
219
+ }
220
+ const invN = 1 / n;
221
+ this.s *= invN;
222
+ this.xy *= invN;
223
+ this.xz *= invN;
224
+ this.yz *= invN;
225
+ this.xw *= invN;
226
+ this.yw *= invN;
227
+ this.zw *= invN;
228
+ this.xyzw *= invN;
229
+ return this;
230
+ }
231
+
232
+ /**
233
+ * Reverse (conjugate) of the rotor
234
+ * For unit rotors: R† = R⁻¹
235
+ * @returns {Rotor4D}
236
+ */
237
+ reverse() {
238
+ // Reverse flips sign of bivectors and pseudoscalar
239
+ return new Rotor4D(
240
+ this.s,
241
+ -this.xy,
242
+ -this.xz,
243
+ -this.yz,
244
+ -this.xw,
245
+ -this.yw,
246
+ -this.zw,
247
+ -this.xyzw
248
+ );
249
+ }
250
+
251
+ /**
252
+ * Inverse of the rotor
253
+ * For unit rotors, this equals reverse()
254
+ * @returns {Rotor4D}
255
+ */
256
+ inverse() {
257
+ const normSq = this.normSquared();
258
+ if (normSq < 1e-10) {
259
+ return Rotor4D.identity();
260
+ }
261
+ const invNormSq = 1 / normSq;
262
+ return new Rotor4D(
263
+ this.s * invNormSq,
264
+ -this.xy * invNormSq,
265
+ -this.xz * invNormSq,
266
+ -this.yz * invNormSq,
267
+ -this.xw * invNormSq,
268
+ -this.yw * invNormSq,
269
+ -this.zw * invNormSq,
270
+ -this.xyzw * invNormSq
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Multiply two rotors (compose rotations)
276
+ * The result applies this rotation, then r's rotation
277
+ *
278
+ * @param {Rotor4D} r - Right operand
279
+ * @returns {Rotor4D} Composed rotor
280
+ */
281
+ multiply(r) {
282
+ // Full geometric product of two rotors in 4D
283
+ // This is derived from the geometric algebra product rules
284
+
285
+ const a = this;
286
+ const b = r;
287
+
288
+ return new Rotor4D(
289
+ // Scalar component
290
+ 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
+
293
+ // XY bivector
294
+ a.s * b.xy + a.xy * b.s + a.xz * b.yz - a.yz * b.xz +
295
+ a.xw * b.yw - a.yw * b.xw - a.zw * b.xyzw - a.xyzw * b.zw,
296
+
297
+ // XZ bivector
298
+ a.s * b.xz + a.xz * b.s - a.xy * b.yz + a.yz * b.xy +
299
+ a.xw * b.zw + a.yw * b.xyzw - a.zw * b.xw + a.xyzw * b.yw,
300
+
301
+ // YZ bivector
302
+ a.s * b.yz + a.yz * b.s + a.xy * b.xz - a.xz * b.xy -
303
+ a.xw * b.xyzw + a.yw * b.zw - a.zw * b.yw - a.xyzw * b.xw,
304
+
305
+ // XW bivector
306
+ a.s * b.xw + a.xw * b.s - a.xy * b.yw + a.xz * b.zw +
307
+ a.yz * b.xyzw + a.yw * b.xy - a.zw * b.xz + a.xyzw * b.yz,
308
+
309
+ // YW bivector
310
+ a.s * b.yw + a.yw * b.s + a.xy * b.xw - a.xz * b.xyzw -
311
+ a.yz * b.zw - a.xw * b.xy + a.zw * b.yz - a.xyzw * b.xz,
312
+
313
+ // ZW bivector
314
+ a.s * b.zw + a.zw * b.s + a.xy * b.xyzw + a.xz * b.xw +
315
+ a.yz * b.yw - a.xw * b.xz - a.yw * b.yz + a.xyzw * b.xy,
316
+
317
+ // Pseudoscalar XYZW
318
+ a.s * b.xyzw + a.xyzw * b.s + a.xy * b.zw - a.xz * b.yw +
319
+ a.yz * b.xw + a.xw * b.yz - a.yw * b.xz + a.zw * b.xy
320
+ );
321
+ }
322
+
323
+ /**
324
+ * Rotate a 4D vector using sandwich product: v' = R v R†
325
+ *
326
+ * @param {Vec4} v - Vector to rotate
327
+ * @returns {Vec4} Rotated vector
328
+ */
329
+ rotate(v) {
330
+ // For efficiency, we expand the sandwich product directly
331
+ // rather than doing two rotor multiplications
332
+
333
+ const x = v.x, y = v.y, z = v.z, w = v.w;
334
+
335
+ // Compute R v (rotor times vector)
336
+ // Vector in GA is: x*e1 + y*e2 + z*e3 + w*e4
337
+ // This produces a mixed multivector
338
+
339
+ // Then multiply by R† (reverse of rotor)
340
+ // Extract the vector part of the result
341
+
342
+ // Pre-compute some common terms
343
+ const s = this.s;
344
+ const xy = this.xy, xz = this.xz, yz = this.yz;
345
+ const xw = this.xw, yw = this.yw, zw = this.zw;
346
+ const xyzw = this.xyzw;
347
+
348
+ // Squared terms for the rotation formula
349
+ const s2 = s * s;
350
+ const xy2 = xy * xy, xz2 = xz * xz, yz2 = yz * yz;
351
+ const xw2 = xw * xw, yw2 = yw * yw, zw2 = zw * zw;
352
+ const xyzw2 = xyzw * xyzw;
353
+
354
+ // The full rotation formula derived from R v R†
355
+ const newX =
356
+ x * (s2 + xy2 + xz2 - yz2 + xw2 - yw2 - zw2 - xyzw2) +
357
+ 2 * y * (s * xy + xz * yz + xw * yw - s * xyzw * zw + xy * s - xyzw * zw) +
358
+ 2 * z * (s * xz - xy * yz + xw * zw + xyzw * yw) +
359
+ 2 * w * (s * xw - xy * yw - xz * zw - xyzw * yz);
360
+
361
+ // Simplified rotation using matrix form
362
+ // This is equivalent but clearer
363
+
364
+ // Actually, let's use the direct matrix multiplication approach
365
+ // which is more numerically stable
366
+
367
+ const m = this.toMatrix();
368
+ return new Vec4(
369
+ m[0] * x + m[4] * y + m[8] * z + m[12] * w,
370
+ m[1] * x + m[5] * y + m[9] * z + m[13] * w,
371
+ m[2] * x + m[6] * y + m[10] * z + m[14] * w,
372
+ m[3] * x + m[7] * y + m[11] * z + m[15] * w
373
+ );
374
+ }
375
+
376
+ /**
377
+ * Convert rotor to 4x4 rotation matrix (column-major for WebGL)
378
+ * @returns {Float32Array} 16-element array in column-major order
379
+ */
380
+ toMatrix() {
381
+ // Normalize first for numerical stability
382
+ const n = this.norm();
383
+ const invN = n > 1e-10 ? 1 / n : 1;
384
+
385
+ const s = this.s * invN;
386
+ const xy = this.xy * invN;
387
+ const xz = this.xz * invN;
388
+ const yz = this.yz * invN;
389
+ const xw = this.xw * invN;
390
+ const yw = this.yw * invN;
391
+ const zw = this.zw * invN;
392
+ const xyzw = this.xyzw * invN;
393
+
394
+ // Pre-compute products
395
+ const s2 = s * s;
396
+ const xy2 = xy * xy;
397
+ const xz2 = xz * xz;
398
+ const yz2 = yz * yz;
399
+ const xw2 = xw * xw;
400
+ const yw2 = yw * yw;
401
+ const zw2 = zw * zw;
402
+ const xyzw2 = xyzw * xyzw;
403
+
404
+ // Cross terms
405
+ const sxy = 2 * s * xy;
406
+ const sxz = 2 * s * xz;
407
+ const syz = 2 * s * yz;
408
+ const sxw = 2 * s * xw;
409
+ const syw = 2 * s * yw;
410
+ const szw = 2 * s * zw;
411
+ const sxyzw = 2 * s * xyzw;
412
+
413
+ const xyxz = 2 * xy * xz;
414
+ const xyyz = 2 * xy * yz;
415
+ const xyxw = 2 * xy * xw;
416
+ const xyyw = 2 * xy * yw;
417
+ const xyzw_c = 2 * xy * zw;
418
+
419
+ const xzyz = 2 * xz * yz;
420
+ const xzxw = 2 * xz * xw;
421
+ const xzyw = 2 * xz * yw;
422
+ const xzzw = 2 * xz * zw;
423
+
424
+ const yzxw = 2 * yz * xw;
425
+ const yzyw = 2 * yz * yw;
426
+ const yzzw = 2 * yz * zw;
427
+
428
+ const xwyw = 2 * xw * yw;
429
+ const xwzw = 2 * xw * zw;
430
+ const ywzw = 2 * yw * zw;
431
+
432
+ const xyxyzw = 2 * xy * xyzw;
433
+ const xzxyzw = 2 * xz * xyzw;
434
+ const yzxyzw = 2 * yz * xyzw;
435
+ const xwxyzw = 2 * xw * xyzw;
436
+ const ywxyzw = 2 * yw * xyzw;
437
+ const zwxyzw = 2 * zw * xyzw;
438
+
439
+ // 4x4 rotation matrix in column-major order
440
+ // Each column is a transformed basis vector
441
+ // Formula derived from sandwich product R v R†
442
+ // Diagonal: s² minus bivectors containing that axis, plus others
443
+ // Off-diagonal: 2*s*bivector terms for single-plane contributions
444
+ return new Float32Array([
445
+ // Column 0 (transformed X axis)
446
+ s2 - xy2 - xz2 + yz2 - xw2 + yw2 + zw2 - xyzw2,
447
+ sxy + xzyz + xwyw - zwxyzw,
448
+ sxz - xyyz + xwzw + ywxyzw,
449
+ sxw - xyyw - xzzw - yzxyzw,
450
+
451
+ // Column 1 (transformed Y axis)
452
+ -sxy + xzyz + xwyw + zwxyzw,
453
+ s2 - xy2 + xz2 - yz2 + xw2 - yw2 + zw2 - xyzw2,
454
+ syz + xyxz + ywzw - xwxyzw,
455
+ syw + xyxw - yzzw + xzxyzw,
456
+
457
+ // Column 2 (transformed Z axis)
458
+ -sxz - xyyz + xwzw - ywxyzw,
459
+ -syz + xyxz + ywzw + xwxyzw,
460
+ s2 + xy2 - xz2 - yz2 + xw2 + yw2 - zw2 - xyzw2,
461
+ szw + xzxw + yzyw - xyxyzw,
462
+
463
+ // Column 3 (transformed W axis)
464
+ -sxw - xyyw - xzzw + yzxyzw,
465
+ -syw + xyxw - yzzw - xzxyzw,
466
+ -szw + xzxw + yzyw + xyxyzw,
467
+ s2 + xy2 + xz2 + yz2 - xw2 - yw2 - zw2 - xyzw2
468
+ ]);
469
+ }
470
+
471
+ /**
472
+ * Spherical linear interpolation between rotors
473
+ * @param {Rotor4D} target - Target rotor
474
+ * @param {number} t - Interpolation factor (0-1)
475
+ * @returns {Rotor4D}
476
+ */
477
+ slerp(target, t) {
478
+ // Compute the cosine of the angle between rotors
479
+ let dot = this.s * target.s +
480
+ this.xy * target.xy + this.xz * target.xz + this.yz * target.yz +
481
+ this.xw * target.xw + this.yw * target.yw + this.zw * target.zw +
482
+ this.xyzw * target.xyzw;
483
+
484
+ // If dot is negative, negate one rotor to take shorter path
485
+ let b = target;
486
+ if (dot < 0) {
487
+ dot = -dot;
488
+ b = new Rotor4D(
489
+ -target.s, -target.xy, -target.xz, -target.yz,
490
+ -target.xw, -target.yw, -target.zw, -target.xyzw
491
+ );
492
+ }
493
+
494
+ // If rotors are very close, use linear interpolation
495
+ if (dot > 0.9995) {
496
+ return new Rotor4D(
497
+ this.s + t * (b.s - this.s),
498
+ this.xy + t * (b.xy - this.xy),
499
+ this.xz + t * (b.xz - this.xz),
500
+ this.yz + t * (b.yz - this.yz),
501
+ this.xw + t * (b.xw - this.xw),
502
+ this.yw + t * (b.yw - this.yw),
503
+ this.zw + t * (b.zw - this.zw),
504
+ this.xyzw + t * (b.xyzw - this.xyzw)
505
+ ).normalizeInPlace();
506
+ }
507
+
508
+ // Spherical interpolation
509
+ const theta = Math.acos(dot);
510
+ const sinTheta = Math.sin(theta);
511
+ const wa = Math.sin((1 - t) * theta) / sinTheta;
512
+ const wb = Math.sin(t * theta) / sinTheta;
513
+
514
+ return new Rotor4D(
515
+ wa * this.s + wb * b.s,
516
+ wa * this.xy + wb * b.xy,
517
+ wa * this.xz + wb * b.xz,
518
+ wa * this.yz + wb * b.yz,
519
+ wa * this.xw + wb * b.xw,
520
+ wa * this.yw + wb * b.yw,
521
+ wa * this.zw + wb * b.zw,
522
+ wa * this.xyzw + wb * b.xyzw
523
+ );
524
+ }
525
+
526
+ /**
527
+ * Check if approximately equal to another rotor
528
+ * @param {Rotor4D} r
529
+ * @param {number} epsilon
530
+ * @returns {boolean}
531
+ */
532
+ equals(r, epsilon = 1e-6) {
533
+ // Account for double cover (R and -R represent same rotation)
534
+ const diff1 = Math.abs(this.s - r.s) + Math.abs(this.xy - r.xy) +
535
+ Math.abs(this.xz - r.xz) + Math.abs(this.yz - r.yz) +
536
+ Math.abs(this.xw - r.xw) + Math.abs(this.yw - r.yw) +
537
+ Math.abs(this.zw - r.zw) + Math.abs(this.xyzw - r.xyzw);
538
+
539
+ const diff2 = Math.abs(this.s + r.s) + Math.abs(this.xy + r.xy) +
540
+ Math.abs(this.xz + r.xz) + Math.abs(this.yz + r.yz) +
541
+ Math.abs(this.xw + r.xw) + Math.abs(this.yw + r.yw) +
542
+ Math.abs(this.zw + r.zw) + Math.abs(this.xyzw + r.xyzw);
543
+
544
+ return Math.min(diff1, diff2) < epsilon * 8;
545
+ }
546
+
547
+ /**
548
+ * Check if this is the identity rotor
549
+ * @param {number} epsilon
550
+ * @returns {boolean}
551
+ */
552
+ isIdentity(epsilon = 1e-6) {
553
+ return this.equals(Rotor4D.identity(), epsilon);
554
+ }
555
+
556
+ /**
557
+ * String representation
558
+ * @param {number} precision
559
+ * @returns {string}
560
+ */
561
+ toString(precision = 3) {
562
+ return `Rotor4D(s=${this.s.toFixed(precision)}, xy=${this.xy.toFixed(precision)}, xz=${this.xz.toFixed(precision)}, yz=${this.yz.toFixed(precision)}, xw=${this.xw.toFixed(precision)}, yw=${this.yw.toFixed(precision)}, zw=${this.zw.toFixed(precision)}, xyzw=${this.xyzw.toFixed(precision)})`;
563
+ }
564
+
565
+ /**
566
+ * JSON representation
567
+ * @returns {object}
568
+ */
569
+ toJSON() {
570
+ return {
571
+ s: this.s,
572
+ xy: this.xy, xz: this.xz, yz: this.yz,
573
+ xw: this.xw, yw: this.yw, zw: this.zw,
574
+ xyzw: this.xyzw
575
+ };
576
+ }
577
+
578
+ /**
579
+ * Convert to array [s, xy, xz, yz, xw, yw, zw, xyzw]
580
+ * @returns {number[]}
581
+ */
582
+ toArray() {
583
+ return [this.s, this.xy, this.xz, this.yz, this.xw, this.yw, this.zw, this.xyzw];
584
+ }
585
+
586
+ /**
587
+ * Create rotor from array
588
+ * @param {number[]} arr - Array of 8 components [s, xy, xz, yz, xw, yw, zw, xyzw]
589
+ * @returns {Rotor4D}
590
+ */
591
+ static fromArray(arr) {
592
+ return new Rotor4D(
593
+ arr[0] ?? 1,
594
+ arr[1] ?? 0,
595
+ arr[2] ?? 0,
596
+ arr[3] ?? 0,
597
+ arr[4] ?? 0,
598
+ arr[5] ?? 0,
599
+ arr[6] ?? 0,
600
+ arr[7] ?? 0
601
+ );
602
+ }
603
+
604
+ /**
605
+ * Create rotor from JSON
606
+ * @param {object} json
607
+ * @returns {Rotor4D}
608
+ */
609
+ static fromJSON(json) {
610
+ return new Rotor4D(
611
+ json.s || 1,
612
+ json.xy || 0, json.xz || 0, json.yz || 0,
613
+ json.xw || 0, json.yw || 0, json.zw || 0,
614
+ json.xyzw || 0
615
+ );
616
+ }
617
+
618
+ /**
619
+ * Create random unit rotor (uniform distribution on rotation group)
620
+ * @returns {Rotor4D}
621
+ */
622
+ static random() {
623
+ // Generate random 8D unit vector for uniform rotor distribution
624
+ const components = [];
625
+ for (let i = 0; i < 8; i++) {
626
+ // Box-Muller for Gaussian
627
+ const u1 = Math.random();
628
+ const u2 = Math.random();
629
+ components.push(Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2));
630
+ }
631
+
632
+ const rotor = new Rotor4D(...components);
633
+ return rotor.normalizeInPlace();
634
+ }
635
+ }
636
+
637
+ export default Rotor4D;