@vib3code/sdk 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,540 @@
1
+ /**
2
+ * Scene4D - Container for 4D scene management
3
+ *
4
+ * Provides a complete scene graph with:
5
+ * - Root node management
6
+ * - Node lookup by ID/name/tag
7
+ * - Layer-based filtering
8
+ * - Update and render traversal
9
+ * - Scene-wide settings
10
+ */
11
+
12
+ import { Node4D } from './Node4D.js';
13
+ import { Vec4 } from '../math/Vec4.js';
14
+
15
+ let sceneIdCounter = 0;
16
+
17
+ /**
18
+ * Scene4D class - Main scene container
19
+ */
20
+ export class Scene4D {
21
+ /**
22
+ * @param {string} [name] - Scene name
23
+ */
24
+ constructor(name = '') {
25
+ /** @type {string} Unique scene ID */
26
+ this.id = `scene_${++sceneIdCounter}`;
27
+
28
+ /** @type {string} Scene name */
29
+ this.name = name || this.id;
30
+
31
+ /** @type {Node4D} Root node of scene graph */
32
+ this.root = new Node4D('__root__');
33
+
34
+ /** @type {Map<string, Node4D>} ID to node lookup */
35
+ this._nodeById = new Map();
36
+ this._nodeById.set(this.root.id, this.root);
37
+
38
+ /** @type {Set<Node4D>} Nodes pending addition */
39
+ this._pendingAdd = new Set();
40
+
41
+ /** @type {Set<Node4D>} Nodes pending removal */
42
+ this._pendingRemove = new Set();
43
+
44
+ /** @type {boolean} Whether scene is currently updating */
45
+ this._updating = false;
46
+
47
+ /** @type {Vec4} Scene background color (RGBA) */
48
+ this.backgroundColor = new Vec4(0, 0, 0, 1);
49
+
50
+ /** @type {Vec4} Ambient light color */
51
+ this.ambientLight = new Vec4(0.2, 0.2, 0.2, 1);
52
+
53
+ /** @type {number} 4D "fog" distance (W-axis fade) */
54
+ this.wFogDistance = 10;
55
+
56
+ /** @type {boolean} Whether W-fog is enabled */
57
+ this.wFogEnabled = false;
58
+
59
+ /** @type {object} Scene metadata */
60
+ this.metadata = {};
61
+
62
+ /** @type {function[]} Update callbacks */
63
+ this._updateCallbacks = [];
64
+
65
+ /** @type {number} Total nodes in scene (cached) */
66
+ this._nodeCount = 1; // Root counts as 1
67
+
68
+ /** @type {boolean} Whether node count needs recalculation */
69
+ this._nodeCountDirty = false;
70
+ }
71
+
72
+ // ==================== Node Management ====================
73
+
74
+ /**
75
+ * Add a node to the scene (under root)
76
+ * @param {Node4D} node
77
+ * @returns {this}
78
+ */
79
+ add(node) {
80
+ if (this._updating) {
81
+ this._pendingAdd.add(node);
82
+ return this;
83
+ }
84
+
85
+ this._addNodeImmediate(node);
86
+ return this;
87
+ }
88
+
89
+ /**
90
+ * Add node immediately
91
+ * @private
92
+ */
93
+ _addNodeImmediate(node) {
94
+ if (node.parent === this.root) return;
95
+
96
+ this.root.addChild(node);
97
+ this._registerNode(node);
98
+ }
99
+
100
+ /**
101
+ * Remove a node from the scene
102
+ * @param {Node4D} node
103
+ * @returns {boolean}
104
+ */
105
+ remove(node) {
106
+ if (node === this.root) return false;
107
+
108
+ if (this._updating) {
109
+ this._pendingRemove.add(node);
110
+ return true;
111
+ }
112
+
113
+ return this._removeNodeImmediate(node);
114
+ }
115
+
116
+ /**
117
+ * Remove node immediately
118
+ * @private
119
+ */
120
+ _removeNodeImmediate(node) {
121
+ this._unregisterNode(node);
122
+ node.parent = null;
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * Register node and all descendants in lookup
128
+ * @private
129
+ */
130
+ _registerNode(node) {
131
+ node.traverse(n => {
132
+ this._nodeById.set(n.id, n);
133
+ });
134
+ this._nodeCountDirty = true;
135
+ }
136
+
137
+ /**
138
+ * Unregister node and all descendants from lookup
139
+ * @private
140
+ */
141
+ _unregisterNode(node) {
142
+ node.traverse(n => {
143
+ this._nodeById.delete(n.id);
144
+ });
145
+ this._nodeCountDirty = true;
146
+ }
147
+
148
+ /**
149
+ * Process pending additions and removals
150
+ * @private
151
+ */
152
+ _processPending() {
153
+ for (const node of this._pendingRemove) {
154
+ this._removeNodeImmediate(node);
155
+ }
156
+ this._pendingRemove.clear();
157
+
158
+ for (const node of this._pendingAdd) {
159
+ this._addNodeImmediate(node);
160
+ }
161
+ this._pendingAdd.clear();
162
+ }
163
+
164
+ /**
165
+ * Get node by ID
166
+ * @param {string} id
167
+ * @returns {Node4D|undefined}
168
+ */
169
+ getNodeById(id) {
170
+ return this._nodeById.get(id);
171
+ }
172
+
173
+ /**
174
+ * Get node by name (first match)
175
+ * @param {string} name
176
+ * @returns {Node4D|undefined}
177
+ */
178
+ getNodeByName(name) {
179
+ return this.root.findByName(name);
180
+ }
181
+
182
+ /**
183
+ * Get all nodes with tag
184
+ * @param {string} tag
185
+ * @returns {Node4D[]}
186
+ */
187
+ getNodesByTag(tag) {
188
+ return this.root.findByTag(tag);
189
+ }
190
+
191
+ /**
192
+ * Get all nodes on a layer
193
+ * @param {number} layer - Layer bit (0-31)
194
+ * @returns {Node4D[]}
195
+ */
196
+ getNodesByLayer(layer) {
197
+ const mask = 1 << layer;
198
+ const results = [];
199
+ this.root.traverse(node => {
200
+ if (node.layerMask & mask) {
201
+ results.push(node);
202
+ }
203
+ });
204
+ return results;
205
+ }
206
+
207
+ /**
208
+ * Get total node count
209
+ * @returns {number}
210
+ */
211
+ get nodeCount() {
212
+ if (this._nodeCountDirty) {
213
+ this._nodeCount = this._nodeById.size;
214
+ this._nodeCountDirty = false;
215
+ }
216
+ return this._nodeCount;
217
+ }
218
+
219
+ /**
220
+ * Check if scene contains a node
221
+ * @param {Node4D} node
222
+ * @returns {boolean}
223
+ */
224
+ contains(node) {
225
+ return this._nodeById.has(node.id);
226
+ }
227
+
228
+ // ==================== Traversal ====================
229
+
230
+ /**
231
+ * Traverse all nodes depth-first
232
+ * @param {function(Node4D): boolean|void} callback
233
+ */
234
+ traverse(callback) {
235
+ this.root.traverse(callback);
236
+ }
237
+
238
+ /**
239
+ * Traverse only visible nodes
240
+ * @param {function(Node4D): void} callback
241
+ */
242
+ traverseVisible(callback) {
243
+ this.root.traverseVisible(callback);
244
+ }
245
+
246
+ /**
247
+ * Traverse nodes matching layer mask
248
+ * @param {number} mask
249
+ * @param {function(Node4D): void} callback
250
+ */
251
+ traverseByLayer(mask, callback) {
252
+ this.root.traverse(node => {
253
+ if (node.layerMask & mask) {
254
+ callback(node);
255
+ }
256
+ });
257
+ }
258
+
259
+ /**
260
+ * Get all visible nodes sorted by W coordinate (far to near)
261
+ * @returns {Node4D[]}
262
+ */
263
+ getVisibleNodesSortedByW() {
264
+ const nodes = [];
265
+ this.traverseVisible(node => {
266
+ if (node !== this.root) {
267
+ nodes.push(node);
268
+ }
269
+ });
270
+
271
+ // Sort by world W coordinate (far to near for proper transparency)
272
+ nodes.sort((a, b) => a.worldPosition.w - b.worldPosition.w);
273
+ return nodes;
274
+ }
275
+
276
+ // ==================== Update Loop ====================
277
+
278
+ /**
279
+ * Register an update callback
280
+ * @param {function(number): void} callback - Called with deltaTime
281
+ * @returns {function} Unsubscribe function
282
+ */
283
+ onUpdate(callback) {
284
+ this._updateCallbacks.push(callback);
285
+ return () => {
286
+ const idx = this._updateCallbacks.indexOf(callback);
287
+ if (idx !== -1) {
288
+ this._updateCallbacks.splice(idx, 1);
289
+ }
290
+ };
291
+ }
292
+
293
+ /**
294
+ * Update the scene
295
+ * @param {number} deltaTime - Time since last update in seconds
296
+ */
297
+ update(deltaTime) {
298
+ this._updating = true;
299
+
300
+ // Call update callbacks
301
+ for (const callback of this._updateCallbacks) {
302
+ callback(deltaTime);
303
+ }
304
+
305
+ // Update all node transforms (ensures world matrices are current)
306
+ this.root.traverse(node => {
307
+ // Access worldMatrix to trigger update if dirty
308
+ void node.worldMatrix;
309
+ });
310
+
311
+ this._updating = false;
312
+
313
+ // Process pending operations
314
+ this._processPending();
315
+ }
316
+
317
+ // ==================== Queries ====================
318
+
319
+ /**
320
+ * Find nodes within a 4D sphere
321
+ * @param {Vec4} center
322
+ * @param {number} radius
323
+ * @returns {Node4D[]}
324
+ */
325
+ findNodesInSphere(center, radius) {
326
+ const results = [];
327
+ const radiusSq = radius * radius;
328
+
329
+ this.root.traverse(node => {
330
+ if (node === this.root) return;
331
+ const dist = node.worldPosition.sub(center).lengthSquared();
332
+ if (dist <= radiusSq) {
333
+ results.push(node);
334
+ }
335
+ });
336
+
337
+ return results;
338
+ }
339
+
340
+ /**
341
+ * Find nodes within a 4D box
342
+ * @param {Vec4} min
343
+ * @param {Vec4} max
344
+ * @returns {Node4D[]}
345
+ */
346
+ findNodesInBox(min, max) {
347
+ const results = [];
348
+
349
+ this.root.traverse(node => {
350
+ if (node === this.root) return;
351
+ const pos = node.worldPosition;
352
+ if (pos.x >= min.x && pos.x <= max.x &&
353
+ pos.y >= min.y && pos.y <= max.y &&
354
+ pos.z >= min.z && pos.z <= max.z &&
355
+ pos.w >= min.w && pos.w <= max.w) {
356
+ results.push(node);
357
+ }
358
+ });
359
+
360
+ return results;
361
+ }
362
+
363
+ /**
364
+ * Find nearest node to a point
365
+ * @param {Vec4} point
366
+ * @param {number} [maxDistance] - Maximum search distance
367
+ * @returns {Node4D|null}
368
+ */
369
+ findNearestNode(point, maxDistance = Infinity) {
370
+ let nearest = null;
371
+ let nearestDistSq = maxDistance * maxDistance;
372
+
373
+ this.root.traverse(node => {
374
+ if (node === this.root) return;
375
+ const distSq = node.worldPosition.sub(point).lengthSquared();
376
+ if (distSq < nearestDistSq) {
377
+ nearestDistSq = distSq;
378
+ nearest = node;
379
+ }
380
+ });
381
+
382
+ return nearest;
383
+ }
384
+
385
+ /**
386
+ * Raycast into the scene (simplified 4D ray)
387
+ * @param {Vec4} origin
388
+ * @param {Vec4} direction
389
+ * @param {number} [maxDistance]
390
+ * @returns {Array<{node: Node4D, distance: number}>}
391
+ */
392
+ raycast(origin, direction, maxDistance = 1000) {
393
+ const hits = [];
394
+ const dir = direction.normalize();
395
+
396
+ this.root.traverse(node => {
397
+ if (node === this.root) return;
398
+
399
+ // Simplified: treat each node as a point
400
+ const toNode = node.worldPosition.sub(origin);
401
+ const dist = toNode.dot(dir);
402
+
403
+ if (dist > 0 && dist < maxDistance) {
404
+ // Check perpendicular distance
405
+ const closest = origin.add(dir.scale(dist));
406
+ const perpDist = node.worldPosition.sub(closest).length();
407
+
408
+ // Assume nodes have radius 0.5 for hit detection
409
+ if (perpDist < 0.5) {
410
+ hits.push({ node, distance: dist });
411
+ }
412
+ }
413
+ });
414
+
415
+ // Sort by distance
416
+ hits.sort((a, b) => a.distance - b.distance);
417
+ return hits;
418
+ }
419
+
420
+ // ==================== Lifecycle ====================
421
+
422
+ /**
423
+ * Clear all nodes from scene
424
+ */
425
+ clear() {
426
+ this.root.removeAllChildren();
427
+ this._nodeById.clear();
428
+ this._nodeById.set(this.root.id, this.root);
429
+ this._pendingAdd.clear();
430
+ this._pendingRemove.clear();
431
+ this._nodeCountDirty = true;
432
+ }
433
+
434
+ /**
435
+ * Dispose scene and all nodes
436
+ */
437
+ dispose() {
438
+ this.clear();
439
+ this._updateCallbacks = [];
440
+ this.root.dispose();
441
+ }
442
+
443
+ /**
444
+ * Clone scene with all nodes
445
+ * @returns {Scene4D}
446
+ */
447
+ clone() {
448
+ const cloned = new Scene4D(this.name + '_clone');
449
+ cloned.backgroundColor = this.backgroundColor.clone();
450
+ cloned.ambientLight = this.ambientLight.clone();
451
+ cloned.wFogDistance = this.wFogDistance;
452
+ cloned.wFogEnabled = this.wFogEnabled;
453
+ cloned.metadata = { ...this.metadata };
454
+
455
+ // Clone all children of root
456
+ for (const child of this.root.children) {
457
+ cloned.add(child.cloneDeep());
458
+ }
459
+
460
+ return cloned;
461
+ }
462
+
463
+ // ==================== Serialization ====================
464
+
465
+ /**
466
+ * Serialize scene to JSON
467
+ * @returns {object}
468
+ */
469
+ toJSON() {
470
+ return {
471
+ id: this.id,
472
+ name: this.name,
473
+ backgroundColor: [
474
+ this.backgroundColor.x,
475
+ this.backgroundColor.y,
476
+ this.backgroundColor.z,
477
+ this.backgroundColor.w
478
+ ],
479
+ ambientLight: [
480
+ this.ambientLight.x,
481
+ this.ambientLight.y,
482
+ this.ambientLight.z,
483
+ this.ambientLight.w
484
+ ],
485
+ wFogDistance: this.wFogDistance,
486
+ wFogEnabled: this.wFogEnabled,
487
+ metadata: this.metadata,
488
+ nodes: this.root.children.map(c => c.toJSON())
489
+ };
490
+ }
491
+
492
+ /**
493
+ * Create scene from JSON
494
+ * @param {object} json
495
+ * @returns {Scene4D}
496
+ */
497
+ static fromJSON(json) {
498
+ const scene = new Scene4D(json.name);
499
+ scene.backgroundColor = new Vec4(...json.backgroundColor);
500
+ scene.ambientLight = new Vec4(...json.ambientLight);
501
+ scene.wFogDistance = json.wFogDistance;
502
+ scene.wFogEnabled = json.wFogEnabled;
503
+ scene.metadata = json.metadata || {};
504
+
505
+ for (const nodeJson of (json.nodes || [])) {
506
+ scene.add(Node4D.fromJSON(nodeJson));
507
+ }
508
+
509
+ return scene;
510
+ }
511
+
512
+ // ==================== Statistics ====================
513
+
514
+ /**
515
+ * Get scene statistics
516
+ * @returns {object}
517
+ */
518
+ getStats() {
519
+ let visibleCount = 0;
520
+ let enabledCount = 0;
521
+ let maxDepth = 0;
522
+
523
+ this.root.traverse(node => {
524
+ if (node.visible) visibleCount++;
525
+ if (node.enabled) enabledCount++;
526
+ maxDepth = Math.max(maxDepth, node.getDepth());
527
+ });
528
+
529
+ return {
530
+ totalNodes: this.nodeCount,
531
+ visibleNodes: visibleCount,
532
+ enabledNodes: enabledCount,
533
+ maxDepth,
534
+ pendingAdd: this._pendingAdd.size,
535
+ pendingRemove: this._pendingRemove.size
536
+ };
537
+ }
538
+ }
539
+
540
+ export default Scene4D;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Scene Module
3
+ *
4
+ * Complete 4D scene graph system with resource management.
5
+ *
6
+ * Core Classes:
7
+ * - Node4D: Transform hierarchy node
8
+ * - Scene4D: Scene container
9
+ * - ResourceManager: Reference-counted resources
10
+ * - MemoryPool: Object pooling
11
+ * - Disposable: Cascade disposal
12
+ */
13
+
14
+ // Scene Graph
15
+ export { Node4D, default as Node4DDefault } from './Node4D.js';
16
+ export { Scene4D, default as Scene4DDefault } from './Scene4D.js';
17
+
18
+ // Resource Management
19
+ export {
20
+ ResourceManager,
21
+ ManagedResource,
22
+ ResourceTypes,
23
+ default as ResourceManagerDefault
24
+ } from './ResourceManager.js';
25
+
26
+ // Memory Pools
27
+ export {
28
+ ObjectPool,
29
+ TypedArrayPool,
30
+ Vec4Pool,
31
+ Mat4x4Pool,
32
+ PoolManager,
33
+ pools,
34
+ default as PoolManagerDefault
35
+ } from './MemoryPool.js';
36
+
37
+ // Disposal System
38
+ export {
39
+ Disposable,
40
+ DisposalManager,
41
+ DisposalState,
42
+ CompositeDisposable,
43
+ SingleAssignmentDisposable,
44
+ SerialDisposable,
45
+ CallbackDisposable,
46
+ createDisposable,
47
+ disposalManager,
48
+ default as DisposableDefault
49
+ } from './Disposable.js';
50
+
51
+ /**
52
+ * Create a complete scene setup with all managers
53
+ * @param {object} [options]
54
+ * @returns {object}
55
+ */
56
+ export function createSceneContext(options = {}) {
57
+ const {
58
+ sceneName = 'main',
59
+ memoryLimit = 256 * 1024 * 1024, // 256MB default
60
+ poolInitialSize = 100
61
+ } = options;
62
+
63
+ const scene = new (require('./Scene4D.js').Scene4D)(sceneName);
64
+ const resources = new (require('./ResourceManager.js').ResourceManager)();
65
+ const disposal = new (require('./Disposable.js').DisposalManager)();
66
+ const poolManager = new (require('./MemoryPool.js').PoolManager)();
67
+
68
+ resources.memoryLimit = memoryLimit;
69
+
70
+ return {
71
+ scene,
72
+ resources,
73
+ disposal,
74
+ pools: poolManager,
75
+
76
+ /**
77
+ * Dispose all context resources
78
+ */
79
+ dispose() {
80
+ disposal.disposeAll();
81
+ resources.disposeAll();
82
+ scene.dispose();
83
+ poolManager.clearAll();
84
+ },
85
+
86
+ /**
87
+ * Get combined statistics
88
+ */
89
+ getStats() {
90
+ return {
91
+ scene: scene.getStats(),
92
+ resources: resources.getStats(),
93
+ disposal: disposal.getStats(),
94
+ pools: poolManager.getStats()
95
+ };
96
+ }
97
+ };
98
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "error.schema.json",
4
+ "title": "VIB3+ Error Schema",
5
+ "description": "Actionable error format for agentic API consumption",
6
+ "type": "object",
7
+ "properties": {
8
+ "error": {
9
+ "type": "object",
10
+ "properties": {
11
+ "type": {
12
+ "type": "string",
13
+ "enum": [
14
+ "ValidationError",
15
+ "RenderError",
16
+ "ResourceError",
17
+ "SystemError",
18
+ "ConfigurationError",
19
+ "NotFoundError",
20
+ "PermissionError"
21
+ ],
22
+ "description": "Error category"
23
+ },
24
+ "code": {
25
+ "type": "string",
26
+ "pattern": "^[A-Z_]+$",
27
+ "description": "Machine-readable error code",
28
+ "examples": [
29
+ "INVALID_GEOMETRY_INDEX",
30
+ "INVALID_ROTATION_PLANE",
31
+ "WEBGL_CONTEXT_LOST",
32
+ "SYSTEM_NOT_INITIALIZED",
33
+ "PARAMETER_OUT_OF_RANGE"
34
+ ]
35
+ },
36
+ "message": {
37
+ "type": "string",
38
+ "description": "Human-readable error description"
39
+ },
40
+ "parameter": {
41
+ "type": "string",
42
+ "description": "The parameter that caused the error, if applicable"
43
+ },
44
+ "provided_value": {
45
+ "description": "The invalid value that was provided"
46
+ },
47
+ "valid_options": {
48
+ "type": "array",
49
+ "description": "List of valid options for enum-type errors"
50
+ },
51
+ "valid_range": {
52
+ "type": "object",
53
+ "properties": {
54
+ "min": { "type": "number" },
55
+ "max": { "type": "number" }
56
+ },
57
+ "description": "Valid range for numeric errors"
58
+ },
59
+ "suggestion": {
60
+ "type": "string",
61
+ "description": "Actionable suggestion for the agent to fix the error"
62
+ },
63
+ "documentation_url": {
64
+ "type": "string",
65
+ "format": "uri",
66
+ "description": "Link to relevant documentation"
67
+ },
68
+ "retry_possible": {
69
+ "type": "boolean",
70
+ "description": "Whether retrying the operation might succeed",
71
+ "default": false
72
+ },
73
+ "retry_after_ms": {
74
+ "type": "integer",
75
+ "description": "Suggested wait time before retry, in milliseconds"
76
+ }
77
+ },
78
+ "required": ["type", "code", "message"],
79
+ "additionalProperties": false
80
+ }
81
+ },
82
+ "required": ["error"],
83
+ "additionalProperties": false
84
+ }