@vib3code/sdk 2.0.1 → 2.0.3-canary.0a63e71

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 (192) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +245 -0
  3. package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
  4. package/DOCS/ARCHITECTURE.md +1 -0
  5. package/DOCS/CI_TESTING.md +2 -0
  6. package/DOCS/CLI_ONBOARDING.md +3 -1
  7. package/DOCS/CONTROL_REFERENCE.md +2 -0
  8. package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +119 -0
  9. package/DOCS/ENV_SETUP.md +2 -0
  10. package/DOCS/EPIC_SCROLL_EVENTS.md +775 -0
  11. package/DOCS/EXPANSION_DESIGN.md +979 -0
  12. package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
  13. package/DOCS/EXPORT_FORMATS.md +2 -0
  14. package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
  15. package/DOCS/HANDOFF_LANDING_PAGE.md +156 -0
  16. package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +495 -0
  17. package/DOCS/LICENSING_TIERS.md +2 -0
  18. package/DOCS/MASTER_PLAN_2026-01-31.md +4 -2
  19. package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +939 -0
  20. package/DOCS/OBS_SETUP_GUIDE.md +2 -0
  21. package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
  22. package/DOCS/PRODUCT_STRATEGY.md +65 -0
  23. package/DOCS/PROJECT_SETUP.md +2 -0
  24. package/DOCS/README.md +105 -0
  25. package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +99 -0
  26. package/DOCS/RENDERER_LIFECYCLE.md +2 -0
  27. package/DOCS/REPO_MANIFEST.md +2 -0
  28. package/DOCS/ROADMAP.md +113 -0
  29. package/DOCS/SCROLL_TIMELINE_v3.md +271 -0
  30. package/DOCS/SITE_REFACTOR_PLAN.md +102 -0
  31. package/DOCS/STATUS.md +26 -0
  32. package/DOCS/SYSTEM_INVENTORY.md +37 -32
  33. package/DOCS/TELEMETRY_EXPORTS.md +2 -0
  34. package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +87 -0
  35. package/DOCS/VISUAL_ANALYSIS_FACETAD.md +135 -0
  36. package/DOCS/VISUAL_ANALYSIS_SIMONE.md +97 -0
  37. package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +88 -0
  38. package/DOCS/WEBGPU_STATUS.md +121 -38
  39. package/DOCS/XR_BENCHMARKS.md +2 -0
  40. package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -0
  41. package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -0
  42. package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -0
  43. package/DOCS/archive/SESSION_014_PLAN.md +1 -0
  44. package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -0
  45. package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -0
  46. package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -0
  47. package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -0
  48. package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +3 -1
  49. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +233 -0
  50. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +129 -0
  51. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -0
  52. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
  53. package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
  54. package/DOCS/dev-tracks/README.md +12 -0
  55. package/README.md +26 -13
  56. package/cpp/CMakeLists.txt +236 -0
  57. package/cpp/bindings/embind.cpp +269 -0
  58. package/cpp/build.sh +129 -0
  59. package/cpp/geometry/Crystal.cpp +103 -0
  60. package/cpp/geometry/Fractal.cpp +136 -0
  61. package/cpp/geometry/GeometryGenerator.cpp +262 -0
  62. package/cpp/geometry/KleinBottle.cpp +71 -0
  63. package/cpp/geometry/Sphere.cpp +134 -0
  64. package/cpp/geometry/Tesseract.cpp +94 -0
  65. package/cpp/geometry/Tetrahedron.cpp +83 -0
  66. package/cpp/geometry/Torus.cpp +65 -0
  67. package/cpp/geometry/WarpFunctions.cpp +238 -0
  68. package/cpp/geometry/Wave.cpp +85 -0
  69. package/cpp/include/vib3_ffi.h +238 -0
  70. package/cpp/math/Mat4x4.cpp +409 -0
  71. package/cpp/math/Mat4x4.hpp +209 -0
  72. package/cpp/math/Projection.cpp +142 -0
  73. package/cpp/math/Projection.hpp +148 -0
  74. package/cpp/math/Rotor4D.cpp +322 -0
  75. package/cpp/math/Rotor4D.hpp +204 -0
  76. package/cpp/math/Vec4.cpp +303 -0
  77. package/cpp/math/Vec4.hpp +225 -0
  78. package/cpp/src/vib3_ffi.cpp +607 -0
  79. package/cpp/tests/Geometry_test.cpp +213 -0
  80. package/cpp/tests/Mat4x4_test.cpp +494 -0
  81. package/cpp/tests/Projection_test.cpp +298 -0
  82. package/cpp/tests/Rotor4D_test.cpp +423 -0
  83. package/cpp/tests/Vec4_test.cpp +489 -0
  84. package/docs/webgpu-live.html +1 -1
  85. package/package.json +41 -30
  86. package/src/agent/index.js +1 -3
  87. package/src/agent/mcp/MCPServer.js +1220 -144
  88. package/src/agent/mcp/index.js +1 -1
  89. package/src/agent/mcp/stdio-server.js +264 -0
  90. package/src/agent/mcp/tools.js +498 -31
  91. package/src/cli/index.js +431 -47
  92. package/src/core/CanvasManager.js +97 -204
  93. package/src/core/ErrorReporter.js +1 -1
  94. package/src/core/Parameters.js +1 -1
  95. package/src/core/VIB3Engine.js +93 -4
  96. package/src/core/VitalitySystem.js +53 -0
  97. package/src/core/index.js +18 -0
  98. package/src/core/renderers/FacetedRendererAdapter.js +10 -9
  99. package/src/core/renderers/HolographicRendererAdapter.js +13 -9
  100. package/src/core/renderers/QuantumRendererAdapter.js +11 -7
  101. package/src/creative/AestheticMapper.js +628 -0
  102. package/src/creative/ChoreographyPlayer.js +481 -0
  103. package/src/creative/index.js +11 -0
  104. package/src/experimental/GameLoop.js +72 -0
  105. package/src/experimental/LatticePhysics.js +100 -0
  106. package/src/experimental/LiveDirector.js +143 -0
  107. package/src/experimental/PlayerController4D.js +154 -0
  108. package/src/experimental/VIB3Actor.js +138 -0
  109. package/src/experimental/VIB3Compositor.js +117 -0
  110. package/src/experimental/VIB3Link.js +122 -0
  111. package/src/experimental/VIB3Orchestrator.js +146 -0
  112. package/src/experimental/VIB3Universe.js +109 -0
  113. package/src/experimental/demos/CrystalLabyrinth.js +202 -0
  114. package/src/export/TradingCardManager.js +3 -4
  115. package/src/export/index.js +11 -1
  116. package/src/faceted/FacetedSystem.js +260 -394
  117. package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
  118. package/src/geometry/generators/Crystal.js +2 -2
  119. package/src/geometry/warp/HypersphereCore.js +53 -24
  120. package/src/holograms/HolographicVisualizer.js +84 -98
  121. package/src/holograms/RealHolographicSystem.js +194 -43
  122. package/src/math/Mat4x4.js +308 -105
  123. package/src/math/Rotor4D.js +124 -40
  124. package/src/math/Vec4.js +200 -103
  125. package/src/math/index.js +7 -7
  126. package/src/polychora/PolychoraSystem.js +77 -0
  127. package/src/quantum/QuantumEngine.js +103 -66
  128. package/src/quantum/QuantumVisualizer.js +31 -22
  129. package/src/reactivity/index.js +3 -5
  130. package/src/render/LayerPresetManager.js +372 -0
  131. package/src/render/LayerReactivityBridge.js +344 -0
  132. package/src/render/LayerRelationshipGraph.js +610 -0
  133. package/src/render/MultiCanvasBridge.js +148 -25
  134. package/src/render/ShaderLoader.js +38 -0
  135. package/src/render/ShaderProgram.js +4 -4
  136. package/src/render/UnifiedRenderBridge.js +4 -1
  137. package/src/render/backends/WebGPUBackend.js +8 -4
  138. package/src/render/index.js +27 -2
  139. package/src/scene/Node4D.js +74 -24
  140. package/src/scene/index.js +4 -4
  141. package/src/shaders/common/geometry24.glsl +65 -0
  142. package/src/shaders/common/geometry24.wgsl +54 -0
  143. package/src/shaders/common/rotation4d.glsl +4 -4
  144. package/src/shaders/common/rotation4d.wgsl +2 -2
  145. package/src/shaders/common/uniforms.wgsl +15 -8
  146. package/src/shaders/faceted/faceted.frag.glsl +220 -80
  147. package/src/shaders/faceted/faceted.frag.wgsl +144 -90
  148. package/src/shaders/holographic/holographic.frag.glsl +28 -9
  149. package/src/shaders/holographic/holographic.frag.wgsl +112 -41
  150. package/src/shaders/quantum/quantum.frag.glsl +1 -0
  151. package/src/shaders/quantum/quantum.frag.wgsl +6 -4
  152. package/src/testing/ParallelTestFramework.js +2 -2
  153. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
  154. package/src/viewer/GalleryUI.js +17 -0
  155. package/src/viewer/ViewerPortal.js +2 -2
  156. package/src/viewer/index.js +1 -1
  157. package/tools/headless-renderer.js +258 -0
  158. package/tools/shader-sync-verify.js +14 -8
  159. package/tools/site-analysis/all-reports.json +32 -0
  160. package/tools/site-analysis/combined-analysis.md +50 -0
  161. package/tools/site-analyzer.mjs +779 -0
  162. package/tools/visual-catalog/capture.js +276 -0
  163. package/tools/visual-catalog/composite.js +138 -0
  164. package/types/adaptive-sdk.d.ts +204 -5
  165. package/types/agent/cli.d.ts +78 -0
  166. package/types/agent/index.d.ts +18 -0
  167. package/types/agent/mcp.d.ts +87 -0
  168. package/types/agent/telemetry.d.ts +190 -0
  169. package/types/core/VIB3Engine.d.ts +26 -0
  170. package/types/core/index.d.ts +261 -0
  171. package/types/creative/AestheticMapper.d.ts +72 -0
  172. package/types/creative/ChoreographyPlayer.d.ts +96 -0
  173. package/types/creative/index.d.ts +17 -0
  174. package/types/export/index.d.ts +243 -0
  175. package/types/geometry/index.d.ts +164 -0
  176. package/types/math/index.d.ts +214 -0
  177. package/types/render/LayerPresetManager.d.ts +78 -0
  178. package/types/render/LayerReactivityBridge.d.ts +85 -0
  179. package/types/render/LayerRelationshipGraph.d.ts +174 -0
  180. package/types/render/index.d.ts +3 -0
  181. package/types/scene/index.d.ts +204 -0
  182. package/types/systems/index.d.ts +244 -0
  183. package/types/variations/index.d.ts +62 -0
  184. package/types/viewer/index.d.ts +225 -0
  185. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +0 -34
  186. package/DOCS/DEV_TRACK_ANALYSIS.md +0 -77
  187. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +0 -42
  188. package/DOCS/SESSION_014_PLAN.md +0 -195
  189. package/DOCS/SESSION_LOG_2026-01-07.md +0 -56
  190. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +0 -72
  191. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +0 -738
  192. /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
