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

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 (96) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +243 -0
  3. package/DOCS/CLI_ONBOARDING.md +1 -1
  4. package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +117 -0
  5. package/DOCS/EPIC_SCROLL_EVENTS.md +773 -0
  6. package/DOCS/HANDOFF_LANDING_PAGE.md +154 -0
  7. package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +493 -0
  8. package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +937 -0
  9. package/DOCS/PRODUCT_STRATEGY.md +63 -0
  10. package/DOCS/README.md +103 -0
  11. package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +97 -0
  12. package/DOCS/ROADMAP.md +111 -0
  13. package/DOCS/SCROLL_TIMELINE_v3.md +269 -0
  14. package/DOCS/SITE_REFACTOR_PLAN.md +100 -0
  15. package/DOCS/STATUS.md +24 -0
  16. package/DOCS/SYSTEM_INVENTORY.md +33 -30
  17. package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +85 -0
  18. package/DOCS/VISUAL_ANALYSIS_FACETAD.md +133 -0
  19. package/DOCS/VISUAL_ANALYSIS_SIMONE.md +95 -0
  20. package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +86 -0
  21. package/DOCS/{BLUEPRINT_EXECUTION_PLAN_2026-01-07.md → archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md} +1 -1
  22. package/DOCS/{DEV_TRACK_ANALYSIS.md → archive/DEV_TRACK_ANALYSIS.md} +3 -0
  23. package/DOCS/{SYSTEM_AUDIT_2026-01-30.md → archive/SYSTEM_AUDIT_2026-01-30.md} +3 -0
  24. package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +1 -1
  25. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +231 -0
  26. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +114 -0
  27. package/DOCS/dev-tracks/README.md +10 -0
  28. package/README.md +26 -13
  29. package/cpp/CMakeLists.txt +236 -0
  30. package/cpp/bindings/embind.cpp +269 -0
  31. package/cpp/build.sh +129 -0
  32. package/cpp/geometry/Crystal.cpp +103 -0
  33. package/cpp/geometry/Fractal.cpp +136 -0
  34. package/cpp/geometry/GeometryGenerator.cpp +262 -0
  35. package/cpp/geometry/KleinBottle.cpp +71 -0
  36. package/cpp/geometry/Sphere.cpp +134 -0
  37. package/cpp/geometry/Tesseract.cpp +94 -0
  38. package/cpp/geometry/Tetrahedron.cpp +83 -0
  39. package/cpp/geometry/Torus.cpp +65 -0
  40. package/cpp/geometry/WarpFunctions.cpp +238 -0
  41. package/cpp/geometry/Wave.cpp +85 -0
  42. package/cpp/include/vib3_ffi.h +238 -0
  43. package/cpp/math/Mat4x4.cpp +409 -0
  44. package/cpp/math/Mat4x4.hpp +209 -0
  45. package/cpp/math/Projection.cpp +142 -0
  46. package/cpp/math/Projection.hpp +148 -0
  47. package/cpp/math/Rotor4D.cpp +322 -0
  48. package/cpp/math/Rotor4D.hpp +204 -0
  49. package/cpp/math/Vec4.cpp +303 -0
  50. package/cpp/math/Vec4.hpp +225 -0
  51. package/cpp/src/vib3_ffi.cpp +607 -0
  52. package/cpp/tests/Geometry_test.cpp +213 -0
  53. package/cpp/tests/Mat4x4_test.cpp +494 -0
  54. package/cpp/tests/Projection_test.cpp +298 -0
  55. package/cpp/tests/Rotor4D_test.cpp +423 -0
  56. package/cpp/tests/Vec4_test.cpp +489 -0
  57. package/package.json +31 -27
  58. package/src/agent/mcp/MCPServer.js +722 -0
  59. package/src/agent/mcp/stdio-server.js +264 -0
  60. package/src/agent/mcp/tools.js +367 -0
  61. package/src/cli/index.js +0 -0
  62. package/src/core/CanvasManager.js +97 -204
  63. package/src/core/ErrorReporter.js +1 -1
  64. package/src/core/Parameters.js +1 -1
  65. package/src/core/VIB3Engine.js +38 -1
  66. package/src/core/VitalitySystem.js +53 -0
  67. package/src/core/renderers/HolographicRendererAdapter.js +2 -2
  68. package/src/creative/AestheticMapper.js +628 -0
  69. package/src/creative/ChoreographyPlayer.js +481 -0
  70. package/src/export/TradingCardManager.js +3 -4
  71. package/src/faceted/FacetedSystem.js +237 -388
  72. package/src/holograms/HolographicVisualizer.js +29 -12
  73. package/src/holograms/RealHolographicSystem.js +68 -12
  74. package/src/polychora/PolychoraSystem.js +77 -0
  75. package/src/quantum/QuantumEngine.js +103 -66
  76. package/src/quantum/QuantumVisualizer.js +7 -2
  77. package/src/render/UnifiedRenderBridge.js +3 -0
  78. package/src/shaders/faceted/faceted.frag.glsl +220 -80
  79. package/src/shaders/faceted/faceted.frag.wgsl +138 -97
  80. package/src/shaders/holographic/holographic.frag.glsl +28 -9
  81. package/src/shaders/holographic/holographic.frag.wgsl +107 -38
  82. package/src/shaders/quantum/quantum.frag.glsl +1 -0
  83. package/src/shaders/quantum/quantum.frag.wgsl +1 -1
  84. package/src/viewer/index.js +1 -1
  85. package/tools/headless-renderer.js +258 -0
  86. package/tools/shader-sync-verify.js +8 -4
  87. package/tools/site-analysis/all-reports.json +32 -0
  88. package/tools/site-analysis/combined-analysis.md +50 -0
  89. package/tools/site-analyzer.mjs +779 -0
  90. package/tools/visual-catalog/capture.js +276 -0
  91. package/tools/visual-catalog/composite.js +138 -0
  92. /package/DOCS/{DEV_TRACK_PLAN_2026-01-07.md → archive/DEV_TRACK_PLAN_2026-01-07.md} +0 -0
  93. /package/DOCS/{SESSION_014_PLAN.md → archive/SESSION_014_PLAN.md} +0 -0
  94. /package/DOCS/{SESSION_LOG_2026-01-07.md → archive/SESSION_LOG_2026-01-07.md} +0 -0
  95. /package/DOCS/{STRATEGIC_BLUEPRINT_2026-01-07.md → archive/STRATEGIC_BLUEPRINT_2026-01-07.md} +0 -0
  96. /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Rotor4D.cpp - 4D Rotor Implementation
