@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.
- package/CHANGELOG.md +118 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
- package/DOCS/CI_TESTING.md +38 -0
- package/DOCS/CLI_ONBOARDING.md +75 -0
- package/DOCS/CONTROL_REFERENCE.md +64 -0
- package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
- package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
- package/DOCS/ENV_SETUP.md +189 -0
- package/DOCS/EXPORT_FORMATS.md +417 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
- package/DOCS/LICENSING_TIERS.md +275 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
- package/DOCS/OBS_SETUP_GUIDE.md +98 -0
- package/DOCS/PROJECT_SETUP.md +66 -0
- package/DOCS/RENDERER_LIFECYCLE.md +40 -0
- package/DOCS/REPO_MANIFEST.md +121 -0
- package/DOCS/SESSION_014_PLAN.md +195 -0
- package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
- package/DOCS/SYSTEM_INVENTORY.md +520 -0
- package/DOCS/TELEMETRY_EXPORTS.md +34 -0
- package/DOCS/WEBGPU_STATUS.md +38 -0
- package/DOCS/XR_BENCHMARKS.md +608 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/docs/.nojekyll +0 -0
- package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/02-hyperspatial_ego_death.html +346 -0
- package/docs/03-post_cartesian_sublime.html +346 -0
- package/docs/04-crystalline_void_meditation.html +346 -0
- package/docs/05-quantum_decoherence_ballet.html +346 -0
- package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/07-hyperspatial_ego_death.html +346 -0
- package/docs/08-post_cartesian_sublime.html +346 -0
- package/docs/09-crystalline_void_meditation.html +346 -0
- package/docs/10-quantum_decoherence_ballet.html +346 -0
- package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/12-hyperspatial_ego_death.html +346 -0
- package/docs/13-post_cartesian_sublime.html +346 -0
- package/docs/index.html +794 -0
- package/docs/test-hub.html +441 -0
- package/docs/url-state.js +102 -0
- package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
- package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
- package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
- package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
- package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
- package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
- package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
- package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
- package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
- package/docs/vib3-exports/index.html +238 -0
- package/docs/webgpu-live.html +702 -0
- package/package.json +367 -0
- package/src/advanced/AIPresetGenerator.js +777 -0
- package/src/advanced/MIDIController.js +703 -0
- package/src/advanced/OffscreenWorker.js +1051 -0
- package/src/advanced/WebGPUCompute.js +1051 -0
- package/src/advanced/WebXRRenderer.js +680 -0
- package/src/agent/cli/AgentCLI.js +615 -0
- package/src/agent/cli/index.js +14 -0
- package/src/agent/index.js +73 -0
- package/src/agent/mcp/MCPServer.js +950 -0
- package/src/agent/mcp/index.js +9 -0
- package/src/agent/mcp/tools.js +548 -0
- package/src/agent/telemetry/EventStream.js +669 -0
- package/src/agent/telemetry/Instrumentation.js +618 -0
- package/src/agent/telemetry/TelemetryExporters.js +427 -0
- package/src/agent/telemetry/TelemetryService.js +464 -0
- package/src/agent/telemetry/index.js +52 -0
- package/src/benchmarks/BenchmarkRunner.js +381 -0
- package/src/benchmarks/MetricsCollector.js +299 -0
- package/src/benchmarks/index.js +9 -0
- package/src/benchmarks/scenes.js +259 -0
- package/src/cli/index.js +675 -0
- package/src/config/ApiConfig.js +88 -0
- package/src/core/CanvasManager.js +217 -0
- package/src/core/ErrorReporter.js +117 -0
- package/src/core/ParameterMapper.js +333 -0
- package/src/core/Parameters.js +396 -0
- package/src/core/RendererContracts.js +200 -0
- package/src/core/UnifiedResourceManager.js +370 -0
- package/src/core/VIB3Engine.js +636 -0
- package/src/core/renderers/FacetedRendererAdapter.js +32 -0
- package/src/core/renderers/HolographicRendererAdapter.js +29 -0
- package/src/core/renderers/QuantumRendererAdapter.js +29 -0
- package/src/core/renderers/RendererLifecycleManager.js +63 -0
- package/src/creative/ColorPresetsSystem.js +980 -0
- package/src/creative/ParameterTimeline.js +1061 -0
- package/src/creative/PostProcessingPipeline.js +1113 -0
- package/src/creative/TransitionAnimator.js +683 -0
- package/src/export/CSSExporter.js +226 -0
- package/src/export/CardGeneratorBase.js +279 -0
- package/src/export/ExportManager.js +580 -0
- package/src/export/FacetedCardGenerator.js +279 -0
- package/src/export/HolographicCardGenerator.js +543 -0
- package/src/export/LottieExporter.js +552 -0
- package/src/export/QuantumCardGenerator.js +315 -0
- package/src/export/SVGExporter.js +519 -0
- package/src/export/ShaderExporter.js +903 -0
- package/src/export/TradingCardGenerator.js +3055 -0
- package/src/export/TradingCardManager.js +181 -0
- package/src/export/VIB3PackageExporter.js +559 -0
- package/src/export/index.js +14 -0
- package/src/export/systems/TradingCardSystemFaceted.js +494 -0
- package/src/export/systems/TradingCardSystemHolographic.js +452 -0
- package/src/export/systems/TradingCardSystemQuantum.js +411 -0
- package/src/faceted/FacetedSystem.js +963 -0
- package/src/features/CollectionManager.js +433 -0
- package/src/gallery/CollectionManager.js +240 -0
- package/src/gallery/GallerySystem.js +485 -0
- package/src/geometry/GeometryFactory.js +314 -0
- package/src/geometry/GeometryLibrary.js +72 -0
- package/src/geometry/buffers/BufferBuilder.js +338 -0
- package/src/geometry/buffers/index.js +18 -0
- package/src/geometry/generators/Crystal.js +420 -0
- package/src/geometry/generators/Fractal.js +298 -0
- package/src/geometry/generators/KleinBottle.js +197 -0
- package/src/geometry/generators/Sphere.js +192 -0
- package/src/geometry/generators/Tesseract.js +160 -0
- package/src/geometry/generators/Tetrahedron.js +225 -0
- package/src/geometry/generators/Torus.js +304 -0
- package/src/geometry/generators/Wave.js +341 -0
- package/src/geometry/index.js +142 -0
- package/src/geometry/warp/HypersphereCore.js +211 -0
- package/src/geometry/warp/HypertetraCore.js +386 -0
- package/src/geometry/warp/index.js +57 -0
- package/src/holograms/HolographicVisualizer.js +1073 -0
- package/src/holograms/RealHolographicSystem.js +966 -0
- package/src/holograms/variantRegistry.js +69 -0
- package/src/integrations/FigmaPlugin.js +854 -0
- package/src/integrations/OBSMode.js +754 -0
- package/src/integrations/ThreeJsPackage.js +660 -0
- package/src/integrations/TouchDesignerExport.js +552 -0
- package/src/integrations/frameworks/Vib3React.js +591 -0
- package/src/integrations/frameworks/Vib3Svelte.js +654 -0
- package/src/integrations/frameworks/Vib3Vue.js +628 -0
- package/src/llm/LLMParameterInterface.js +240 -0
- package/src/llm/LLMParameterUI.js +577 -0
- package/src/math/Mat4x4.js +708 -0
- package/src/math/Projection.js +341 -0
- package/src/math/Rotor4D.js +637 -0
- package/src/math/Vec4.js +476 -0
- package/src/math/constants.js +164 -0
- package/src/math/index.js +68 -0
- package/src/math/projections.js +54 -0
- package/src/math/rotations.js +196 -0
- package/src/quantum/QuantumEngine.js +906 -0
- package/src/quantum/QuantumVisualizer.js +1103 -0
- package/src/reactivity/ReactivityConfig.js +499 -0
- package/src/reactivity/ReactivityManager.js +586 -0
- package/src/reactivity/SpatialInputSystem.js +1783 -0
- package/src/reactivity/index.js +93 -0
- package/src/render/CommandBuffer.js +465 -0
- package/src/render/MultiCanvasBridge.js +340 -0
- package/src/render/RenderCommand.js +514 -0
- package/src/render/RenderResourceRegistry.js +523 -0
- package/src/render/RenderState.js +552 -0
- package/src/render/RenderTarget.js +512 -0
- package/src/render/ShaderLoader.js +253 -0
- package/src/render/ShaderProgram.js +599 -0
- package/src/render/UnifiedRenderBridge.js +496 -0
- package/src/render/backends/WebGLBackend.js +1108 -0
- package/src/render/backends/WebGPUBackend.js +1409 -0
- package/src/render/commands/CommandBufferExecutor.js +607 -0
- package/src/render/commands/RenderCommandBuffer.js +661 -0
- package/src/render/commands/index.js +17 -0
- package/src/render/index.js +367 -0
- package/src/scene/Disposable.js +498 -0
- package/src/scene/MemoryPool.js +618 -0
- package/src/scene/Node4D.js +697 -0
- package/src/scene/ResourceManager.js +599 -0
- package/src/scene/Scene4D.js +540 -0
- package/src/scene/index.js +98 -0
- package/src/schemas/error.schema.json +84 -0
- package/src/schemas/extension.schema.json +88 -0
- package/src/schemas/index.js +214 -0
- package/src/schemas/parameters.schema.json +142 -0
- package/src/schemas/tool-pack.schema.json +44 -0
- package/src/schemas/tool-response.schema.json +127 -0
- package/src/shaders/common/fullscreen.vert.glsl +5 -0
- package/src/shaders/common/fullscreen.vert.wgsl +17 -0
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +85 -0
- package/src/shaders/common/rotation4d.wgsl +86 -0
- package/src/shaders/common/uniforms.glsl +44 -0
- package/src/shaders/common/uniforms.wgsl +48 -0
- package/src/shaders/faceted/faceted.frag.glsl +129 -0
- package/src/shaders/faceted/faceted.frag.wgsl +164 -0
- package/src/shaders/holographic/holographic.frag.glsl +406 -0
- package/src/shaders/holographic/holographic.frag.wgsl +185 -0
- package/src/shaders/quantum/quantum.frag.glsl +513 -0
- package/src/shaders/quantum/quantum.frag.wgsl +361 -0
- package/src/testing/ParallelTestFramework.js +519 -0
- package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
- package/src/testing/exportFormats.test.js +8 -0
- package/src/testing/projections.test.js +14 -0
- package/src/testing/rotations.test.js +37 -0
- package/src/ui/InteractivityMenu.js +516 -0
- package/src/ui/StatusManager.js +96 -0
- package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
- package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
- package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
- package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
- package/src/variations/VariationManager.js +431 -0
- package/src/viewer/AudioReactivity.js +505 -0
- package/src/viewer/CardBending.js +481 -0
- package/src/viewer/GalleryUI.js +832 -0
- package/src/viewer/ReactivityManager.js +590 -0
- package/src/viewer/TradingCardExporter.js +600 -0
- package/src/viewer/ViewerPortal.js +374 -0
- package/src/viewer/index.js +12 -0
- package/src/wasm/WasmLoader.js +296 -0
- package/src/wasm/index.js +132 -0
- package/tools/agentic/mcpTools.js +88 -0
- package/tools/cli/agent-cli.js +92 -0
- package/tools/export/formats.js +24 -0
- package/tools/math/rotation-baseline.mjs +64 -0
- package/tools/shader-sync-verify.js +937 -0
- package/tools/telemetry/manifestPipeline.js +141 -0
- package/tools/telemetry/telemetryEvents.js +35 -0
- package/types/adaptive-sdk.d.ts +185 -0
- package/types/advanced/AIPresetGenerator.d.ts +81 -0
- package/types/advanced/MIDIController.d.ts +100 -0
- package/types/advanced/OffscreenWorker.d.ts +82 -0
- package/types/advanced/WebGPUCompute.d.ts +52 -0
- package/types/advanced/WebXRRenderer.d.ts +77 -0
- package/types/advanced/index.d.ts +46 -0
- package/types/core/ErrorReporter.d.ts +50 -0
- package/types/core/VIB3Engine.d.ts +204 -0
- package/types/creative/ColorPresetsSystem.d.ts +91 -0
- package/types/creative/ParameterTimeline.d.ts +74 -0
- package/types/creative/PostProcessingPipeline.d.ts +109 -0
- package/types/creative/TransitionAnimator.d.ts +71 -0
- package/types/creative/index.d.ts +35 -0
- package/types/integrations/FigmaPlugin.d.ts +46 -0
- package/types/integrations/OBSMode.d.ts +74 -0
- package/types/integrations/ThreeJsPackage.d.ts +62 -0
- package/types/integrations/TouchDesignerExport.d.ts +36 -0
- package/types/integrations/Vib3React.d.ts +74 -0
- package/types/integrations/Vib3Svelte.d.ts +63 -0
- package/types/integrations/Vib3Vue.d.ts +55 -0
- package/types/integrations/index.d.ts +52 -0
- package/types/reactivity/SpatialInputSystem.d.ts +173 -0
- package/types/reactivity/index.d.ts +394 -0
- package/types/render/CommandBuffer.d.ts +169 -0
- package/types/render/RenderCommand.d.ts +312 -0
- package/types/render/RenderState.d.ts +279 -0
- package/types/render/RenderTarget.d.ts +254 -0
- package/types/render/ShaderProgram.d.ts +277 -0
- package/types/render/UnifiedRenderBridge.d.ts +143 -0
- package/types/render/WebGLBackend.d.ts +168 -0
- package/types/render/WebGPUBackend.d.ts +186 -0
- package/types/render/index.d.ts +141 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIB3+ Reactivity System
|
|
3
|
+
*
|
|
4
|
+
* Unified reactivity configuration and management for:
|
|
5
|
+
* - Audio frequency band mappings
|
|
6
|
+
* - Device tilt/gyroscope control
|
|
7
|
+
* - Mouse/touch/click interactions
|
|
8
|
+
*
|
|
9
|
+
* @module reactivity
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
ReactivityConfig,
|
|
14
|
+
DEFAULT_REACTIVITY_CONFIG,
|
|
15
|
+
TARGETABLE_PARAMETERS,
|
|
16
|
+
AUDIO_BANDS,
|
|
17
|
+
BLEND_MODES,
|
|
18
|
+
INTERACTION_MODES
|
|
19
|
+
} from './ReactivityConfig.js';
|
|
20
|
+
|
|
21
|
+
export { ReactivityManager } from './ReactivityManager.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a pre-configured ReactivityManager with common settings
|
|
25
|
+
*/
|
|
26
|
+
export function createReactivityManager(options = {}) {
|
|
27
|
+
const { config, parameterUpdateFn } = options;
|
|
28
|
+
|
|
29
|
+
const manager = new (await import('./ReactivityManager.js')).ReactivityManager(parameterUpdateFn);
|
|
30
|
+
|
|
31
|
+
if (config) {
|
|
32
|
+
manager.loadConfig(config);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return manager;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create ReactivityConfig from a preset name
|
|
40
|
+
*/
|
|
41
|
+
export function createPresetConfig(presetName) {
|
|
42
|
+
const { ReactivityConfig } = require('./ReactivityConfig.js');
|
|
43
|
+
const config = new ReactivityConfig();
|
|
44
|
+
|
|
45
|
+
switch (presetName) {
|
|
46
|
+
case 'ambient':
|
|
47
|
+
config.setAudioEnabled(false);
|
|
48
|
+
config.setTiltEnabled(true);
|
|
49
|
+
config.setTiltSensitivity(0.5);
|
|
50
|
+
config.config.tilt.smoothing = 0.3;
|
|
51
|
+
config.setMouseMode('rotation', { sensitivity: 0.3 });
|
|
52
|
+
config.setClickMode('none');
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
case 'reactive':
|
|
56
|
+
config.setAudioEnabled(true);
|
|
57
|
+
config.config.audio.globalSensitivity = 1.5;
|
|
58
|
+
config.setTiltEnabled(true);
|
|
59
|
+
config.setMouseMode('velocity');
|
|
60
|
+
config.setClickMode('burst', { intensity: 1.5 });
|
|
61
|
+
break;
|
|
62
|
+
|
|
63
|
+
case 'immersive':
|
|
64
|
+
config.setAudioEnabled(false);
|
|
65
|
+
config.setTiltEnabled(true);
|
|
66
|
+
config.setTiltDramaticMode(true);
|
|
67
|
+
config.setTiltSensitivity(1.5);
|
|
68
|
+
config.setMouseMode('none');
|
|
69
|
+
config.setClickMode('none');
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case 'performance':
|
|
73
|
+
config.setAudioEnabled(true);
|
|
74
|
+
config.config.audio.globalSensitivity = 2.0;
|
|
75
|
+
config.setTiltEnabled(false);
|
|
76
|
+
config.setInteractionEnabled(false);
|
|
77
|
+
break;
|
|
78
|
+
|
|
79
|
+
case 'background':
|
|
80
|
+
config.setAudioEnabled(true);
|
|
81
|
+
config.config.audio.globalSensitivity = 0.3;
|
|
82
|
+
config.setTiltEnabled(false);
|
|
83
|
+
config.setInteractionEnabled(false);
|
|
84
|
+
break;
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
console.warn(`Unknown preset: ${presetName}, using defaults`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return config;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log('🎛️ VIB3+ Reactivity System loaded');
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommandBuffer - Batches and sorts render commands
|
|
3
|
+
*
|
|
4
|
+
* Provides deferred command execution with sorting capabilities:
|
|
5
|
+
* - State-based sorting to minimize GPU state changes
|
|
6
|
+
* - Depth sorting for correct transparency rendering
|
|
7
|
+
* - Priority-based ordering for clear/setup commands
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { RenderCommand, CommandType } from './RenderCommand.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Sort modes for command ordering
|
|
14
|
+
*/
|
|
15
|
+
export const SortMode = {
|
|
16
|
+
/** No sorting, execute in submission order */
|
|
17
|
+
NONE: 'none',
|
|
18
|
+
|
|
19
|
+
/** Sort by priority then state key */
|
|
20
|
+
STATE: 'state',
|
|
21
|
+
|
|
22
|
+
/** Sort by depth (front-to-back for opaque) */
|
|
23
|
+
FRONT_TO_BACK: 'front_to_back',
|
|
24
|
+
|
|
25
|
+
/** Sort by depth (back-to-front for transparent) */
|
|
26
|
+
BACK_TO_FRONT: 'back_to_front',
|
|
27
|
+
|
|
28
|
+
/** Custom comparator function */
|
|
29
|
+
CUSTOM: 'custom'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* CommandBuffer class
|
|
34
|
+
*/
|
|
35
|
+
export class CommandBuffer {
|
|
36
|
+
/**
|
|
37
|
+
* @param {object} [options]
|
|
38
|
+
*/
|
|
39
|
+
constructor(options = {}) {
|
|
40
|
+
/** @type {RenderCommand[]} Command queue */
|
|
41
|
+
this._commands = [];
|
|
42
|
+
|
|
43
|
+
/** @type {string} Sort mode */
|
|
44
|
+
this.sortMode = options.sortMode || SortMode.STATE;
|
|
45
|
+
|
|
46
|
+
/** @type {function|null} Custom sort comparator */
|
|
47
|
+
this.customComparator = options.customComparator || null;
|
|
48
|
+
|
|
49
|
+
/** @type {boolean} Whether buffer is currently recording */
|
|
50
|
+
this._recording = false;
|
|
51
|
+
|
|
52
|
+
/** @type {boolean} Whether buffer has been sorted */
|
|
53
|
+
this._sorted = false;
|
|
54
|
+
|
|
55
|
+
/** @type {string|null} Debug label */
|
|
56
|
+
this.label = options.label || null;
|
|
57
|
+
|
|
58
|
+
/** @type {object} Statistics */
|
|
59
|
+
this._stats = {
|
|
60
|
+
commandCount: 0,
|
|
61
|
+
drawCalls: 0,
|
|
62
|
+
stateChanges: 0,
|
|
63
|
+
triangles: 0
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Begin recording commands
|
|
69
|
+
* @param {boolean} [clear=true] - Whether to clear existing commands
|
|
70
|
+
* @returns {this}
|
|
71
|
+
*/
|
|
72
|
+
begin(clear = true) {
|
|
73
|
+
if (clear) {
|
|
74
|
+
this._commands = [];
|
|
75
|
+
this._resetStats();
|
|
76
|
+
}
|
|
77
|
+
this._recording = true;
|
|
78
|
+
this._sorted = false;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* End recording
|
|
84
|
+
* @returns {this}
|
|
85
|
+
*/
|
|
86
|
+
end() {
|
|
87
|
+
this._recording = false;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Add a command to the buffer
|
|
93
|
+
* @param {RenderCommand} command
|
|
94
|
+
* @returns {this}
|
|
95
|
+
*/
|
|
96
|
+
add(command) {
|
|
97
|
+
if (!this._recording) {
|
|
98
|
+
console.warn('CommandBuffer: Adding command while not recording');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this._commands.push(command);
|
|
102
|
+
this._sorted = false;
|
|
103
|
+
this._updateStats(command);
|
|
104
|
+
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Add multiple commands
|
|
110
|
+
* @param {RenderCommand[]} commands
|
|
111
|
+
* @returns {this}
|
|
112
|
+
*/
|
|
113
|
+
addAll(commands) {
|
|
114
|
+
for (const cmd of commands) {
|
|
115
|
+
this.add(cmd);
|
|
116
|
+
}
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Sort commands according to sort mode
|
|
122
|
+
* @returns {this}
|
|
123
|
+
*/
|
|
124
|
+
sort() {
|
|
125
|
+
if (this._sorted) return this;
|
|
126
|
+
|
|
127
|
+
switch (this.sortMode) {
|
|
128
|
+
case SortMode.NONE:
|
|
129
|
+
// No sorting
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case SortMode.STATE:
|
|
133
|
+
this._sortByState();
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
case SortMode.FRONT_TO_BACK:
|
|
137
|
+
this._sortByDepth(false);
|
|
138
|
+
break;
|
|
139
|
+
|
|
140
|
+
case SortMode.BACK_TO_FRONT:
|
|
141
|
+
this._sortByDepth(true);
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
case SortMode.CUSTOM:
|
|
145
|
+
if (this.customComparator) {
|
|
146
|
+
this._commands.sort(this.customComparator);
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this._sorted = true;
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Sort by priority and state key
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
_sortByState() {
|
|
160
|
+
this._commands.sort((a, b) => {
|
|
161
|
+
// First by priority (higher first)
|
|
162
|
+
if (a.priority !== b.priority) {
|
|
163
|
+
return b.priority - a.priority;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Then by sort key (for state grouping)
|
|
167
|
+
return a.sortKey - b.sortKey;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Sort by depth
|
|
173
|
+
* @param {boolean} backToFront
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_sortByDepth(backToFront) {
|
|
177
|
+
// Separate draw commands from others
|
|
178
|
+
const draws = [];
|
|
179
|
+
const others = [];
|
|
180
|
+
|
|
181
|
+
for (const cmd of this._commands) {
|
|
182
|
+
if (this._isDrawCommand(cmd)) {
|
|
183
|
+
draws.push(cmd);
|
|
184
|
+
} else {
|
|
185
|
+
others.push(cmd);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Sort draw commands by depth
|
|
190
|
+
draws.sort((a, b) => {
|
|
191
|
+
const depthA = a.depth || 0;
|
|
192
|
+
const depthB = b.depth || 0;
|
|
193
|
+
return backToFront ? depthB - depthA : depthA - depthB;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Sort others by priority
|
|
197
|
+
others.sort((a, b) => b.priority - a.priority);
|
|
198
|
+
|
|
199
|
+
// Recombine: others first, then draws
|
|
200
|
+
this._commands = [...others, ...draws];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Check if command is a draw command
|
|
205
|
+
* @private
|
|
206
|
+
*/
|
|
207
|
+
_isDrawCommand(cmd) {
|
|
208
|
+
return cmd.type === CommandType.DRAW ||
|
|
209
|
+
cmd.type === CommandType.DRAW_INDEXED ||
|
|
210
|
+
cmd.type === CommandType.DRAW_INSTANCED ||
|
|
211
|
+
cmd.type === CommandType.DRAW_INDEXED_INSTANCED;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Execute all commands
|
|
216
|
+
* @param {object} backend - Rendering backend
|
|
217
|
+
*/
|
|
218
|
+
execute(backend) {
|
|
219
|
+
if (!this._sorted && this.sortMode !== SortMode.NONE) {
|
|
220
|
+
this.sort();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
for (const command of this._commands) {
|
|
224
|
+
command.execute(backend);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Execute commands with profiling
|
|
230
|
+
* @param {object} backend
|
|
231
|
+
* @returns {object} Execution stats
|
|
232
|
+
*/
|
|
233
|
+
executeWithProfiling(backend) {
|
|
234
|
+
const startTime = performance.now();
|
|
235
|
+
|
|
236
|
+
this.execute(backend);
|
|
237
|
+
|
|
238
|
+
const endTime = performance.now();
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
...this._stats,
|
|
242
|
+
executionTime: endTime - startTime
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get command count
|
|
248
|
+
* @returns {number}
|
|
249
|
+
*/
|
|
250
|
+
get length() {
|
|
251
|
+
return this._commands.length;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get commands (read-only)
|
|
256
|
+
* @returns {RenderCommand[]}
|
|
257
|
+
*/
|
|
258
|
+
get commands() {
|
|
259
|
+
return [...this._commands];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Check if empty
|
|
264
|
+
* @returns {boolean}
|
|
265
|
+
*/
|
|
266
|
+
get isEmpty() {
|
|
267
|
+
return this._commands.length === 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get statistics
|
|
272
|
+
* @returns {object}
|
|
273
|
+
*/
|
|
274
|
+
get stats() {
|
|
275
|
+
return { ...this._stats };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Clear the buffer
|
|
280
|
+
* @returns {this}
|
|
281
|
+
*/
|
|
282
|
+
clear() {
|
|
283
|
+
this._commands = [];
|
|
284
|
+
this._sorted = false;
|
|
285
|
+
this._resetStats();
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Reset statistics
|
|
291
|
+
* @private
|
|
292
|
+
*/
|
|
293
|
+
_resetStats() {
|
|
294
|
+
this._stats = {
|
|
295
|
+
commandCount: 0,
|
|
296
|
+
drawCalls: 0,
|
|
297
|
+
stateChanges: 0,
|
|
298
|
+
triangles: 0
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Update statistics for a command
|
|
304
|
+
* @param {RenderCommand} command
|
|
305
|
+
* @private
|
|
306
|
+
*/
|
|
307
|
+
_updateStats(command) {
|
|
308
|
+
this._stats.commandCount++;
|
|
309
|
+
|
|
310
|
+
switch (command.type) {
|
|
311
|
+
case CommandType.DRAW:
|
|
312
|
+
case CommandType.DRAW_INDEXED:
|
|
313
|
+
this._stats.drawCalls++;
|
|
314
|
+
if (command.primitive === 'triangles') {
|
|
315
|
+
const count = command.vertexCount || command.indexCount || 0;
|
|
316
|
+
this._stats.triangles += Math.floor(count / 3);
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
|
|
320
|
+
case CommandType.DRAW_INSTANCED:
|
|
321
|
+
case CommandType.DRAW_INDEXED_INSTANCED:
|
|
322
|
+
this._stats.drawCalls++;
|
|
323
|
+
if (command.primitive === 'triangles') {
|
|
324
|
+
const count = command.vertexCount || command.indexCount || 0;
|
|
325
|
+
const instances = command.instanceCount || 1;
|
|
326
|
+
this._stats.triangles += Math.floor(count / 3) * instances;
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
|
|
330
|
+
case CommandType.SET_STATE:
|
|
331
|
+
this._stats.stateChanges++;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Merge another command buffer into this one
|
|
338
|
+
* @param {CommandBuffer} other
|
|
339
|
+
* @returns {this}
|
|
340
|
+
*/
|
|
341
|
+
merge(other) {
|
|
342
|
+
for (const cmd of other._commands) {
|
|
343
|
+
this.add(cmd);
|
|
344
|
+
}
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Filter commands by type
|
|
350
|
+
* @param {string} type
|
|
351
|
+
* @returns {RenderCommand[]}
|
|
352
|
+
*/
|
|
353
|
+
filterByType(type) {
|
|
354
|
+
return this._commands.filter(cmd => cmd.type === type);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Get draw commands only
|
|
359
|
+
* @returns {RenderCommand[]}
|
|
360
|
+
*/
|
|
361
|
+
getDrawCommands() {
|
|
362
|
+
return this._commands.filter(cmd => this._isDrawCommand(cmd));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Clone the buffer
|
|
367
|
+
* @returns {CommandBuffer}
|
|
368
|
+
*/
|
|
369
|
+
clone() {
|
|
370
|
+
const buffer = new CommandBuffer({
|
|
371
|
+
sortMode: this.sortMode,
|
|
372
|
+
customComparator: this.customComparator,
|
|
373
|
+
label: this.label
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
buffer._commands = [...this._commands];
|
|
377
|
+
buffer._sorted = this._sorted;
|
|
378
|
+
buffer._stats = { ...this._stats };
|
|
379
|
+
|
|
380
|
+
return buffer;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* CommandBufferPool - Reuses command buffers to reduce allocations
|
|
386
|
+
*/
|
|
387
|
+
export class CommandBufferPool {
|
|
388
|
+
constructor(initialSize = 4) {
|
|
389
|
+
/** @type {CommandBuffer[]} */
|
|
390
|
+
this._available = [];
|
|
391
|
+
|
|
392
|
+
/** @type {Set<CommandBuffer>} */
|
|
393
|
+
this._inUse = new Set();
|
|
394
|
+
|
|
395
|
+
// Pre-allocate
|
|
396
|
+
for (let i = 0; i < initialSize; i++) {
|
|
397
|
+
this._available.push(new CommandBuffer());
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Acquire a command buffer
|
|
403
|
+
* @param {object} [options]
|
|
404
|
+
* @returns {CommandBuffer}
|
|
405
|
+
*/
|
|
406
|
+
acquire(options = {}) {
|
|
407
|
+
let buffer;
|
|
408
|
+
|
|
409
|
+
if (this._available.length > 0) {
|
|
410
|
+
buffer = this._available.pop();
|
|
411
|
+
buffer.sortMode = options.sortMode || SortMode.STATE;
|
|
412
|
+
buffer.customComparator = options.customComparator || null;
|
|
413
|
+
buffer.label = options.label || null;
|
|
414
|
+
} else {
|
|
415
|
+
buffer = new CommandBuffer(options);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
buffer.begin();
|
|
419
|
+
this._inUse.add(buffer);
|
|
420
|
+
return buffer;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Release a command buffer back to pool
|
|
425
|
+
* @param {CommandBuffer} buffer
|
|
426
|
+
*/
|
|
427
|
+
release(buffer) {
|
|
428
|
+
if (!this._inUse.has(buffer)) return;
|
|
429
|
+
|
|
430
|
+
this._inUse.delete(buffer);
|
|
431
|
+
buffer.clear();
|
|
432
|
+
buffer.end();
|
|
433
|
+
this._available.push(buffer);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Release all in-use buffers
|
|
438
|
+
*/
|
|
439
|
+
releaseAll() {
|
|
440
|
+
for (const buffer of this._inUse) {
|
|
441
|
+
buffer.clear();
|
|
442
|
+
buffer.end();
|
|
443
|
+
this._available.push(buffer);
|
|
444
|
+
}
|
|
445
|
+
this._inUse.clear();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Get pool statistics
|
|
450
|
+
* @returns {object}
|
|
451
|
+
*/
|
|
452
|
+
getStats() {
|
|
453
|
+
return {
|
|
454
|
+
available: this._available.length,
|
|
455
|
+
inUse: this._inUse.size
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Global command buffer pool
|
|
462
|
+
*/
|
|
463
|
+
export const commandBufferPool = new CommandBufferPool();
|
|
464
|
+
|
|
465
|
+
export default CommandBuffer;
|