@@ -50,6 +50,7 @@ const FRAGMENT_SHADER_GLSL = `
50
50
  uniform float u_bass;
51
51
  uniform float u_mid;
52
52
  uniform float u_high;
53
+ uniform float u_breath; // Vitality System Breath (0.0 - 1.0)
53
54
 
54
55
  // ── 6D Rotation Matrices ──
55
56
 
@@ -159,10 +160,16 @@ const FRAGMENT_SHADER_GLSL = `
159
160
  int geomType = int(clamp(floor(baseGeomFloat + 0.5), 0.0, totalBase - 1.0));
160
161
 
161
162
  if (geomType == 0) {
162
- // Tetrahedron lattice
163
- vec4 pos = fract(p * u_gridDensity * 0.08);
164
- vec4 dist = min(pos, 1.0 - pos);
165
- return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
163
+ // Tetrahedron lattice — tetrahedral symmetry planes
164
+ float d = u_gridDensity * 0.08;
165
+ vec3 c1 = normalize(vec3(1.0, 1.0, 1.0));
166
+ vec3 c2 = normalize(vec3(-1.0, -1.0, 1.0));
167
+ vec3 c3 = normalize(vec3(-1.0, 1.0, -1.0));
168
+ vec3 c4 = normalize(vec3(1.0, -1.0, -1.0));
169
+ vec3 q = fract(p.xyz * d + 0.5) - 0.5;
170
+ float minPlane = min(min(abs(dot(q, c1)), abs(dot(q, c2))),
171
+ min(abs(dot(q, c3)), abs(dot(q, c4))));
172
+ return (1.0 - smoothstep(0.0, 0.05, minPlane)) * u_morphFactor;
166
173
  }
