@vib3code/sdk 2.0.1 → 2.0.3-canary.75a3290
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/CHANGELOG.md +36 -0
- package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +243 -0
- package/DOCS/CLI_ONBOARDING.md +1 -1
- package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +117 -0
- package/DOCS/EPIC_SCROLL_EVENTS.md +773 -0
- package/DOCS/HANDOFF_LANDING_PAGE.md +154 -0
- package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +493 -0
- package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +937 -0
- package/DOCS/PRODUCT_STRATEGY.md +63 -0
- package/DOCS/README.md +103 -0
- package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +97 -0
- package/DOCS/ROADMAP.md +111 -0
- package/DOCS/SCROLL_TIMELINE_v3.md +269 -0
- package/DOCS/SITE_REFACTOR_PLAN.md +100 -0
- package/DOCS/STATUS.md +24 -0
- package/DOCS/SYSTEM_INVENTORY.md +33 -30
- package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +85 -0
- package/DOCS/VISUAL_ANALYSIS_FACETAD.md +133 -0
- package/DOCS/VISUAL_ANALYSIS_SIMONE.md +95 -0
- package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +86 -0
- package/DOCS/{BLUEPRINT_EXECUTION_PLAN_2026-01-07.md → archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md} +1 -1
- package/DOCS/{DEV_TRACK_ANALYSIS.md → archive/DEV_TRACK_ANALYSIS.md} +3 -0
- package/DOCS/{SYSTEM_AUDIT_2026-01-30.md → archive/SYSTEM_AUDIT_2026-01-30.md} +3 -0
- package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +1 -1
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +231 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +127 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +142 -0
- package/DOCS/dev-tracks/README.md +10 -0
- package/README.md +26 -13
- package/cpp/CMakeLists.txt +236 -0
- package/cpp/bindings/embind.cpp +269 -0
- package/cpp/build.sh +129 -0
- package/cpp/geometry/Crystal.cpp +103 -0
- package/cpp/geometry/Fractal.cpp +136 -0
- package/cpp/geometry/GeometryGenerator.cpp +262 -0
- package/cpp/geometry/KleinBottle.cpp +71 -0
- package/cpp/geometry/Sphere.cpp +134 -0
- package/cpp/geometry/Tesseract.cpp +94 -0
- package/cpp/geometry/Tetrahedron.cpp +83 -0
- package/cpp/geometry/Torus.cpp +65 -0
- package/cpp/geometry/WarpFunctions.cpp +238 -0
- package/cpp/geometry/Wave.cpp +85 -0
- package/cpp/include/vib3_ffi.h +238 -0
- package/cpp/math/Mat4x4.cpp +409 -0
- package/cpp/math/Mat4x4.hpp +209 -0
- package/cpp/math/Projection.cpp +142 -0
- package/cpp/math/Projection.hpp +148 -0
- package/cpp/math/Rotor4D.cpp +322 -0
- package/cpp/math/Rotor4D.hpp +204 -0
- package/cpp/math/Vec4.cpp +303 -0
- package/cpp/math/Vec4.hpp +225 -0
- package/cpp/src/vib3_ffi.cpp +607 -0
- package/cpp/tests/Geometry_test.cpp +213 -0
- package/cpp/tests/Mat4x4_test.cpp +494 -0
- package/cpp/tests/Projection_test.cpp +298 -0
- package/cpp/tests/Rotor4D_test.cpp +423 -0
- package/cpp/tests/Vec4_test.cpp +489 -0
- package/package.json +40 -27
- package/src/agent/index.js +1 -3
- package/src/agent/mcp/MCPServer.js +918 -0
- package/src/agent/mcp/index.js +1 -1
- package/src/agent/mcp/stdio-server.js +264 -0
- package/src/agent/mcp/tools.js +454 -0
- package/src/cli/index.js +374 -44
- package/src/core/CanvasManager.js +97 -204
- package/src/core/ErrorReporter.js +1 -1
- package/src/core/Parameters.js +1 -1
- package/src/core/VIB3Engine.js +93 -4
- package/src/core/VitalitySystem.js +53 -0
- package/src/core/index.js +18 -0
- package/src/core/renderers/FacetedRendererAdapter.js +10 -9
- package/src/core/renderers/HolographicRendererAdapter.js +13 -9
- package/src/core/renderers/QuantumRendererAdapter.js +11 -7
- package/src/creative/AestheticMapper.js +628 -0
- package/src/creative/ChoreographyPlayer.js +481 -0
- package/src/creative/index.js +11 -0
- package/src/export/TradingCardManager.js +3 -4
- package/src/export/index.js +11 -1
- package/src/faceted/FacetedSystem.js +241 -388
- package/src/holograms/HolographicVisualizer.js +29 -12
- package/src/holograms/RealHolographicSystem.js +194 -43
- package/src/math/index.js +7 -7
- package/src/polychora/PolychoraSystem.js +77 -0
- package/src/quantum/QuantumEngine.js +103 -66
- package/src/quantum/QuantumVisualizer.js +7 -2
- 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/UnifiedRenderBridge.js +3 -0
- package/src/render/index.js +27 -2
- package/src/scene/index.js +4 -4
- package/src/shaders/faceted/faceted.frag.glsl +220 -80
- package/src/shaders/faceted/faceted.frag.wgsl +138 -97
- package/src/shaders/holographic/holographic.frag.glsl +28 -9
- package/src/shaders/holographic/holographic.frag.wgsl +107 -38
- package/src/shaders/quantum/quantum.frag.glsl +1 -0
- package/src/shaders/quantum/quantum.frag.wgsl +1 -1
- package/src/testing/ParallelTestFramework.js +2 -2
- package/src/viewer/GalleryUI.js +17 -0
- package/src/viewer/ViewerPortal.js +2 -2
- package/src/viewer/index.js +1 -1
- package/tools/headless-renderer.js +258 -0
- package/tools/shader-sync-verify.js +8 -4
- package/tools/site-analysis/all-reports.json +32 -0
- package/tools/site-analysis/combined-analysis.md +50 -0
- package/tools/site-analyzer.mjs +779 -0
- package/tools/visual-catalog/capture.js +276 -0
- package/tools/visual-catalog/composite.js +138 -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/DOCS/{DEV_TRACK_PLAN_2026-01-07.md → archive/DEV_TRACK_PLAN_2026-01-07.md} +0 -0
- /package/DOCS/{SESSION_014_PLAN.md → archive/SESSION_014_PLAN.md} +0 -0
- /package/DOCS/{SESSION_LOG_2026-01-07.md → archive/SESSION_LOG_2026-01-07.md} +0 -0
- /package/DOCS/{STRATEGIC_BLUEPRINT_2026-01-07.md → archive/STRATEGIC_BLUEPRINT_2026-01-07.md} +0 -0
- /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
|