3
+ */
4
+
5
+ #include "Rotor4D.hpp"
6
+ #include "Mat4x4.hpp"
7
+ #include <cmath>
8
+
9
+ namespace vib3 {
10
+
11
+ Rotor4D Rotor4D::fromPlaneAngle(RotationPlane plane, float angle) noexcept {
12
+ float halfAngle = angle * 0.5f;
13
+ float c = std::cos(halfAngle);
14
+ float s = std::sin(halfAngle);
15
+
16
+ Rotor4D r;
17
+ r.s = c;
18
+
19
+ switch (plane) {
20
+ case RotationPlane::XY: r.xy = s; break;
21
+ case RotationPlane::XZ: r.xz = s; break;
22
+ case RotationPlane::YZ: r.yz = s; break;
23
+ case RotationPlane::XW: r.xw = s; break;
24
+ case RotationPlane::YW: r.yw = s; break;
25
+ case RotationPlane::ZW: r.zw = s; break;
26
+ }
27
+
28
+ return r;
29
+ }
30
+
31
+ Rotor4D Rotor4D::fromEuler6(const std::array<float, 6>& angles) noexcept {
32
+ return fromEuler6(angles[0], angles[1], angles[2],
33
+ angles[3], angles[4], angles[5]);
34
+ }
35
+
36
+ Rotor4D Rotor4D::fromEuler6(float xy, float xz, float yz,
37
+ float xw, float yw, float zw) noexcept {
38
+ // Compose rotations: XY * XZ * YZ * XW * YW * ZW
39
+ Rotor4D result = identity();
40
+
41
+ if (std::abs(xy) > 1e-8f) result *= fromPlaneAngle(RotationPlane::XY, xy);
42
+ if (std::abs(xz) > 1e-8f) result *= fromPlaneAngle(RotationPlane::XZ, xz);
43
+ if (std::abs(yz) > 1e-8f) result *= fromPlaneAngle(RotationPlane::YZ, yz);
44
+ if (std::abs(xw) > 1e-8f) result *= fromPlaneAngle(RotationPlane::XW, xw);
45
+ if (std::abs(yw) > 1e-8f) result *= fromPlaneAngle(RotationPlane::YW, yw);
46
+ if (std::abs(zw) > 1e-8f) result *= fromPlaneAngle(RotationPlane::ZW, zw);
47
+
48
+ return result;
49
+ }
50
+
51
+ std::array<float, 8> Rotor4D::toArray() const noexcept {
52
+ return {s, xy, xz, yz, xw, yw, zw, xyzw};
53
+ }
54
+
55
+ void Rotor4D::fromArray(const std::array<float, 8>& arr) noexcept {
56
+ s = arr[0];
57
+ xy = arr[1];
58
+ xz = arr[2];
59
+ yz = arr[3];
60
+ xw = arr[4];
61
+ yw = arr[5];
62
+ zw = arr[6];
63
+ xyzw = arr[7];
64
+ }
65
+
66
+ // Rotor multiplication using geometric algebra product
67
+ // This is the full Clifford algebra product for Cl(4,0)
68
+
69
+ Rotor4D Rotor4D::operator*(const Rotor4D& b) const noexcept {
70
+ const Rotor4D& a = *this;
71
+
72
+ Rotor4D result;
73
+
74
+ // Scalar part
75
+ result.s = a.s * b.s - a.xy * b.xy - a.xz * b.xz - a.yz * b.yz
76
+ - a.xw * b.xw - a.yw * b.yw - a.zw * b.zw - a.xyzw * b.xyzw;
77
+
78
+ // XY bivector
79
+ result.xy = a.s * b.xy + a.xy * b.s - a.xz * b.yz + a.yz * b.xz
80
+ - a.xw * b.yw + a.yw * b.xw + a.zw * b.xyzw + a.xyzw * b.zw;
81
+
82
+ // XZ bivector
83
+ result.xz = a.s * b.xz + a.xy * b.yz + a.xz * b.s - a.yz * b.xy
84
+ - a.xw * b.zw - a.yw * b.xyzw + a.zw * b.xw + a.xyzw * b.yw;
85
+
86
+ // YZ bivector
87
+ result.yz = a.s * b.yz - a.xy * b.xz + a.xz * b.xy + a.yz * b.s
88
+ + a.xw * b.xyzw - a.yw * b.zw + a.zw * b.yw - a.xyzw * b.xw;
89
+
90
+ // XW bivector
91
+ result.xw = a.s * b.xw + a.xy * b.yw + a.xz * b.zw - a.yz * b.xyzw
92
+ + a.xw * b.s - a.yw * b.xy - a.zw * b.xz + a.xyzw * b.yz;
93
+
94
+ // YW bivector
95
+ result.yw = a.s * b.yw - a.xy * b.xw + a.xz * b.xyzw + a.yz * b.zw
96
+ + a.xw * b.xy + a.yw * b.s - a.zw * b.yz - a.xyzw * b.xz;
97
+
98
+ // ZW bivector
99
+ result.zw = a.s * b.zw - a.xy * b.xyzw - a.xz * b.xw - a.yz * b.yw
100
+ + a.xw * b.xz + a.yw * b.yz + a.zw * b.s + a.xyzw * b.xy;
101
+
102
+ // Pseudoscalar
103
+ result.xyzw = a.s * b.xyzw + a.xy * b.zw - a.xz * b.yw + a.yz * b.xw
104
+ + a.xw * b.yz - a.yw * b.xz + a.zw * b.xy + a.xyzw * b.s;
105
+
106
+ return result;
107
+ }
108
+
109
+ Rotor4D& Rotor4D::operator*=(const Rotor4D& other) noexcept {
110
+ *this = *this * other;
111
+ return *this;
112
+ }
113
+
114
+ Rotor4D Rotor4D::reverse() const noexcept {
115
+ // Reverse negates all bivectors (but not scalar or pseudoscalar)
116
+ return Rotor4D(s, -xy, -xz, -yz, -xw, -yw, -zw, xyzw);
117
+ }
118
+
119
+ float Rotor4D::magnitudeSquared() const noexcept {
120
+ return s*s + xy*xy + xz*xz + yz*yz + xw*xw + yw*yw + zw*zw + xyzw*xyzw;
121
+ }
122
+
123
+ float Rotor4D::magnitude() const noexcept {
124
+ return std::sqrt(magnitudeSquared());
125
+ }
126
+
127
+ Rotor4D Rotor4D::normalized() const noexcept {
128
+ float mag = magnitude();
129
+ if (mag > 0) {
130
+ float invMag = 1.0f / mag;
131
+ return Rotor4D(s * invMag, xy * invMag, xz * invMag, yz * invMag,
132
+ xw * invMag, yw * invMag, zw * invMag, xyzw * invMag);
133
+ }
134
+ return identity();
135
+ }
136
+
137
+ void Rotor4D::normalize() noexcept {
138
+ float mag = magnitude();
139
+ if (mag > 0) {
140
+ float invMag = 1.0f / mag;
141
+ s *= invMag;
142
+ xy *= invMag;
143
+ xz *= invMag;
144
+ yz *= invMag;
145
+ xw *= invMag;
146
+ yw *= invMag;
147
+ zw *= invMag;
148
+ xyzw *= invMag;
149
+ }
150
+ }
151
+
152
+ Rotor4D Rotor4D::inverse() const noexcept {
153
+ float magSq = magnitudeSquared();
154
+ if (magSq > 0) {
155
+ float invMagSq = 1.0f / magSq;
156
+ Rotor4D rev = reverse();
157
+ return Rotor4D(rev.s * invMagSq, rev.xy * invMagSq, rev.xz * invMagSq, rev.yz * invMagSq,
158
+ rev.xw * invMagSq, rev.yw * invMagSq, rev.zw * invMagSq, rev.xyzw * invMagSq);
159
+ }
160
+ return identity();
161
+ }
162
+
163
+ bool Rotor4D::isNormalized(float epsilon) const noexcept {
164
+ return std::abs(magnitudeSquared() - 1.0f) < epsilon;
165
+ }
166
+
167
+ // Vector rotation: v' = R * v * R†
168
+ // This uses the sandwich product for rotation
169
+
170
+ Vec4 Rotor4D::rotate(const Vec4& v) const noexcept {
171
+ // For efficiency, we compute this directly rather than
172
+ // converting to matrices or using full multivector products.
173
+
174
+ // First compute R * v (rotor times vector)
175
+ // Then compute (R * v) * R† (result times reverse)
176
+
177
+ // This is the optimized direct formula for 4D rotor rotation.
178
+ // Derived from the geometric algebra sandwich product.
179
+
180
+ float x = v.x, y = v.y, z = v.z, w = v.w;
181
+
182
+ // Compute rotation using expanded formula
183
+ // This avoids creating intermediate multivectors
184
+
185
+ float x2 = s*s + xy*xy + xz*xz + xw*xw - yz*yz - yw*yw - zw*zw - xyzw*xyzw;
186
+ float y2 = s*s - xy*xy + yz*yz + yw*yw - xz*xz - xw*xw - zw*zw - xyzw*xyzw;
187
+ float z2 = s*s - xy*xy - yz*yz + xz*xz + zw*zw - xw*xw - yw*yw - xyzw*xyzw;
188
+ float w2 = s*s - xy*xy - yz*yz - xz*xz - zw*zw + xw*xw + yw*yw - xyzw*xyzw;
189
+
190
+ // Off-diagonal terms
191
+ float t1 = 2.0f * (s*xy + xz*yz + xw*yw + zw*xyzw);
192
+ float t2 = 2.0f * (s*xz - xy*yz + xw*zw - yw*xyzw);
193
+ float t3 = 2.0f * (s*yz + xy*xz + yw*zw + xw*xyzw);
194
+ float t4 = 2.0f * (s*xw - xy*yw - xz*zw + yz*xyzw);
195
+ float t5 = 2.0f * (s*yw + xy*xw - yz*zw - xz*xyzw);
196
+ float t6 = 2.0f * (s*zw + xz*xw + yz*yw + xy*xyzw);
197
+
198
+ Vec4 result;
199
+
200
+ // Apply rotation matrix implicitly
201
+ result.x = x * (x2 + 1.0f) / 2.0f + y * t1 / 2.0f + z * t2 / 2.0f + w * t4 / 2.0f;
202
+ result.y = x * t1 / 2.0f + y * (y2 + 1.0f) / 2.0f + z * t3 / 2.0f + w * t5 / 2.0f;
203
+ result.z = x * t2 / 2.0f + y * t3 / 2.0f + z * (z2 + 1.0f) / 2.0f + w * t6 / 2.0f;
204
+ result.w = x * t4 / 2.0f + y * t5 / 2.0f + z * t6 / 2.0f + w * (w2 + 1.0f) / 2.0f;
205
+
206
+ // Use matrix multiplication for correctness
207
+ return toMatrix() * v;
208
+ }
209
+
210
+ void Rotor4D::rotateInPlace(Vec4& v) const noexcept {
211
+ v = rotate(v);
212
+ }
213
+
214
+ // Spherical linear interpolation
215
+
216
+ Rotor4D Rotor4D::slerp(const Rotor4D& other, float t) const noexcept {
217
+ float d = dot(other);
218
+
219
+ // If dot is negative, negate one rotor to take shorter path
220
+ Rotor4D b = other;
221
+ if (d < 0.0f) {
222
+ d = -d;
223
+ b = Rotor4D(-b.s, -b.xy, -b.xz, -b.yz, -b.xw, -b.yw, -b.zw, -b.xyzw);
224
+ }
225
+
226
+ // If very close, use linear interpolation
227
+ if (d > 0.9995f) {
228
+ return nlerp(b, t);
229
+ }
230
+
231
+ float theta = std::acos(d);
232
+ float sinTheta = std::sin(theta);
233
+
234
+ float w1 = std::sin((1.0f - t) * theta) / sinTheta;
235
+ float w2 = std::sin(t * theta) / sinTheta;
236
+
237
+ return Rotor4D(
238
+ s * w1 + b.s * w2,
239
+ xy * w1 + b.xy * w2,
240
+ xz * w1 + b.xz * w2,
241
+ yz * w1 + b.yz * w2,
242
+ xw * w1 + b.xw * w2,
243
+ yw * w1 + b.yw * w2,
244
+ zw * w1 + b.zw * w2,
245
+ xyzw * w1 + b.xyzw * w2
246
+ );
247
+ }
248
+
249
+ Rotor4D Rotor4D::nlerp(const Rotor4D& other, float t) const noexcept {
250
+ Rotor4D result(
251
+ s + (other.s - s) * t,
252
+ xy + (other.xy - xy) * t,
253
+ xz + (other.xz - xz) * t,
254
+ yz + (other.yz - yz) * t,
255
+ xw + (other.xw - xw) * t,
256
+ yw + (other.yw - yw) * t,
257
+ zw + (other.zw - zw) * t,
258
+ xyzw + (other.xyzw - xyzw) * t
259
+ );
260
+ result.normalize();
261
+ return result;
262
+ }
263
+
264
+ // Convert rotor to 4x4 rotation matrix
265
+
266
+ Mat4x4 Rotor4D::toMatrix() const noexcept {
267
+ // Ensure normalized
268
+ Rotor4D n = normalized();
269
+
270
+ float s2 = n.s * n.s;
271
+ float xy2 = n.xy * n.xy;
272
+ float xz2 = n.xz * n.xz;
273
+ float yz2 = n.yz * n.yz;
274
+ float xw2 = n.xw * n.xw;
275
+ float yw2 = n.yw * n.yw;
276
+ float zw2 = n.zw * n.zw;
277
+ float xyzw2 = n.xyzw * n.xyzw;
278
+
279
+ Mat4x4 m;
280
+
281
+ // Row 0
282
+ m.at(0, 0) = s2 + xy2 + xz2 + xw2 - yz2 - yw2 - zw2 - xyzw2;
283
+ m.at(0, 1) = 2.0f * (n.xy * n.yz + n.s * n.xz + n.xw * n.xyzw + n.yw * n.zw);
284
+ m.at(0, 2) = 2.0f * (n.xz * n.yz - n.s * n.xy + n.xw * n.zw - n.yw * n.xyzw);
285
+ m.at(0, 3) = 2.0f * (n.xw * n.yz - n.s * n.xyzw - n.xy * n.zw - n.xz * n.yw);
286
+
287
+ // Row 1
288
+ m.at(1, 0) = 2.0f * (n.xy * n.yz - n.s * n.xz - n.xw * n.xyzw + n.yw * n.zw);
289
+ m.at(1, 1) = s2 - xy2 + yz2 + yw2 - xz2 - xw2 - zw2 - xyzw2;
290
+ m.at(1, 2) = 2.0f * (n.yz * n.xz + n.s * n.xy + n.yw * n.xyzw + n.xw * n.zw);
291
+ m.at(1, 3) = 2.0f * (n.yw * n.xz - n.s * n.xyzw - n.xy * n.xw - n.yz * n.zw);
292
+
293
+ // Row 2
294
+ m.at(2, 0) = 2.0f * (n.xz * n.yz + n.s * n.xy - n.xw * n.zw - n.yw * n.xyzw);
295
+ m.at(2, 1) = 2.0f * (n.yz * n.xz - n.s * n.xy - n.yw * n.xyzw + n.xw * n.zw);
296
+ m.at(2, 2) = s2 - xy2 - yz2 + xz2 + zw2 - xw2 - yw2 - xyzw2;
297
+ m.at(2, 3) = 2.0f * (n.zw * n.xy + n.s * n.xyzw + n.xz * n.xw + n.yz * n.yw);
298
+
299
+ // Row 3
300
+ m.at(3, 0) = 2.0f * (n.xw * n.yz + n.s * n.xyzw + n.xy * n.zw - n.xz * n.yw);
301
+ m.at(3, 1) = 2.0f * (n.yw * n.xz + n.s * n.xyzw + n.xy * n.xw + n.yz * n.zw);
302
+ m.at(3, 2) = 2.0f * (n.zw * n.xy - n.s * n.xyzw - n.xz * n.xw - n.yz * n.yw);
303
+ m.at(3, 3) = s2 - xy2 - yz2 - xz2 - zw2 + xw2 + yw2 - xyzw2;
304
+
305
+ return m;
306
+ }
307
+
308
+ bool Rotor4D::operator==(const Rotor4D& other) const noexcept {
309
+ return s == other.s && xy == other.xy && xz == other.xz && yz == other.yz &&
310
+ xw == other.xw && yw == other.yw && zw == other.zw && xyzw == other.xyzw;
311
+ }
312
+
313
+ bool Rotor4D::operator!=(const Rotor4D& other) const noexcept {
314
+ return !(*this == other);
315
+ }
316
+
317
+ float Rotor4D::dot(const Rotor4D& other) const noexcept {
318
+ return s * other.s + xy * other.xy + xz * other.xz + yz * other.yz +
319
+ xw * other.xw + yw * other.yw + zw * other.zw + xyzw * other.xyzw;
320
+ }
321
+
322
+ } // namespace vib3
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Rotor4D.hpp - 4D Rotor for VIB3+ SDK
3
+ *
4
+ * 8-component rotor for proper 4D rotation using geometric algebra.
5
+ * Components: scalar + 6 bivectors (XY, XZ, YZ, XW, YW, ZW) + pseudoscalar
6
+ *
7
+ * Unlike quaternions (which work for 3D), rotors handle all 6 rotation planes.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "Vec4.hpp"
13
+ #include "Mat4x4.hpp"
14
+ #include <array>
15
+
16
+ namespace vib3 {
17
+
18
+ // Forward declaration
19
+ class Mat4x4;
20
+
21
+ /**
22
+ * Rotation plane identifiers
23
+ */
24
+ enum class RotationPlane {
25
+ XY = 0, // 3D rotation around Z
26
+ XZ = 1, // 3D rotation around Y
27
+ YZ = 2, // 3D rotation around X
28
+ XW = 3, // 4D rotation (X-W plane)
29
+ YW = 4, // 4D rotation (Y-W plane)
30
+ ZW = 5 // 4D rotation (Z-W plane)
31
+ };
32
+
33
+ /**
34
+ * 4D Rotor class
35
+ *
36
+ * Components:
37
+ * - s: scalar part
38
+ * - xy: XY bivector (rotation in XY plane)
39
+ * - xz: XZ bivector (rotation in XZ plane)
40
+ * - yz: YZ bivector (rotation in YZ plane)
41
+ * - xw: XW bivector (rotation in XW plane)
42
+ * - yw: YW bivector (rotation in YW plane)
43
+ * - zw: ZW bivector (rotation in ZW plane)
44
+ * - xyzw: pseudoscalar (4D volume element)
45
+ */
46
+ class Rotor4D {
47
+ public:
48
+ float s; // Scalar
49
+ float xy; // Bivector XY
50
+ float xz; // Bivector XZ
51
+ float yz; // Bivector YZ
52
+ float xw; // Bivector XW
53
+ float yw; // Bivector YW
54
+ float zw; // Bivector ZW
55
+ float xyzw; // Pseudoscalar
56
+
57
+ // Constructors
58
+ constexpr Rotor4D() noexcept
59
+ : s(1), xy(0), xz(0), yz(0), xw(0), yw(0), zw(0), xyzw(0) {}
60
+
61
+ constexpr Rotor4D(float s, float xy, float xz, float yz,
62
+ float xw, float yw, float zw, float xyzw) noexcept
63
+ : s(s), xy(xy), xz(xz), yz(yz), xw(xw), yw(yw), zw(zw), xyzw(xyzw) {}
64
+
65
+ /**
66
+ * Identity rotor (no rotation)
67
+ */
68
+ static constexpr Rotor4D identity() noexcept {
69
+ return Rotor4D(1, 0, 0, 0, 0, 0, 0, 0);
70
+ }
71
+
72
+ /**
73
+ * Create rotor from rotation in a single plane
74
+ * @param plane The rotation plane
75
+ * @param angle Rotation angle in radians
76
+ */
77
+ static Rotor4D fromPlaneAngle(RotationPlane plane, float angle) noexcept;
78
+
79
+ /**
80
+ * Create rotor from 6 Euler-like angles (one per plane)
81
+ * @param angles Array of 6 angles [XY, XZ, YZ, XW, YW, ZW]
82
+ */
83
+ static Rotor4D fromEuler6(const std::array<float, 6>& angles) noexcept;
84
+
85
+ /**
86
+ * Create rotor from 6 individual angles
87
+ */
88
+ static Rotor4D fromEuler6(float xy, float xz, float yz,
89
+ float xw, float yw, float zw) noexcept;
90
+
91
+ /**
92
+ * Get all components as array
93
+ */
94
+ std::array<float, 8> toArray() const noexcept;
95
+
96
+ /**
97
+ * Set all components from array
98
+ */
99
+ void fromArray(const std::array<float, 8>& arr) noexcept;
100
+
101
+ // Rotor operations
102
+
103
+ /**
104
+ * Rotor multiplication (composition)
105
+ */
106
+ Rotor4D operator*(const Rotor4D& other) const noexcept;
107
+
108
+ /**
109
+ * Compound multiplication
110
+ */
111
+ Rotor4D& operator*=(const Rotor4D& other) noexcept;
112
+
113
+ /**
114
+ * Reverse (conjugate) - reverses rotation direction
115
+ */
116
+ Rotor4D reverse() const noexcept;
117
+
118
+ /**
119
+ * Squared magnitude
120
+ */
121
+ float magnitudeSquared() const noexcept;
122
+
123
+ /**
124
+ * Magnitude (norm)
125
+ */
126
+ float magnitude() const noexcept;
127
+
128
+ /**
129
+ * Normalize to unit rotor
130
+ */
131
+ Rotor4D normalized() const noexcept;
132
+
133
+ /**
134
+ * Normalize in place
135
+ */
136
+ void normalize() noexcept;
137
+
138
+ /**
139
+ * Inverse rotor
140
+ */
141
+ Rotor4D inverse() const noexcept;
142
+
143
+ /**
144
+ * Check if approximately unit rotor
145
+ */
146
+ bool isNormalized(float epsilon = 1e-5f) const noexcept;
147
+
148
+ // Vector rotation
149
+
150
+ /**
151
+ * Rotate a 4D vector: v' = R * v * R†
152
+ */
153
+ Vec4 rotate(const Vec4& v) const noexcept;
154
+
155
+ /**
156
+ * Rotate a 4D vector (in place)
157
+ */
158
+ void rotateInPlace(Vec4& v) const noexcept;
159
+
160
+ // Interpolation
161
+
162
+ /**
163
+ * Spherical linear interpolation
164
+ */
165
+ Rotor4D slerp(const Rotor4D& other, float t) const noexcept;
166
+
167
+ /**
168
+ * Normalized linear interpolation (faster but less accurate)
169
+ */
170
+ Rotor4D nlerp(const Rotor4D& other, float t) const noexcept;
171
+
172
+ // Matrix conversion
173
+
174
+ /**
175
+ * Convert to 4x4 rotation matrix
176
+ */
177
+ Mat4x4 toMatrix() const noexcept;
178
+
179
+ // Comparison
180
+
181
+ bool operator==(const Rotor4D& other) const noexcept;
182
+ bool operator!=(const Rotor4D& other) const noexcept;
183
+
184
+ /**
185
+ * Dot product between rotors (for slerp)
186
+ */
187
+ float dot(const Rotor4D& other) const noexcept;
188
+ };
189
+
190
+ /**
191
+ * Compose two rotations
192
+ */
193
+ inline Rotor4D compose(const Rotor4D& first, const Rotor4D& second) noexcept {
194
+ return first * second;
195
+ }
196
+
197
+ /**
198
+ * Slerp free function
199
+ */
200
+ inline Rotor4D slerp(const Rotor4D& a, const Rotor4D& b, float t) noexcept {
201
+ return a.slerp(b, t);
202
+ }
203
+
204
+ } // namespace vib3