167
174
  else if (geomType == 1) {
168
175
  // Hypercube lattice
@@ -267,7 +274,11 @@ const FRAGMENT_SHADER_GLSL = `
267
274
  // Intensity from lattice
268
275
  float geometryIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
269
276
  geometryIntensity += u_clickIntensity * 0.3;
270
- float finalIntensity = geometryIntensity * u_intensity;
277
+
278
+ // Exhale: Vitality Breath Modulation
279
+ float breathMod = 1.0 + (u_breath * 0.3); // +30% intensity at full breath
280
+
281
+ float finalIntensity = geometryIntensity * u_intensity * breathMod;
271
282
 
272
283
  // Audio-reactive hue shift
273
284
  float hue = u_hue / 360.0 + value * 0.1 + u_high * 0.08;
@@ -283,7 +294,7 @@ const FRAGMENT_SHADER_GLSL = `
283
294
  float gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
284
295
  vec3 color = mix(vec3(gray), baseColor, u_saturation) * finalIntensity;
285
296
 
286
- gl_FragColor = vec4(color, finalIntensity * u_roleIntensity);
297
+ gl_FragColor = vec4(color, finalIntensity);
287
298
  }
288
299
  `;
289
300
 
@@ -291,7 +302,7 @@ const FRAGMENT_SHADER_GLSL = `
291
302
  const FRAGMENT_SHADER_WGSL = `
292
303
  struct VIB3Uniforms {
293
304
  time: f32,
294
- speed: f32,
305
+ _pad0: f32,
295
306
  resolution: vec2<f32>,
296
307
  geometry: f32,
297
308
  rot4dXY: f32,
@@ -304,18 +315,24 @@ struct VIB3Uniforms {
304
315
  gridDensity: f32,
305
316
  morphFactor: f32,
306
317
  chaos: f32,
318
+ speed: f32,
307
319
  hue: f32,
308
320
  intensity: f32,
309
321
  saturation: f32,
310
322
  mouseIntensity: f32,
311
323
  clickIntensity: f32,
312
- roleIntensity: f32,
313
324
  bass: f32,
314
325
  mid: f32,
315
326
  high: f32,
316
- _pad0: f32,
317
- mouse: vec2<f32>,
318
- _pad1: vec2<f32>,
327
+ layerScale: f32,
328
+ layerOpacity: f32,
329
+ _pad1: f32,
330
+ layerColorR: f32,
331
+ layerColorG: f32,
332
+ layerColorB: f32,
333
+ densityMult: f32,
334
+ speedMult: f32,
335
+ breath: f32, // Index 32
319
336
  };
320
337
 
321
338
  @group(0) @binding(0) var<uniform> u: VIB3Uniforms;
@@ -406,7 +423,7 @@ fn warpHypertetraCore_w(p: vec3<f32>, geomIdx: i32) -> vec3<f32> {
406
423
  fn applyCoreWarp_w(p: vec3<f32>, geomType: f32, mouseDelta: vec2<f32>) -> vec3<f32> {
407
424
  let coreFloat = floor(geomType / 8.0);
408
425
  let coreIndex = i32(clamp(coreFloat, 0.0, 2.0));
409
- let baseFloat = geomType - coreFloat * 8.0;
426
+ let baseFloat = geomType - floor(geomType / 8.0) * 8.0;
410
427
  let geomIdx = i32(clamp(floor(baseFloat + 0.5), 0.0, 7.0));
411
428
  if (coreIndex == 1) { return warpHypersphereCore_w(p, geomIdx); }
412
429
  if (coreIndex == 2) { return warpHypertetraCore_w(p, geomIdx); }
@@ -418,8 +435,15 @@ fn geometryFunction_w(p: vec4<f32>) -> f32 {
418
435
  let gt = i32(clamp(floor(baseFloat + 0.5), 0.0, 7.0));
419
436
  let d = u.gridDensity * 0.08;
420
437
  if (gt == 0) {
421
- let pos = fract(p * d); let dist = min(pos, 1.0 - pos);
422
- return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u.morphFactor;
438
+ // Tetrahedron tetrahedral symmetry planes
439
+ let c1 = normalize(vec3<f32>(1.0, 1.0, 1.0));
440
+ let c2 = normalize(vec3<f32>(-1.0, -1.0, 1.0));
441
+ let c3 = normalize(vec3<f32>(-1.0, 1.0, -1.0));
442
+ let c4 = normalize(vec3<f32>(1.0, -1.0, -1.0));
443
+ let q = fract(p.xyz * d + 0.5) - 0.5;
444
+ let minPlane = min(min(abs(dot(q, c1)), abs(dot(q, c2))),
445
+ min(abs(dot(q, c3)), abs(dot(q, c4))));
446
+ return (1.0 - smoothstep(0.0, 0.05, minPlane)) * u.morphFactor;
423
447
  } else if (gt == 1) {
424
448
  let pos = fract(p * d); let dist = min(pos, 1.0 - pos);
425
449
  return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u.morphFactor;
@@ -459,7 +483,7 @@ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
459
483
  let timeSpeed = u.time * 0.0001 * u.speed;
460
484
 
461
485
  var pos = vec4<f32>(uv2 * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
462
- pos = vec4<f32>(pos.xy + (u.mouse - 0.5) * u.mouseIntensity * 2.0, pos.z, pos.w);
486
+ pos = vec4<f32>(pos.xy + (vec2<f32>(0.5, 0.5) - 0.5) * u.mouseIntensity * 2.0, pos.z, pos.w);
463
487
 
464
488
  pos = rotateXY_w(u.rot4dXY) * pos;
465
489
  pos = rotateXZ_w(u.rot4dXZ) * pos;
@@ -469,7 +493,7 @@ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
469
493
  pos = rotateZW_w(u.rot4dZW) * pos;
470
494
 
471
495
  let basePoint = project4Dto3D_w(pos);
472
- let warpedPoint = applyCoreWarp_w(basePoint, u.geometry, u.mouse - 0.5);
496
+ let warpedPoint = applyCoreWarp_w(basePoint, u.geometry, vec2<f32>(0.0, 0.0));
473
497
  let warpedPos = vec4<f32>(warpedPoint, pos.w);
474
498
  var value = geometryFunction_w(warpedPos);
475
499
 
@@ -478,7 +502,10 @@ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
478
502
 
479
503
  var geomIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
480
504
  geomIntensity += u.clickIntensity * 0.3;
481
- let finalIntensity = geomIntensity * u.intensity;
505
+
506
+ // Vitality (Breath) modulation
507
+ let breathMod = 1.0 + (u.breath * 0.3);
508
+ let finalIntensity = geomIntensity * u.intensity * breathMod;
482
509
 
483
510
  let hueVal = u.hue / 360.0 + value * 0.1 + u.high * 0.08;
484
511
  let baseColor = vec3<f32>(
@@ -488,7 +515,7 @@ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
488
515
  let gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
489
516
  let color = mix(vec3<f32>(gray), baseColor, u.saturation) * finalIntensity;
490
517
 
491
- return vec4<f32>(color, finalIntensity * u.roleIntensity);
518
+ return vec4<f32>(color, finalIntensity);
492
519
  }
493
520
  `;
