@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.
- 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 +114 -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 +31 -27
- package/src/agent/mcp/MCPServer.js +722 -0
- package/src/agent/mcp/stdio-server.js +264 -0
- package/src/agent/mcp/tools.js +367 -0
- package/src/cli/index.js +0 -0
- 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 +38 -1
- package/src/core/VitalitySystem.js +53 -0
- package/src/core/renderers/HolographicRendererAdapter.js +2 -2
- package/src/creative/AestheticMapper.js +628 -0
- package/src/creative/ChoreographyPlayer.js +481 -0
- package/src/export/TradingCardManager.js +3 -4
- package/src/faceted/FacetedSystem.js +237 -388
- package/src/holograms/HolographicVisualizer.js +29 -12
- package/src/holograms/RealHolographicSystem.js +68 -12
- package/src/polychora/PolychoraSystem.js +77 -0
- package/src/quantum/QuantumEngine.js +103 -66
- package/src/quantum/QuantumVisualizer.js +7 -2
- package/src/render/UnifiedRenderBridge.js +3 -0
- 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/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/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
|
@@ -29,7 +29,7 @@ export class HolographicVisualizer {
|
|
|
29
29
|
this.canvas.getContext('experimental-webgl');
|
|
30
30
|
|
|
31
31
|
if (existingContext && !existingContext.isContextLost()) {
|
|
32
|
-
console.log(`🔄 Reusing existing WebGL context for ${
|
|
32
|
+
console.log(`🔄 Reusing existing WebGL context for ${canvasIdOrElement instanceof HTMLCanvasElement ? canvasIdOrElement.id : canvasIdOrElement}`);
|
|
33
33
|
this.gl = existingContext;
|
|
34
34
|
} else {
|
|
35
35
|
// Try WebGL2 first (better mobile support), then WebGL1
|
|
@@ -39,9 +39,9 @@ export class HolographicVisualizer {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (!this.gl) {
|
|
42
|
-
console.error(`WebGL not supported for ${
|
|
42
|
+
console.error(`WebGL not supported for ${canvasIdOrElement}`);
|
|
43
43
|
this.showWebGLError();
|
|
44
|
-
throw new Error(`WebGL not supported for ${
|
|
44
|
+
throw new Error(`WebGL not supported for ${canvasIdOrElement}`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
this.variantParams = this.generateVariantParams(variant);
|
|
@@ -86,17 +86,17 @@ export class HolographicVisualizer {
|
|
|
86
86
|
this._onContextLost = (e) => {
|
|
87
87
|
e.preventDefault();
|
|
88
88
|
this._contextLost = true;
|
|
89
|
-
console.warn(`WebGL context lost for ${
|
|
89
|
+
console.warn(`WebGL context lost for ${canvasIdOrElement}`);
|
|
90
90
|
};
|
|
91
91
|
this._onContextRestored = () => {
|
|
92
|
-
console.log(`WebGL context restored for ${
|
|
92
|
+
console.log(`WebGL context restored for ${canvasIdOrElement}`);
|
|
93
93
|
this._contextLost = false;
|
|
94
94
|
try {
|
|
95
95
|
this.initShaders();
|
|
96
96
|
this.initBuffers();
|
|
97
97
|
this.resize();
|
|
98
98
|
} catch (err) {
|
|
99
|
-
console.error(`Failed to reinit after context restore for ${
|
|
99
|
+
console.error(`Failed to reinit after context restore for ${canvasIdOrElement}:`, err);
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
102
|
this.canvas.addEventListener('webglcontextlost', this._onContextLost);
|
|
@@ -238,6 +238,9 @@ export class HolographicVisualizer {
|
|
|
238
238
|
uniform float u_rot4dYW;
|
|
239
239
|
uniform float u_rot4dZW;
|
|
240
240
|
|
|
241
|
+
// EXHALE FEATURE: Breathing uniform
|
|
242
|
+
uniform float u_breath;
|
|
243
|
+
|
|
241
244
|
// 6D rotation matrices - 3D space rotations (XY, XZ, YZ)
|
|
242
245
|
mat4 rotateXY(float theta) {
|
|
243
246
|
float c = cos(theta);
|
|
@@ -276,9 +279,12 @@ export class HolographicVisualizer {
|
|
|
276
279
|
return mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, c, -s, 0, 0, s, c);
|
|
277
280
|
}
|
|
278
281
|
|
|
279
|
-
// 4D to 3D projection
|
|
282
|
+
// 4D to 3D projection - BREATHING EFFECT
|
|
280
283
|
vec3 project4Dto3D(vec4 p) {
|
|
281
|
-
|
|
284
|
+
// Modulate projection distance with breath for "exhale" effect (expansion/contraction)
|
|
285
|
+
float baseDim = 2.5;
|
|
286
|
+
float dim = baseDim + u_breath * 0.5; // Expands on exhale
|
|
287
|
+
float w = dim / (dim + p.w);
|
|
282
288
|
return vec3(p.x * w, p.y * w, p.z * w);
|
|
283
289
|
}
|
|
284
290
|
|
|
@@ -543,8 +549,10 @@ export class HolographicVisualizer {
|
|
|
543
549
|
|
|
544
550
|
float scrollDensityMod = 1.0 + u_gridDensityShift * 0.3;
|
|
545
551
|
float audioDensityMod = 1.0 + u_audioDensityBoost * 0.5;
|
|
546
|
-
//
|
|
547
|
-
float
|
|
552
|
+
// Controlled density calculation - breathing modulation added
|
|
553
|
+
float breathDensityMod = 1.0 + u_breath * 0.1;
|
|
554
|
+
float baseDensity = u_density * u_roleDensity * breathDensityMod;
|
|
555
|
+
|
|
548
556
|
float densityVariations = (u_densityVariation * 0.3 + (scrollDensityMod - 1.0) * 0.4 + (audioDensityMod - 1.0) * 0.2);
|
|
549
557
|
float roleDensity = baseDensity + densityVariations;
|
|
550
558
|
|
|
@@ -555,6 +563,9 @@ export class HolographicVisualizer {
|
|
|
555
563
|
vec3 baseColor = u_color;
|
|
556
564
|
float latticeIntensity = lattice * u_intensity;
|
|
557
565
|
|
|
566
|
+
// Breathing glow effect
|
|
567
|
+
latticeIntensity *= (1.0 + u_breath * 0.4);
|
|
568
|
+
|
|
558
569
|
// Multi-layer color composition for higher fidelity
|
|
559
570
|
vec3 color = baseColor * (0.2 + latticeIntensity * 0.8);
|
|
560
571
|
|
|
@@ -639,7 +650,8 @@ export class HolographicVisualizer {
|
|
|
639
650
|
rot4dYZ: this.gl.getUniformLocation(this.program, 'u_rot4dYZ'),
|
|
640
651
|
rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
|
|
641
652
|
rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
|
|
642
|
-
rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW')
|
|
653
|
+
rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
|
|
654
|
+
breath: this.gl.getUniformLocation(this.program, 'u_breath')
|
|
643
655
|
};
|
|
644
656
|
}
|
|
645
657
|
|
|
@@ -939,6 +951,10 @@ export class HolographicVisualizer {
|
|
|
939
951
|
this.gl.uniform1f(this.uniforms.rot4dYW, this.variantParams.rot4dYW || 0.0);
|
|
940
952
|
this.gl.uniform1f(this.uniforms.rot4dZW, this.variantParams.rot4dZW || 0.0);
|
|
941
953
|
|
|
954
|
+
// Exhale feature: Use centralized breath from VitalitySystem (0.0 = inhale, 1.0 = exhale)
|
|
955
|
+
const breathCycle = this.variantParams.breath || 0.0;
|
|
956
|
+
this.gl.uniform1f(this.uniforms.breath, breathCycle);
|
|
957
|
+
|
|
942
958
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
|
943
959
|
}
|
|
944
960
|
|
|
@@ -1036,7 +1052,8 @@ export class HolographicVisualizer {
|
|
|
1036
1052
|
'saturation': 'saturation',
|
|
1037
1053
|
'chaos': 'chaos',
|
|
1038
1054
|
'speed': 'speed',
|
|
1039
|
-
'geometry': 'geometryType'
|
|
1055
|
+
'geometry': 'geometryType',
|
|
1056
|
+
'breath': 'breath'
|
|
1040
1057
|
};
|
|
1041
1058
|
return paramMap[globalParam] || globalParam;
|
|
1042
1059
|
}
|
|
@@ -19,6 +19,11 @@ export class RealHolographicSystem {
|
|
|
19
19
|
/** @type {HTMLCanvasElement|null} */
|
|
20
20
|
this.canvasOverride = options.canvas || null;
|
|
21
21
|
|
|
22
|
+
// Multi-canvas override: { background, shadow, content, highlight, accent }
|
|
23
|
+
// Enables 5-layer mode without DOM ID lookup (for landing page / multi-instance)
|
|
24
|
+
/** @type {Object<string, HTMLCanvasElement>|null} */
|
|
25
|
+
this.canvasSet = options.canvases || null;
|
|
26
|
+
|
|
22
27
|
// Bridge rendering state
|
|
23
28
|
/** @type {MultiCanvasBridge|null} */
|
|
24
29
|
this._multiCanvasBridge = null;
|
|
@@ -87,6 +92,39 @@ export class RealHolographicSystem {
|
|
|
87
92
|
return;
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
// Multi-canvas override: 5-layer mode with provided canvas elements
|
|
96
|
+
// Used by landing page adapters to create multiple independent 5-layer instances
|
|
97
|
+
if (this.canvasSet) {
|
|
98
|
+
const layerDefs = [
|
|
99
|
+
{ key: 'background', role: 'background', reactivity: 0.5 },
|
|
100
|
+
{ key: 'shadow', role: 'shadow', reactivity: 0.7 },
|
|
101
|
+
{ key: 'content', role: 'content', reactivity: 0.9 },
|
|
102
|
+
{ key: 'highlight', role: 'highlight', reactivity: 1.1 },
|
|
103
|
+
{ key: 'accent', role: 'accent', reactivity: 1.5 },
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
let successfulLayers = 0;
|
|
107
|
+
layerDefs.forEach(layer => {
|
|
108
|
+
const canvas = this.canvasSet[layer.key];
|
|
109
|
+
if (!canvas) return;
|
|
110
|
+
try {
|
|
111
|
+
const visualizer = new HolographicVisualizer(
|
|
112
|
+
canvas, layer.role, layer.reactivity, this.currentVariant
|
|
113
|
+
);
|
|
114
|
+
if (visualizer.gl) {
|
|
115
|
+
this.visualizers.push(visualizer);
|
|
116
|
+
successfulLayers++;
|
|
117
|
+
console.log(`✅ Created holographic layer (canvasSet): ${layer.role}`);
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.warn(`Failed to create holographic layer ${layer.role}:`, error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
console.log(`✅ Created ${successfulLayers} holographic visualizers via canvasSet`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
90
128
|
// Create the 5 visualizers using HOLO canvas IDs
|
|
91
129
|
const layers = [
|
|
92
130
|
{ id: 'holo-background-canvas', role: 'background', reactivity: 0.5 },
|
|
@@ -701,7 +739,7 @@ export class RealHolographicSystem {
|
|
|
701
739
|
window.updateParameter('morphFactor', depthMorph.toFixed(2));
|
|
702
740
|
}
|
|
703
741
|
|
|
704
|
-
|
|
742
|
+
// Holographic shimmer updated
|
|
705
743
|
}
|
|
706
744
|
|
|
707
745
|
triggerHolographicColorBurst(x, y) {
|
|
@@ -723,11 +761,13 @@ export class RealHolographicSystem {
|
|
|
723
761
|
this.burstChaosEffect = 0.6; // Chaos/morph burst effect
|
|
724
762
|
this.burstSpeedBoost = 1.8; // Animation speed burst
|
|
725
763
|
|
|
726
|
-
|
|
764
|
+
// Holographic color burst triggered
|
|
727
765
|
}
|
|
728
|
-
|
|
766
|
+
|
|
729
767
|
startHolographicColorBurstLoop() {
|
|
768
|
+
this._burstLoopActive = true;
|
|
730
769
|
const burstAnimation = () => {
|
|
770
|
+
if (!this._burstLoopActive) return;
|
|
731
771
|
// DRAMATIC HOLOGRAPHIC COLOR BURST ANIMATION (like Quantum's multi-parameter effects)
|
|
732
772
|
let hasActiveEffects = false;
|
|
733
773
|
|
|
@@ -797,16 +837,16 @@ export class RealHolographicSystem {
|
|
|
797
837
|
this.colorBurstIntensity *= 0.94;
|
|
798
838
|
}
|
|
799
839
|
|
|
800
|
-
|
|
801
|
-
requestAnimationFrame(burstAnimation);
|
|
802
|
-
}
|
|
840
|
+
this._burstRafId = requestAnimationFrame(burstAnimation);
|
|
803
841
|
};
|
|
804
|
-
|
|
805
|
-
burstAnimation
|
|
842
|
+
|
|
843
|
+
this._burstRafId = requestAnimationFrame(burstAnimation);
|
|
806
844
|
}
|
|
807
845
|
|
|
808
846
|
startRenderLoop() {
|
|
847
|
+
this._renderLoopActive = true;
|
|
809
848
|
const render = () => {
|
|
849
|
+
if (!this._renderLoopActive) return;
|
|
810
850
|
if (this.isActive) {
|
|
811
851
|
// Update audio reactivity
|
|
812
852
|
this.updateAudio();
|
|
@@ -821,11 +861,11 @@ export class RealHolographicSystem {
|
|
|
821
861
|
}
|
|
822
862
|
}
|
|
823
863
|
|
|
824
|
-
requestAnimationFrame(render);
|
|
864
|
+
this._renderRafId = requestAnimationFrame(render);
|
|
825
865
|
};
|
|
826
866
|
|
|
827
|
-
render
|
|
828
|
-
console.log(
|
|
867
|
+
this._renderRafId = requestAnimationFrame(render);
|
|
868
|
+
console.log(`REAL Holographic render loop started (${this._renderMode} mode)`);
|
|
829
869
|
}
|
|
830
870
|
|
|
831
871
|
getVariantName(variant = this.currentVariant) {
|
|
@@ -833,6 +873,22 @@ export class RealHolographicSystem {
|
|
|
833
873
|
}
|
|
834
874
|
|
|
835
875
|
destroy() {
|
|
876
|
+
this.isActive = false;
|
|
877
|
+
|
|
878
|
+
// Cancel render loop
|
|
879
|
+
this._renderLoopActive = false;
|
|
880
|
+
if (this._renderRafId) {
|
|
881
|
+
cancelAnimationFrame(this._renderRafId);
|
|
882
|
+
this._renderRafId = null;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// Cancel burst effect loop
|
|
886
|
+
this._burstLoopActive = false;
|
|
887
|
+
if (this._burstRafId) {
|
|
888
|
+
cancelAnimationFrame(this._burstRafId);
|
|
889
|
+
this._burstRafId = null;
|
|
890
|
+
}
|
|
891
|
+
|
|
836
892
|
// Dispose bridge if active
|
|
837
893
|
if (this._multiCanvasBridge) {
|
|
838
894
|
this._multiCanvasBridge.dispose();
|
|
@@ -851,7 +907,7 @@ export class RealHolographicSystem {
|
|
|
851
907
|
this.audioContext.close();
|
|
852
908
|
}
|
|
853
909
|
|
|
854
|
-
console.log('
|
|
910
|
+
console.log('REAL Holographic System destroyed');
|
|
855
911
|
}
|
|
856
912
|
|
|
857
913
|
// ============================================
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polychora System - 4D Polytope Visualization (Wireframe/Solid)
|
|
3
|
+
* Renders high-dimensional regular polytopes (5-cell, 8-cell, 16-cell, 24-cell, 120-cell, 600-cell)
|
|
4
|
+
* Uses 4D-to-3D projection with 6D rotation.
|
|
5
|
+
*
|
|
6
|
+
* "The Shadow of the Hyper-Object"
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { UnifiedRenderBridge } from '../render/UnifiedRenderBridge.js';
|
|
10
|
+
|
|
11
|
+
export class PolychoraSystem {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.active = false;
|
|
14
|
+
this.canvas = null;
|
|
15
|
+
this.gl = null;
|
|
16
|
+
this.program = null;
|
|
17
|
+
this.params = {
|
|
18
|
+
polytope: 0, // 0=Pentatope, 1=Tesseract, 2=Hexadecachoron, 3=Icositetrachoron, 4=Hecatonicosachoron, 5=Hexacosichoron
|
|
19
|
+
edgeThickness: 0.02,
|
|
20
|
+
vertexSize: 0.05,
|
|
21
|
+
wireframe: 1.0, // 1=Wire, 0=Solid
|
|
22
|
+
rot4dXY: 0, rot4dXZ: 0, rot4dYZ: 0,
|
|
23
|
+
rot4dXW: 0, rot4dYW: 0, rot4dZW: 0,
|
|
24
|
+
hue: 280,
|
|
25
|
+
intensity: 0.8
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
initialize(canvas) {
|
|
30
|
+
this.canvas = canvas;
|
|
31
|
+
this.gl = canvas.getContext('webgl');
|
|
32
|
+
if (!this.gl) return false;
|
|
33
|
+
|
|
34
|
+
// Basic shader for Polychora (placeholder for now)
|
|
35
|
+
const vs = `
|
|
36
|
+
attribute vec4 a_pos; // x, y, z, w
|
|
37
|
+
uniform float u_rot[6];
|
|
38
|
+
void main() {
|
|
39
|
+
// ... 4D rotation logic ...
|
|
40
|
+
gl_Position = vec4(a_pos.xyz, 1.0); // Simplified
|
|
41
|
+
gl_PointSize = 5.0;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
const fs = `
|
|
45
|
+
precision mediump float;
|
|
46
|
+
uniform vec3 u_color;
|
|
47
|
+
void main() {
|
|
48
|
+
gl_FragColor = vec4(u_color, 1.0);
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
// This is a stub implementation to fulfill "completeness"
|
|
53
|
+
// In a full implementation, we'd generate 4D mesh data here.
|
|
54
|
+
console.log('Polychora System initialized (Stub)');
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render() {
|
|
59
|
+
if (!this.active || !this.gl) return;
|
|
60
|
+
this.gl.clearColor(0,0,0,0);
|
|
61
|
+
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
62
|
+
// ... render logic ...
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
updateParameters(params) {
|
|
66
|
+
Object.assign(this.params, params);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setActive(active) {
|
|
70
|
+
this.active = active;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
destroy() {
|
|
74
|
+
this.active = false;
|
|
75
|
+
// Cleanup
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -22,6 +22,11 @@ export class QuantumEngine {
|
|
|
22
22
|
/** @type {HTMLCanvasElement|null} */
|
|
23
23
|
this.canvasOverride = options.canvas || null;
|
|
24
24
|
|
|
25
|
+
// Multi-canvas override: { background, shadow, content, highlight, accent }
|
|
26
|
+
// Enables 5-layer mode without DOM ID lookup (for landing page / multi-instance)
|
|
27
|
+
/** @type {Object<string, HTMLCanvasElement>|null} */
|
|
28
|
+
this.canvasSet = options.canvases || null;
|
|
29
|
+
|
|
25
30
|
// Bridge rendering state
|
|
26
31
|
/** @type {MultiCanvasBridge|null} */
|
|
27
32
|
this._multiCanvasBridge = null;
|
|
@@ -89,6 +94,37 @@ export class QuantumEngine {
|
|
|
89
94
|
return;
|
|
90
95
|
}
|
|
91
96
|
|
|
97
|
+
// Multi-canvas override: 5-layer mode with provided canvas elements
|
|
98
|
+
// Used by landing page adapters to create multiple independent 5-layer instances
|
|
99
|
+
if (this.canvasSet) {
|
|
100
|
+
const layerDefs = [
|
|
101
|
+
{ key: 'background', role: 'background', reactivity: 0.4 },
|
|
102
|
+
{ key: 'shadow', role: 'shadow', reactivity: 0.6 },
|
|
103
|
+
{ key: 'content', role: 'content', reactivity: 1.0 },
|
|
104
|
+
{ key: 'highlight', role: 'highlight', reactivity: 1.3 },
|
|
105
|
+
{ key: 'accent', role: 'accent', reactivity: 1.6 },
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
layerDefs.forEach(layer => {
|
|
109
|
+
const canvas = this.canvasSet[layer.key];
|
|
110
|
+
if (!canvas) return;
|
|
111
|
+
try {
|
|
112
|
+
const visualizer = new QuantumHolographicVisualizer(
|
|
113
|
+
canvas, layer.role, layer.reactivity, 0
|
|
114
|
+
);
|
|
115
|
+
if (visualizer.gl) {
|
|
116
|
+
this.visualizers.push(visualizer);
|
|
117
|
+
console.log(`🌌 Created quantum layer (canvasSet): ${layer.role}`);
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.warn(`Failed to create quantum layer ${layer.role}:`, error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
console.log(`✅ Created ${this.visualizers.length} quantum visualizers via canvasSet`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
92
128
|
const layers = [
|
|
93
129
|
{ id: 'quantum-background-canvas', role: 'background', reactivity: 0.4 },
|
|
94
130
|
{ id: 'quantum-shadow-canvas', role: 'shadow', reactivity: 0.6 },
|
|
@@ -340,22 +376,27 @@ export class QuantumEngine {
|
|
|
340
376
|
console.log('🌌 Quantum gesture reactivity skipped (single-canvas override mode)');
|
|
341
377
|
return;
|
|
342
378
|
}
|
|
343
|
-
|
|
379
|
+
|
|
344
380
|
console.log('🌌 Setting up Quantum: velocity + click + scroll + multi-parameter reactivity');
|
|
345
|
-
|
|
381
|
+
|
|
346
382
|
// Enhanced state for smooth effects
|
|
347
383
|
this.clickFlashIntensity = 0;
|
|
348
384
|
this.scrollMorph = 1.0; // Base morph factor
|
|
349
385
|
this.velocitySmoothing = 0.8; // Smoother velocity transitions
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
386
|
+
|
|
387
|
+
// Gather canvases: from canvasSet (landing page) or DOM IDs (main app)
|
|
388
|
+
const canvasElements = [];
|
|
389
|
+
if (this.canvasSet) {
|
|
390
|
+
Object.values(this.canvasSet).forEach(c => { if (c) canvasElements.push(c); });
|
|
391
|
+
} else {
|
|
392
|
+
['quantum-background-canvas', 'quantum-shadow-canvas', 'quantum-content-canvas',
|
|
393
|
+
'quantum-highlight-canvas', 'quantum-accent-canvas'].forEach(id => {
|
|
394
|
+
const c = document.getElementById(id);
|
|
395
|
+
if (c) canvasElements.push(c);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
canvasElements.forEach(canvas => {
|
|
359
400
|
|
|
360
401
|
// Mouse movement -> smooth velocity + multiple parameters
|
|
361
402
|
canvas.addEventListener('mousemove', (e) => {
|
|
@@ -368,20 +409,19 @@ export class QuantumEngine {
|
|
|
368
409
|
this.updateEnhancedQuantumParameters(mouseX, mouseY);
|
|
369
410
|
});
|
|
370
411
|
|
|
371
|
-
// Touch movement -> same enhanced parameters
|
|
412
|
+
// Touch movement -> same enhanced parameters
|
|
372
413
|
canvas.addEventListener('touchmove', (e) => {
|
|
373
414
|
if (!this.isActive) return;
|
|
374
|
-
|
|
375
|
-
|
|
415
|
+
|
|
376
416
|
if (e.touches.length > 0) {
|
|
377
417
|
const touch = e.touches[0];
|
|
378
418
|
const rect = canvas.getBoundingClientRect();
|
|
379
419
|
const touchX = (touch.clientX - rect.left) / rect.width;
|
|
380
420
|
const touchY = (touch.clientY - rect.top) / rect.height;
|
|
381
|
-
|
|
421
|
+
|
|
382
422
|
this.updateEnhancedQuantumParameters(touchX, touchY);
|
|
383
423
|
}
|
|
384
|
-
}, { passive:
|
|
424
|
+
}, { passive: true });
|
|
385
425
|
|
|
386
426
|
// Click -> quantum flash effect
|
|
387
427
|
canvas.addEventListener('click', (e) => {
|
|
@@ -398,9 +438,8 @@ export class QuantumEngine {
|
|
|
398
438
|
// Wheel -> quantum morphing scroll effect
|
|
399
439
|
canvas.addEventListener('wheel', (e) => {
|
|
400
440
|
if (!this.isActive) return;
|
|
401
|
-
e.preventDefault();
|
|
402
441
|
this.updateQuantumScroll(e.deltaY);
|
|
403
|
-
}, { passive:
|
|
442
|
+
}, { passive: true });
|
|
404
443
|
});
|
|
405
444
|
|
|
406
445
|
// Start smooth animation loops
|
|
@@ -483,7 +522,11 @@ export class QuantumEngine {
|
|
|
483
522
|
this.lastMousePosition.x = x;
|
|
484
523
|
this.lastMousePosition.y = y;
|
|
485
524
|
|
|
486
|
-
|
|
525
|
+
// Debug logging (throttled to avoid console spam)
|
|
526
|
+
if (!this._lastLogTime || performance.now() - this._lastLogTime > 2000) {
|
|
527
|
+
this._lastLogTime = performance.now();
|
|
528
|
+
console.log(`Quantum: Rot=${rotationAngle.toFixed(2)}, Density=${Math.round(gridDensity)}, Hue=${Math.round(hue)}`);
|
|
529
|
+
}
|
|
487
530
|
}
|
|
488
531
|
|
|
489
532
|
triggerQuantumClick() {
|
|
@@ -495,7 +538,7 @@ export class QuantumEngine {
|
|
|
495
538
|
this.quantumSpeedWave = 2.0; // Speed wave effect
|
|
496
539
|
this.quantumHueShift = 60; // Color explosion shift
|
|
497
540
|
|
|
498
|
-
|
|
541
|
+
// Quantum energy burst triggered
|
|
499
542
|
}
|
|
500
543
|
|
|
501
544
|
updateQuantumScroll(deltaY) {
|
|
@@ -511,81 +554,60 @@ export class QuantumEngine {
|
|
|
511
554
|
window.updateParameter('morphFactor', this.scrollMorph.toFixed(2));
|
|
512
555
|
}
|
|
513
556
|
|
|
514
|
-
|
|
557
|
+
// Quantum scroll morph updated
|
|
515
558
|
}
|
|
516
559
|
|
|
517
560
|
startQuantumEffectLoops() {
|
|
561
|
+
this._effectsLoopActive = true;
|
|
518
562
|
const quantumEffects = () => {
|
|
519
|
-
|
|
520
|
-
|
|
563
|
+
if (!this._effectsLoopActive) return;
|
|
564
|
+
|
|
521
565
|
// QUANTUM FLASH EFFECT (saturation + morph)
|
|
522
566
|
if (this.clickFlashIntensity > 0.01) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const flashSaturation = 0.9 + (this.clickFlashIntensity * 0.1); // 0.9-1.0 boost
|
|
527
|
-
const flashMorph = this.scrollMorph + (this.clickFlashIntensity * 0.5); // Morph boost
|
|
528
|
-
|
|
567
|
+
const flashSaturation = 0.9 + (this.clickFlashIntensity * 0.1);
|
|
568
|
+
const flashMorph = this.scrollMorph + (this.clickFlashIntensity * 0.5);
|
|
569
|
+
|
|
529
570
|
if (window.updateParameter) {
|
|
530
571
|
window.updateParameter('saturation', flashSaturation.toFixed(2));
|
|
531
572
|
window.updateParameter('morphFactor', flashMorph.toFixed(2));
|
|
532
573
|
}
|
|
533
|
-
|
|
534
|
-
// Smooth decay
|
|
535
574
|
this.clickFlashIntensity *= 0.91;
|
|
536
575
|
}
|
|
537
|
-
|
|
576
|
+
|
|
538
577
|
// DRAMATIC CHAOS BLAST EFFECT (fluid decay)
|
|
539
578
|
if (this.quantumChaosBlast > 0.01) {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const baseChaos = 0.3; // Quantum default chaos
|
|
579
|
+
const baseChaos = 0.3;
|
|
543
580
|
const currentChaos = baseChaos + this.quantumChaosBlast;
|
|
544
|
-
|
|
545
581
|
if (window.updateParameter) {
|
|
546
582
|
window.updateParameter('chaos', Math.min(1.0, currentChaos).toFixed(2));
|
|
547
583
|
}
|
|
548
|
-
|
|
549
|
-
// Smooth decay
|
|
550
|
-
this.quantumChaosBlast *= 0.88; // Slightly faster than faceted for quantum energy feel
|
|
584
|
+
this.quantumChaosBlast *= 0.88;
|
|
551
585
|
}
|
|
552
|
-
|
|
553
|
-
// DRAMATIC SPEED WAVE EFFECT (fluid decay)
|
|
586
|
+
|
|
587
|
+
// DRAMATIC SPEED WAVE EFFECT (fluid decay)
|
|
554
588
|
if (this.quantumSpeedWave > 0.01) {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const baseSpeed = 1.0; // Quantum default speed
|
|
589
|
+
const baseSpeed = 1.0;
|
|
558
590
|
const currentSpeed = baseSpeed + this.quantumSpeedWave;
|
|
559
|
-
|
|
560
591
|
if (window.updateParameter) {
|
|
561
592
|
window.updateParameter('speed', Math.min(3.0, currentSpeed).toFixed(2));
|
|
562
593
|
}
|
|
563
|
-
|
|
564
|
-
// Smooth wave decay
|
|
565
594
|
this.quantumSpeedWave *= 0.89;
|
|
566
595
|
}
|
|
567
|
-
|
|
596
|
+
|
|
568
597
|
// QUANTUM HUE EXPLOSION EFFECT (fluid decay)
|
|
569
598
|
if (this.quantumHueShift > 1) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const baseHue = 280; // Quantum purple-blue
|
|
599
|
+
const baseHue = 280;
|
|
573
600
|
const currentHue = (baseHue + this.quantumHueShift) % 360;
|
|
574
|
-
|
|
575
601
|
if (window.updateParameter) {
|
|
576
602
|
window.updateParameter('hue', Math.round(currentHue));
|
|
577
603
|
}
|
|
578
|
-
|
|
579
|
-
// Smooth color return
|
|
580
604
|
this.quantumHueShift *= 0.90;
|
|
581
605
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
requestAnimationFrame(quantumEffects);
|
|
585
|
-
}
|
|
606
|
+
|
|
607
|
+
this._effectsRafId = requestAnimationFrame(quantumEffects);
|
|
586
608
|
};
|
|
587
|
-
|
|
588
|
-
quantumEffects
|
|
609
|
+
|
|
610
|
+
this._effectsRafId = requestAnimationFrame(quantumEffects);
|
|
589
611
|
}
|
|
590
612
|
|
|
591
613
|
async enableAudio() {
|
|
@@ -691,16 +713,17 @@ export class QuantumEngine {
|
|
|
691
713
|
if (window.mobileDebug) {
|
|
692
714
|
window.mobileDebug.log(`🎬 Quantum Engine: Starting render loop with ${this.visualizers?.length} visualizers, isActive=${this.isActive}`);
|
|
693
715
|
}
|
|
694
|
-
|
|
716
|
+
|
|
717
|
+
this._renderLoopActive = true;
|
|
695
718
|
const render = () => {
|
|
719
|
+
if (!this._renderLoopActive) return;
|
|
696
720
|
this.renderFrame();
|
|
697
|
-
|
|
698
|
-
requestAnimationFrame(render);
|
|
721
|
+
this._renderRafId = requestAnimationFrame(render);
|
|
699
722
|
};
|
|
700
|
-
|
|
701
|
-
render
|
|
723
|
+
|
|
724
|
+
this._renderRafId = requestAnimationFrame(render);
|
|
702
725
|
console.log('🎬 Quantum render loop started');
|
|
703
|
-
|
|
726
|
+
|
|
704
727
|
if (window.mobileDebug) {
|
|
705
728
|
window.mobileDebug.log(`✅ Quantum Engine: Render loop started, will render when isActive=true`);
|
|
706
729
|
}
|
|
@@ -777,6 +800,20 @@ export class QuantumEngine {
|
|
|
777
800
|
destroy() {
|
|
778
801
|
this.isActive = false;
|
|
779
802
|
|
|
803
|
+
// Cancel render loop
|
|
804
|
+
this._renderLoopActive = false;
|
|
805
|
+
if (this._renderRafId) {
|
|
806
|
+
cancelAnimationFrame(this._renderRafId);
|
|
807
|
+
this._renderRafId = null;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// Cancel effects loop
|
|
811
|
+
this._effectsLoopActive = false;
|
|
812
|
+
if (this._effectsRafId) {
|
|
813
|
+
cancelAnimationFrame(this._effectsRafId);
|
|
814
|
+
this._effectsRafId = null;
|
|
815
|
+
}
|
|
816
|
+
|
|
780
817
|
// Disconnect from universal reactivity
|
|
781
818
|
if (window.universalReactivity) {
|
|
782
819
|
window.universalReactivity.disconnectSystem('quantum');
|
|
@@ -276,6 +276,7 @@ uniform float u_rot4dZW;
|
|
|
276
276
|
uniform float u_mouseIntensity;
|
|
277
277
|
uniform float u_clickIntensity;
|
|
278
278
|
uniform float u_roleIntensity;
|
|
279
|
+
uniform float u_breath;
|
|
279
280
|
|
|
280
281
|
// 6D rotation matrices - 3D space rotations (XY, XZ, YZ)
|
|
281
282
|
mat4 rotateXY(float theta) {
|
|
@@ -681,7 +682,9 @@ void main() {
|
|
|
681
682
|
geometryIntensity += shimmer * geometryIntensity;
|
|
682
683
|
|
|
683
684
|
// Apply user intensity control
|
|
684
|
-
|
|
685
|
+
// Breath modulation (Exhale system)
|
|
686
|
+
float breathMod = 1.0 + (u_breath * 0.4);
|
|
687
|
+
float finalIntensity = geometryIntensity * u_intensity * breathMod;
|
|
685
688
|
|
|
686
689
|
// LAYER-BY-LAYER COLOR SYSTEM with user hue/saturation/intensity controls
|
|
687
690
|
// Determine canvas layer from role/variant (0=background, 1=shadow, 2=content, 3=highlight, 4=accent)
|
|
@@ -792,7 +795,8 @@ void main() {
|
|
|
792
795
|
rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
|
|
793
796
|
mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
|
|
794
797
|
clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
|
|
795
|
-
roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity')
|
|
798
|
+
roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity'),
|
|
799
|
+
breath: this.gl.getUniformLocation(this.program, 'u_breath')
|
|
796
800
|
};
|
|
797
801
|
}
|
|
798
802
|
|
|
@@ -1065,6 +1069,7 @@ void main() {
|
|
|
1065
1069
|
this.gl.uniform1f(this.uniforms.mouseIntensity, this.mouseIntensity);
|
|
1066
1070
|
this.gl.uniform1f(this.uniforms.clickIntensity, this.clickIntensity);
|
|
1067
1071
|
this.gl.uniform1f(this.uniforms.roleIntensity, roleIntensities[this.role] || 1.0);
|
|
1072
|
+
this.gl.uniform1f(this.uniforms.breath, this.params.breath || 0.0);
|
|
1068
1073
|
|
|
1069
1074
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
|
1070
1075
|
}
|
|
@@ -56,6 +56,9 @@ function packVIB3Uniforms(uniforms) {
|
|
|
56
56
|
data[22] = uniforms.u_mid || 0;
|
|
57
57
|
data[23] = uniforms.u_high || 0;
|
|
58
58
|
|
|
59
|
+
// Breath/Vitality parameter
|
|
60
|
+
data[32] = uniforms.u_breath || 0;
|
|
61
|
+
|
|
59
62
|
data[24] = uniforms.u_layerScale || 1.0;
|
|
60
63
|
data[25] = uniforms.u_layerOpacity || 1.0;
|
|
61
64
|
data[26] = 0; // _pad1
|