494
521
 
@@ -498,466 +525,305 @@ fn main(input: VertexOutput) -> @location(0) vec4<f32> {
498
525
 
499
526
  export class FacetedSystem {
500
527
  constructor() {
528
+ this.bridge = null;
501
529
  this.canvas = null;
502
530
  this.gl = null;
503
531
  this.program = null;
504
- this.isActive = false;
505
- this.time = 0;
506
- this.parameters = {
507
- geometry: 0,
508
- rot4dXY: 0, rot4dXZ: 0, rot4dYZ: 0,
509
- rot4dXW: 0, rot4dYW: 0, rot4dZW: 0,
510
- gridDensity: 15,
511
- morphFactor: 1.0,
512
- chaos: 0.2,
513
- speed: 1.0,
514
- hue: 200,
515
- intensity: 0.7,
516
- saturation: 0.8,
517
- dimension: 3.5,
518
- mouseX: 0.5,
519
- mouseY: 0.5,
520
- mouseIntensity: 0.0,
521
- clickIntensity: 0.0,
522
- roleIntensity: 1.0,
523
- bass: 0.0,
524
- mid: 0.0,
525
- high: 0.0
526
- };
527
-
528
- /** @type {UnifiedRenderBridge|null} */
529
- this._bridge = null;
530
-
531
- /** @type {'direct'|'bridge'} Rendering mode */
532
- this._renderMode = 'direct';
532
+ this.params = {};
533
+ this.initialized = false;
534
+ this.contextLost = false;
535
+ this._animFrame = null;
536
+ this._time = 0;
537
+ this._running = false;
538
+ this._quadBuffer = null;
539
+ this._uniformLocations = {};
540
+ this._useDirectGL = false;
533
541
  }
534
542
 
543
+ // ─── Synchronous Direct WebGL Init (matches Quantum/Holographic pattern) ───
544
+
535
545
  /**
536
- * Initialize with UnifiedRenderBridge for WebGL/WebGPU abstraction.
537
- * @param {HTMLCanvasElement} canvas
538
- * @param {object} [options]
539
- * @param {boolean} [options.preferWebGPU=true]
540
- * @param {boolean} [options.debug=false]
541
- * @returns {Promise<boolean>}
546
+ * Initialize directly with WebGL on a given canvas.
547
+ * Synchronous no async bridge, no WebGPU.
548
+ * This is the preferred path for the landing page and adapters.
542
549
  */
543
- async initWithBridge(canvas, options = {}) {
550
+ initDirect(canvas) {
544
551
  this.canvas = canvas;
545
552
  try {
546
- this._bridge = await UnifiedRenderBridge.create(canvas, options);
547
-
548
- // Try loading external shader files first, fall back to inline
549
- let sources = {
550
- glslVertex: VERTEX_SHADER_GLSL,
551
- glslFragment: FRAGMENT_SHADER_GLSL,
552
- wgslFragment: FRAGMENT_SHADER_WGSL
553
- };
554
-
555
- try {
556
- const external = await shaderLoader.loadShaderPair('faceted', 'faceted/faceted.frag');
557
- if (external.glslFragment) {
558
- sources.glslFragment = external.glslFragment;
559
- }
560
- if (external.wgslFragment) {
561
- sources.wgslFragment = external.wgslFragment;
562
- }
563
- if (external.glslVertex) {
564
- sources.glslVertex = external.glslVertex;
565
- }
566
- } catch (loadErr) {
567
- // External load failed — use inline shaders (already set above)
568
- }
569
-
570
- const compiled = this._bridge.compileShader('faceted', sources);
571
-
572
- if (!compiled) {
573
- console.error('Failed to compile faceted shaders via bridge');
574
- return false;
575
- }
576
-
577
- this._renderMode = 'bridge';
578
- console.log(`Faceted System initialized via ${this._bridge.getBackendType()} bridge`);
579
- return true;
553
+ this.gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
580
554
  } catch (e) {
581
- console.error('Faceted bridge init failed, falling back to direct:', e);
582
- return this.initialize(canvas);
583
- }
584
- }
585
-
586
- /**
587
- * Initialize faceted system (direct WebGL mode)
588
- * Finds canvas by ID in DOM (matches reference architecture)
589
- */
590
- initialize(canvasOverride = null) {
591
- this.canvas = canvasOverride ?? document.getElementById('content-canvas');
592
- if (!this.canvas) {
593
- console.error('Faceted canvas (content-canvas) not found in DOM');
594
- console.log('Looking for canvas IDs:', ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas']);
555
+ console.warn('FacetedSystem: WebGL context creation failed', e);
595
556
  return false;
596
557
  }
597
-
598
- this.gl = this.canvas.getContext('webgl');
599
558
  if (!this.gl) {
600
- console.error('WebGL not available for Faceted System');
559
+ console.warn('FacetedSystem: WebGL not available');
601
560
  return false;
602
561
  }
603
562
 
604
- this._contextLost = false;
605
-
606
- // WebGL context loss/restore handlers
607
- this._onContextLost = (e) => {
608
- e.preventDefault();
609
- this._contextLost = true;
610
- console.warn('Faceted: WebGL context lost');
611
- };
612
- this._onContextRestored = () => {
613
- console.log('Faceted: WebGL context restored');
614
- this._contextLost = false;
615
- this.createShaderProgram();
616
- };
617
- this.canvas.addEventListener('webglcontextlost', this._onContextLost);
618
- this.canvas.addEventListener('webglcontextrestored', this._onContextRestored);
619
-
620
- if (!this.createShaderProgram()) {
621
- console.error('Failed to create faceted shader program');
563
+ // Compile shader program
564
+ this.program = this._compileProgram(this.gl, VERTEX_SHADER_GLSL, FRAGMENT_SHADER_GLSL);
565
+ if (!this.program) {
566
+ console.error('FacetedSystem: Shader compilation failed');
622
567
  return false;
623
568
  }
624
569
 
625
- this.setupCanvasSize();
626
- this._renderMode = 'direct';
627
- console.log('Faceted System initialized on content-canvas');
628
- return true;
629
- }
630
-
631
- /**
632
- * Create shader program with 6D rotation and 24 geometry support
633
- */
634
- createShaderProgram() {
635
- this.program = this.compileProgram(VERTEX_SHADER_GLSL, FRAGMENT_SHADER_GLSL);
636
- if (!this.program) return false;
637
-
638
- // Create fullscreen quad
639
- const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
640
- const buffer = this.gl.createBuffer();
641
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
570
+ // Create fullscreen quad buffer
571
+ const vertices = new Float32Array([-1,-1, 1,-1, -1,1, -1,1, 1,-1, 1,1]);
572
+ this._quadBuffer = this.gl.createBuffer();
573
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._quadBuffer);
642
574
  this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
643
575
 
576
+ // Cache uniform locations
577
+ const gl = this.gl;
578
+ const numUniforms = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);
579
+ for (let i = 0; i < numUniforms; i++) {
580
+ const info = gl.getActiveUniform(this.program, i);
581
+ if (info) {
582
+ this._uniformLocations[info.name] = gl.getUniformLocation(this.program, info.name);
583
+ }
584
+ }
585
+
586
+ this._useDirectGL = true;
587
+ this.initialized = true;
588
+ this.start();
644
589
  return true;
645
590
  }
646
591
 
647
- /**
648
- * Compile shader program
649
- */
650
- compileProgram(vertexSource, fragmentSource) {
651
- const vertexShader = this.compileShader(this.gl.VERTEX_SHADER, vertexSource);
652
- const fragmentShader = this.compileShader(this.gl.FRAGMENT_SHADER, fragmentSource);
653
-
654
- if (!vertexShader || !fragmentShader) return null;
592
+ _compileProgram(gl, vertexSrc, fragmentSrc) {
593
+ const vs = this._compileShader(gl, gl.VERTEX_SHADER, vertexSrc);
594
+ const fs = this._compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);
595
+ if (!vs || !fs) return null;
655
596
 
656
- const program = this.gl.createProgram();
657
- this.gl.attachShader(program, vertexShader);
658
- this.gl.attachShader(program, fragmentShader);
659
- this.gl.linkProgram(program);
597
+ const program = gl.createProgram();
598
+ gl.attachShader(program, vs);
599
+ gl.attachShader(program, fs);
600
+ gl.linkProgram(program);
660
601
 
661
- if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
662
- console.error('Shader program link error:', this.gl.getProgramInfoLog(program));
602
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
603
+ console.error('FacetedSystem link error:', gl.getProgramInfoLog(program));
663
604
  return null;
664
605
  }
665
606
 
607
+ gl.deleteShader(vs);
608
+ gl.deleteShader(fs);
666
609
  return program;
667
610
  }
668
611
 
669
- /**
670
- * Compile individual shader
671
- */
672
- compileShader(type, source) {
673
- const shader = this.gl.createShader(type);
674
- this.gl.shaderSource(shader, source);
675
- this.gl.compileShader(shader);
676
-
677
- if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
678
- console.error('Shader compile error:', this.gl.getShaderInfoLog(shader));
612
+ _compileShader(gl, type, source) {
613
+ const shader = gl.createShader(type);
614
+ gl.shaderSource(shader, source);
615
+ gl.compileShader(shader);
616
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
617
+ console.error('FacetedSystem shader error:', gl.getShaderInfoLog(shader));
618
+ gl.deleteShader(shader);
679
619
  return null;
680
620
  }
681
-
682
621
  return shader;
683
622
  }
684
623
 
685
- /**
686
- * Setup canvas size
687
- */
688
- setupCanvasSize() {
689
- const rect = this.canvas.parentElement.getBoundingClientRect();
690
- this.canvas.width = rect.width || 800;
691
- this.canvas.height = rect.height || 600;
692
- if (this.gl) {
693
- this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
694
- }
695
- }
624
+ // ─── Async Bridge Init (for SDK/WebGPU usage) ───
696
625
 
697
- /**
698
- * Start rendering
699
- */
700
- start() {
701
- this.isActive = true;
702
- this.render();
703
- console.log('Faceted System started');
704
- }
705
-
706
- /**
707
- * Stop rendering
708
- */
709
- stop() {
710
- this.isActive = false;
711
- console.log('Faceted System stopped');
626
+ async initWithBridge(canvas, options) {
627
+ this.canvas = canvas;
628
+ try {
629
+ this.bridge = await UnifiedRenderBridge.create(canvas, options);
630
+ if (this.bridge) {
631
+ const success = this.bridge.compileShader('faceted', {
632
+ glslVertex: VERTEX_SHADER_GLSL,
633
+ glslFragment: FRAGMENT_SHADER_GLSL,
634
+ wgslFragment: FRAGMENT_SHADER_WGSL
635
+ });
636
+ if (!success) {
637
+ console.error("Faceted shader compilation failed");
638
+ return false;
639
+ }
640
+ this.initialized = true;
641
+ this.start();
642
+ return true;
643
+ }
644
+ } catch (e) {
645
+ console.error("Faceted initWithBridge failed:", e);
646
+ }
647
+ return false;
712
648
  }
713
649
 
714
- /**
715
- * Set active state
716
- */
717
- setActive(active) {
718
- if (active) {
719
- this.start();
720
- } else {
721
- this.stop();
650
+ async initialize(options = {}) {
651
+ if (this.initialized) return true;
652
+ const canvas = options.canvas ||
653
+ document.getElementById('faceted-content-canvas') ||
654
+ document.getElementById('content-canvas');
655
+ if (!canvas) {
656
+ console.warn("FacetedSystem: No canvas found for initialize()");
657
+ return false;
722
658
  }
659
+ return this.initWithBridge(canvas, {
660
+ preferWebGPU: options.preferWebGPU !== undefined ? options.preferWebGPU : true,
661
+ debug: options.debug || false
662
+ });
723
663
  }
724
664
 
725
- /**
726
- * Get the current rendering backend type
727
- * @returns {'webgl'|'webgpu'|'direct-webgl'}
728
- */
729
- getBackendType() {
730
- if (this._renderMode === 'bridge' && this._bridge) {
731
- return this._bridge.getBackendType();
732
- }
733
- return 'direct-webgl';
665
+ // ─── Parameters ───
666
+
667
+ updateParameters(params) {
668
+ if (!params) return;
669
+ this.params = { ...this.params, ...params };
734
670
  }
735
671
 
736
672
  /**
737
- * Build uniform object for current parameters
738
- * @private
673
+ * Build the uniform object with proper u_ prefixed names for the shader.
739
674
  */
740
675
  _buildUniforms() {
676
+ const p = this.params;
741
677
  return {
742
- u_time: this.time,
743
- u_resolution: [this.canvas.width, this.canvas.height],
744
- u_mouse: [this.parameters.mouseX || 0.5, this.parameters.mouseY || 0.5],
745
- u_geometry: this.parameters.geometry,
746
- u_rot4dXY: this.parameters.rot4dXY,
747
- u_rot4dXZ: this.parameters.rot4dXZ,
748
- u_rot4dYZ: this.parameters.rot4dYZ,
749
- u_rot4dXW: this.parameters.rot4dXW,
750
- u_rot4dYW: this.parameters.rot4dYW,
751
- u_rot4dZW: this.parameters.rot4dZW,
752
- u_dimension: this.parameters.dimension,
753
- u_gridDensity: this.parameters.gridDensity,
754
- u_morphFactor: this.parameters.morphFactor,
755
- u_chaos: this.parameters.chaos,
756
- u_speed: this.parameters.speed,
757
- u_hue: this.parameters.hue,
758
- u_intensity: this.parameters.intensity,
759
- u_saturation: this.parameters.saturation,
760
- u_mouseIntensity: this.parameters.mouseIntensity || 0,
761
- u_clickIntensity: this.parameters.clickIntensity || 0,
762
- u_roleIntensity: this.parameters.roleIntensity || 1.0,
763
- u_bass: this.parameters.bass || 0,
764
- u_mid: this.parameters.mid || 0,
765
- u_high: this.parameters.high || 0
678
+ u_time: this._time,
679
+ u_resolution: [this.canvas?.width || 800, this.canvas?.height || 600],
680
+ u_geometry: p.geometry ?? 0,
681
+ u_rot4dXY: p.rot4dXY ?? 0,
682
+ u_rot4dXZ: p.rot4dXZ ?? 0,
683
+ u_rot4dYZ: p.rot4dYZ ?? 0,
684
+ u_rot4dXW: p.rot4dXW ?? 0,
685
+ u_rot4dYW: p.rot4dYW ?? 0,
686
+ u_rot4dZW: p.rot4dZW ?? 0,
687
+ u_dimension: p.dimension ?? 3.5,
688
+ u_gridDensity: p.gridDensity ?? 15,
689
+ u_morphFactor: p.morphFactor ?? 1.0,
690
+ u_chaos: p.chaos ?? 0.2,
691
+ u_speed: p.speed ?? 1.0,
692
+ u_hue: p.hue ?? 200,
693
+ u_intensity: p.intensity ?? 0.7,
694
+ u_saturation: p.saturation ?? 0.8,
695
+ u_mouseIntensity: p.mouseIntensity ?? 0,
696
+ u_clickIntensity: p.clickIntensity ?? 0,
697
+ u_bass: p.bass ?? 0,
698
+ u_mid: p.mid ?? 0,
699
+ u_high: p.high ?? 0,
700
+ u_breath: p.breath ?? 0,
701
+ u_mouse: p.mouse ?? [0.5, 0.5],
766
702
  };
767
703
  }
768
704
 
769
- /**
770
- * Render a single frame (bridge mode)
771
- * @private
772
- */
773
- _renderBridgeFrame() {
774
- if (!this._bridge) return;
775
- this._bridge.setUniforms(this._buildUniforms());
776
- this._bridge.render('faceted');
705
+ // ─── Render Loop ───
706
+
707
+ start() {
708
+ if (this._running) return;
709
+ this._running = true;
710
+ this._renderLoop();
777
711
  }
778
712
 
779
- /**
780
- * Render a single frame (direct WebGL mode)
781
- * @private
782
- */
783
- _renderDirectFrame() {
784
- if (!this.gl || !this.program || this._contextLost) return;
785
- if (this.gl.isContextLost()) {
786
- this._contextLost = true;
787
- return;
713
+ stop() {
714
+ this._running = false;
715
+ if (this._animFrame) {
716
+ cancelAnimationFrame(this._animFrame);
717
+ this._animFrame = null;
788
718
  }
789
-
790
- this.gl.useProgram(this.program);
791
- this.gl.enable(this.gl.BLEND);
792
- this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
793
-
794
- this.gl.clearColor(0, 0, 0, 1);
795
- this.gl.clear(this.gl.COLOR_BUFFER_BIT);
796
-
797
- const uniforms = this._buildUniforms();
798
-
799
- Object.entries(uniforms).forEach(([name, value]) => {
800
- const location = this.gl.getUniformLocation(this.program, name);
801
- if (location !== null) {
802
- if (Array.isArray(value)) {
803
- this.gl.uniform2fv(location, value);
804
- } else {
805
- this.gl.uniform1f(location, value);
806
- }
807
- }
808
- });
809
-
810
- // Draw fullscreen quad
811
- const posLocation = this.gl.getAttribLocation(this.program, 'a_position');
812
- this.gl.enableVertexAttribArray(posLocation);
813
- this.gl.vertexAttribPointer(posLocation, 2, this.gl.FLOAT, false, 0, 0);
814
- this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
815
719
  }
816
720
 
817
- /**
818
- * Render a single frame
819
- */
820
- renderFrame() {
821
- if (!this.isActive) return;
822
-
823
- // Apply audio reactivity
824
- if (window.audioEnabled && window.audioReactive) {
825
- this.parameters.bass = window.audioReactive.bass || 0;
826
- this.parameters.mid = window.audioReactive.mid || 0;
827
- this.parameters.high = window.audioReactive.high || 0;
828
- }
721
+ _renderLoop() {
722
+ if (!this._running) return;
829
723
 
830
- this.time += 0.016 * this.parameters.speed;
724
+ this._time += 16.0 * (this.params.speed ?? 1.0);
831
725
 
832
- if (this._renderMode === 'bridge') {
833
- this._renderBridgeFrame();
834
- } else {
835
- this._renderDirectFrame();
726
+ if (this._useDirectGL) {
727
+ this._renderDirectGL();
728
+ } else if (this.bridge) {
729
+ this.bridge.setUniforms(this._buildUniforms());
730
+ this.bridge.render('faceted', { clear: true, clearColor: [0, 0, 0, 1] });
836
731
  }
732
+
733
+ this._animFrame = requestAnimationFrame(() => this._renderLoop());
837
734
  }
838
735
 
839
736
  /**
840
- * Render loop
737
+ * Direct WebGL rendering — no bridge, just raw GL calls.
738
+ * Matches the original working FacetedSystem pattern.
841
739
  */
842
- render(frameState = {}) {
843
- // Apply frameState parameters if provided
844
- if (frameState.params) {
845
- Object.assign(this.parameters, frameState.params);
846
- }
847
- if (typeof frameState.time === 'number') {
848
- this.time = frameState.time;
849
- }
740
+ _renderDirectGL() {
741
+ const gl = this.gl;
742
+ if (!gl || !this.program) return;
850
743
 
851
- this.renderFrame();
744
+ gl.useProgram(this.program);
745
+ gl.enable(gl.BLEND);
746
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
747
+ gl.clearColor(0, 0, 0, 1);
748
+ gl.clear(gl.COLOR_BUFFER_BIT);
852
749
 
853
- if (this.isActive) {
854
- requestAnimationFrame(() => this.render());
750
+ // Set uniforms
751
+ const uniforms = this._buildUniforms();
752
+ for (const [name, value] of Object.entries(uniforms)) {
753
+ const loc = this._uniformLocations[name];
754
+ if (loc === null || loc === undefined) continue;
755
+ if (Array.isArray(value)) {
756
+ if (value.length === 2) gl.uniform2fv(loc, value);
757
+ else if (value.length === 3) gl.uniform3fv(loc, value);
758
+ else if (value.length === 4) gl.uniform4fv(loc, value);
759
+ } else {
760
+ gl.uniform1f(loc, value);
761
+ }
855
762
  }
856
- }
857
763
 
858
- /**
859
- * Update parameters with validation
860
- */
861
- updateParameters(params) {
862
- if (!params || typeof params !== 'object') return;
863
- for (const [key, value] of Object.entries(params)) {
864
- // Only accept finite numbers to prevent NaN/Infinity reaching shaders
865
- if (typeof value === 'number' && Number.isFinite(value)) {
866
- this.parameters[key] = value;
867
- }
764
+ // Draw fullscreen quad
765
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._quadBuffer);
766
+ const posLoc = gl.getAttribLocation(this.program, 'a_position');
767
+ if (posLoc >= 0) {
768
+ gl.enableVertexAttribArray(posLoc);
769
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
868
770
  }
771
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
869
772
  }
870
773
 
871
- // ============================================
872
- // RendererContract Compliance Methods
873
- // ============================================
874
-
875
- /**
876
- * Initialize the renderer (RendererContract.init)
877
- * @param {Object} [context] - Optional context with canvas or canvasId
878
- * @returns {boolean|Promise<boolean>} Success status
879
- */
880
- init(context = {}) {
881
- const canvasOverride = context.canvas ||
882
- (context.canvasId ? document.getElementById(context.canvasId) : null);
883
-
884
- // If preferWebGPU is set and canvas is provided, use bridge mode
885
- if (context.preferWebGPU && canvasOverride) {
886
- return this.initWithBridge(canvasOverride, {
887
- preferWebGPU: true,
888
- debug: context.debug
889
- });
774
+ render() {
775
+ if (this._useDirectGL) {
776
+ this._renderDirectGL();
777
+ } else if (this.bridge) {
778
+ this.bridge.setUniforms(this._buildUniforms());
779
+ this.bridge.render('faceted', { clear: true, clearColor: [0, 0, 0, 1] });
890
780
  }
781
+ }
891
782
 
892
- return this.initialize(canvasOverride);
783
+ getBackendType() {
784
+ if (this._useDirectGL) return 'webgl';
785
+ return this.bridge ? this.bridge.getBackendType() : 'none';
893
786
  }
894
787
 
895
- /**
896
- * Handle canvas resize (RendererContract.resize)
897
- * @param {number} width
898
- * @param {number} height
899
- * @param {number} [pixelRatio=1]
900
- */
901
- resize(width, height, pixelRatio = 1) {
902
- if (!this.canvas) return;
903
-
904
- if (this._renderMode === 'bridge' && this._bridge) {
905
- this._bridge.resize(width, height, pixelRatio);
906
- } else if (this.gl) {
907
- this.canvas.width = width * pixelRatio;
908
- this.canvas.height = height * pixelRatio;
909
- this.canvas.style.width = `${width}px`;
910
- this.canvas.style.height = `${height}px`;
911
- this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
912
- }
788
+ setActive(active) {
789
+ if (active) this.start();
790
+ else this.stop();
791
+ const layer = document.getElementById('faceted-layer');
792
+ if (layer) layer.style.display = active ? 'block' : 'none';
913
793
  }
914
794
 
915
- /**
916
- * Clean up all resources (RendererContract.dispose)
917
- */
918
- dispose() {
919
- this.isActive = false;
795
+ init(context = {}) { return this.initialize(context); }
920
796
 
921
- // Remove context loss listeners
797
+ resize(width, height, pixelRatio = 1) {
798
+ const w = Math.floor(width * pixelRatio);
799
+ const h = Math.floor(height * pixelRatio);
922
800
  if (this.canvas) {
923
- if (this._onContextLost) {
924
- this.canvas.removeEventListener('webglcontextlost', this._onContextLost);
925
- }
926
- if (this._onContextRestored) {
927
- this.canvas.removeEventListener('webglcontextrestored', this._onContextRestored);
928
- }
801
+ this.canvas.width = w;
802
+ this.canvas.height = h;
929
803
  }
930
-
931
- if (this._bridge) {
932
- this._bridge.dispose();
933
- this._bridge = null;
804
+ if (this._useDirectGL && this.gl) {
805
+ this.gl.viewport(0, 0, w, h);
806
+ } else if (this.bridge && this.bridge.resize) {
807
+ this.bridge.resize(width, height, pixelRatio);
934
808
  }
809
+ }
935
810
 
936
- if (this.gl && !this.gl.isContextLost()) {
937
- if (this.program) {
938
- this.gl.deleteProgram(this.program);
939
- }
940
- }
941
- this.program = null;
811
+ dispose() { this.destroy(); }
942
812
 
943
- if (this.gl) {
944
- const loseContext = this.gl.getExtension('WEBGL_lose_context');
945
- if (loseContext) {
946
- loseContext.loseContext();
947
- }
813
+ destroy() {
814
+ this.stop();
815
+ if (this._useDirectGL && this.gl) {
816
+ if (this.program) this.gl.deleteProgram(this.program);
817
+ if (this._quadBuffer) this.gl.deleteBuffer(this._quadBuffer);
948
818
  this.gl = null;
819
+ this.program = null;
820
+ this._quadBuffer = null;
949
821
  }
950
-
951
- this.canvas = null;
952
- this._renderMode = 'direct';
953
- this._contextLost = true;
954
- console.log('Faceted System disposed');
955
- }
956
-
957
- /**
958
- * Alias for dispose (for backward compatibility)
959
- */
960
- destroy() {
961
- this.dispose();
822
+ if (this.bridge) {
823
+ this.bridge.dispose();
824
+ this.bridge = null;
825
+ }
826
+ this.initialized = false;
827
+ this._useDirectGL = false;
962
828
  }
963
829
  }