/** * Experimental GPU interaction product API. * * The exported constructors are the runtime engine constructors. Their public * declaration shape exposes scheduling, source registration, diagnostics, and * disposal while deliberately hiding storage buffers, compute nodes, grid * passes, mutable registries, and readback caches. * * @module three-blocks/experimental/gpu-interaction */ import type * as THREE from 'three/webgpu'; /** Spatial-hash configuration used by a shared interaction world. */ export interface GPUInteractionGridOptions { /** World-space width of one grid cell. */ cellSize?: number | undefined; /** Positive integer cell counts on the X, Y, and Z axes. */ dimensions?: readonly [number, number, number] | undefined; /** World-space minimum corner of the grid. */ origin?: readonly [number, number, number] | undefined; /** Maximum grid cells linked by one collider before it becomes global. */ maxCellsPerCollider?: number | undefined; } /** Fixed capacities and broadphase configuration for {@link GPUInteractionWorld}. */ export interface GPUInteractionWorldOptions { /** Maximum colliders reserved across every registered source. */ maxColliders?: number | undefined; /** Maximum colliders that may contribute optional feedback. */ maxFeedbackColliders?: number | undefined; /** Maximum collider-to-grid-cell links in the broadphase. */ maxGridLinks?: number | undefined; /** Maximum oversized or unbounded colliders scanned globally. */ maxGlobalColliders?: number | undefined; /** Spatial-hash configuration. */ grid?: GPUInteractionGridOptions | undefined; } /** Immutable collider-slot reservation assigned to one source. */ export interface GPUInteractionSourceRange { /** First collider slot owned by the source. */ readonly baseColliderSlot: number; /** Number of consecutive collider slots reserved for the source. */ readonly capacity: number; } /** * Lifecycle contract for a collider producer. * * Sources are attached before world initialization. During each manual frame, * `update()` runs inside `beginFrame()` before the broadphase is built and * `afterFeedbackResolved()` runs inside `resolveFeedback()`. A registered source * is owned by the world and is disposed when the world is disposed. */ export interface GPUInteractionSource { /** Fixed number of collider slots required by the source. */ readonly capacity: number; /** Receive the owning world and immutable collider-slot reservation. */ attach(world: GPUInteractionWorld, range: GPUInteractionSourceRange): void; /** Detach from the world without necessarily releasing source-owned resources. */ detach?(): void; /** Allocate source resources after the world has allocated its shared resources. */ initialize?(renderer: THREE.Renderer): unknown; /** Publish current collider transforms before the frame broadphase is built. */ update?(renderer: THREE.Renderer, deltaTime: number): number | null | undefined; /** Consume resolved feedback after all registered simulations have stepped. */ afterFeedbackResolved?(renderer: THREE.Renderer): void; /** Release resources owned by this source. */ dispose?(): void; } /** Read-only counters describing shared interaction work and bounded overflows. */ export interface GPUInteractionStats { /** Active colliders published during the latest frame. */ readonly activeColliders: number; /** Collider shapes skipped because a consumer does not support them. */ readonly unsupportedShapes: number; /** Source collider slots rejected because world capacity was exhausted. */ readonly colliderOverflows: number; /** Broadphase grid links retained during the latest readback. */ readonly gridLinks: number; /** Broadphase grid links dropped beyond configured capacity. */ readonly gridLinkOverflows: number; /** Oversized or unbounded colliders retained in the global list. */ readonly globalColliders: number; /** Global colliders dropped beyond configured capacity. */ readonly globalColliderOverflows: number; /** Colliders currently configured to receive feedback. */ readonly activeFeedbackColliders: number; /** Feedback colliders dropped beyond configured capacity. */ readonly feedbackColliderOverflows: number; /** Feedback contributions accepted by the latest reduction. */ readonly feedbackContributions: number; /** Feedback contributions dropped beyond configured capacity. */ readonly feedbackContributionOverflows: number; /** Packed physics bodies skipped because their data was stale. */ readonly stalePackedBodies: number; /** Packed physics readbacks skipped to avoid overlapping work. */ readonly skippedPackedReadbacks: number; } /** Read-only fixed-capacity and storage estimate for an interaction world. */ export interface GPUInteractionSizingReport { /** Maximum colliders reserved by the world. */ readonly maxColliders: number; /** Maximum feedback colliders reserved by the world. */ readonly maxFeedbackColliders: number; /** Maximum broadphase grid links reserved by the world. */ readonly maxGridLinks: number; /** Maximum global colliders reserved by the world. */ readonly maxGlobalColliders: number; /** Grid configuration used to calculate the report. */ readonly grid: Readonly; /** Total number of spatial-hash cells. */ readonly cellCount: number; /** Bytes reserved by cell-offset and cell-cursor arrays. */ readonly cellArrayBytes: number; /** Bytes reserved by collider-to-cell links. */ readonly linkBytes: number; /** Bytes reserved by the global collider list. */ readonly globalColliderBytes: number; /** Bytes reserved by collider attributes. */ readonly colliderBytes: number; /** Bytes reserved by optional feedback attributes. */ readonly feedbackBytes: number; /** Total estimated storage bytes owned by the world. */ readonly totalBytes: number; } /** Renderer limits required by the world's shared storage allocations. */ export interface GPUInteractionStorageRendererLimits { /** Minimum storage-buffer binding size in bytes. */ readonly maxStorageBufferBindingSize: number; /** Minimum allocatable buffer size in bytes. */ readonly maxBufferSize: number; } /** Renderer limits required by a complete interaction system. */ export interface GPUInteractionRequiredRendererLimits extends GPUInteractionStorageRendererLimits { /** Minimum storage-buffer binding count used by registered simulation passes. */ readonly maxStorageBuffersPerShaderStage: number; } /** One renderer-limit incompatibility reported before initialization. */ export interface GPUInteractionLimitFailure { /** WebGPU limit name. */ readonly name: string; /** Minimum value required by the configured interaction world. */ readonly required: number; /** Value available on the inspected renderer. */ readonly available: number; } /** Read-only WebGPU capability and renderer-limit report. */ export interface GPUInteractionCapabilityReport { /** Overall availability, or `null` when no renderer was inspected. */ readonly available: boolean | null; /** Whether the inspected renderer uses WebGPU, or `null` before inspection. */ readonly webgpu: boolean | null; /** Whether compute submission is available, or `null` before inspection. */ readonly compute: boolean | null; /** Whether the world has completed initialization. */ readonly initialized: boolean; /** Whether two-way feedback reduction is available. */ readonly feedback: false; /** Human-readable explanation of the current feedback support level. */ readonly feedbackReason: string; /** Whether the runtime provides `SharedArrayBuffer`. */ readonly sharedArrayBuffer: boolean; /** Shared storage compatibility and sizing information. */ readonly storage: Readonly<{ /** Compatibility, or `null` when no renderer was inspected. */ compatible: boolean | null; /** Minimum renderer limits for the shared interaction storage. */ requiredRendererLimits: GPUInteractionStorageRendererLimits; /** Largest single shared allocation. */ largestBuffer: Readonly<{ name: string | null; bytes: number; }>; /** Total shared storage byte estimate. */ totalByteLength: number; /** Renderer limits below the configured requirements. */ failures: readonly GPUInteractionLimitFailure[]; }>; /** Smoke-volume storage-texture compatibility. */ readonly smoke: Readonly<{ /** Storage format required by smoke interaction. */ requiredStorageFormat: 'rgba16float'; /** Format availability, or `null` when no renderer was inspected. */ storageFormatSupported: boolean | null; /** Human-readable incompatibility reason. */ reason: string | null; }>; /** Human-readable reasons the configured system is unavailable. */ readonly reasons: readonly string[]; } /** * Shared moving-collider world. * * Register every fixed-capacity source before `initialize()`. For manual * orchestration, the per-frame order is: update physics transforms, * `beginFrame()`, step all simulations, then `resolveFeedback()` in a `finally` * block. Prefer {@link GPUInteractionSystem.step} when one scheduler owns the * frame. The world owns registered sources and its shared GPU allocations. */ export interface GPUInteractionWorld { /** Whether shared resources have been allocated. */ readonly initialized: boolean; /** Whether this world has released its owned resources. */ readonly disposed: boolean; /** Register and transfer ownership of a fixed-capacity collider source. */ addSource(source: TSource): TSource; /** Remove and detach a source before initialization without disposing it. */ removeSource(source: GPUInteractionSource): boolean; /** Allocate shared resources and initialize all registered sources. */ initialize(renderer: THREE.Renderer): Promise; /** Publish source transforms and build the broadphase for one frame. */ beginFrame(renderer?: THREE.Renderer | null, deltaTime?: number): this; /** Resolve enabled feedback producers and close the current frame. */ resolveFeedback(renderer?: THREE.Renderer | null): this; /** Return the current frozen CPU-visible counter snapshot. */ getMetrics(): GPUInteractionStats; /** Explicitly refresh bounded GPU counters; avoid calling every frame. */ requestMetricsReadback(renderer?: THREE.Renderer | null): Promise; /** Clear all accumulated counter values. */ resetMetrics(): this; /** Return fixed-capacity and estimated-storage diagnostics. */ getSizingReport(): GPUInteractionSizingReport; /** Inspect WebGPU and configured renderer-limit compatibility. */ getCapabilityReport(renderer?: THREE.Renderer | null): GPUInteractionCapabilityReport; /** Dispose registered sources and every shared GPU allocation. */ dispose(): void; } interface GPUInteractionWorldConstructor { /** Construct an uninitialized world with fixed capacities. */ new (options?: GPUInteractionWorldOptions): GPUInteractionWorld; /** Runtime prototype. */ readonly prototype: GPUInteractionWorld; } /** Runtime world constructor with buffers, grid passes, and registries hidden. */ export declare const GPUInteractionWorld: GPUInteractionWorldConstructor; /** Physics stepping policy used by {@link GPUInteractionSystem.addPhysics}. */ export type GPUInteractionPhysicsStep = 'auto' | 'before' | 'after' | 'manual'; /** Physics-source creation options passed through by the system. */ export interface GPUInteractionPhysicsOptions { /** Scheduler phase, automatic source preference, or manual physics stepping. */ step?: GPUInteractionPhysicsStep | undefined; /** Engine-specific source options forwarded to `createInteractionSource()`. */ [option: string]: unknown; } /** Collider source optionally capable of advancing its owning physics engine. */ export interface GPUInteractionPhysicsSource extends GPUInteractionSource { /** Preferred automatic physics phase. */ readonly interactionStepPhase?: 'before' | 'after' | null | undefined; /** Storage-buffer binding count required by this source. */ readonly interactionStorageBufferRequirement?: number | undefined; /** Advance source physics during its selected scheduler phase. */ advancePhysics?(renderer: THREE.Renderer, deltaTime: number): unknown; } /** Physics engine adapter accepted by {@link GPUInteractionSystem.addPhysics}. */ export interface GPUInteractionPhysicsEngine { /** Create the fixed-capacity collider source owned by the interaction world. */ createInteractionSource(options: Record): TSource; } /** Broadphase query strategy used by an interaction-enabled simulation. */ export type GPUInteractionQueryMode = 'grid' | 'scan'; /** Options forwarded when a simulation is attached to the shared world. */ export interface GPUInteractionSimulationOptions { /** Spatial-grid broadphase or direct collider scan. */ queryMode?: GPUInteractionQueryMode | undefined; /** Simulation-specific interaction options. */ [option: string]: unknown; } /** Simulation lifecycle required by {@link GPUInteractionSystem}. */ export interface GPUInteractionSimulation { /** Attach the shared world before system initialization. */ setInteractionWorld(world: GPUInteractionWorld, options: GPUInteractionSimulationOptions): unknown; /** Detach the shared world without disposing the simulation. */ clearInteractionWorld?(): void; /** Advance one simulation step between world begin-frame and feedback resolution. */ step(renderer: THREE.Renderer, deltaTime: number): unknown; } /** Construction options for the shared interaction scheduler. */ export interface GPUInteractionSystemOptions extends GPUInteractionWorldOptions { /** Existing world to use, or options for the world owned by the system. */ world?: GPUInteractionWorld | GPUInteractionWorldOptions | undefined; } /** * Shared physics-to-simulation scheduler. * * Add physics and simulations before `initialize()`. Each `step()` performs * before-phase physics, source publication and broadphase construction, * simulation steps in registration order, feedback resolution, and after-phase * physics. Do not overlap calls. Render after the returned promise resolves. * The system owns its world and physics sources, but not registered simulations * or physics engine objects. */ export interface GPUInteractionSystem { /** Shared world owned and disposed by this scheduler. */ readonly world: GPUInteractionWorld; /** Whether the system and its shared world have initialized. */ readonly initialized: boolean; /** Whether this scheduler has released its owned resources. */ readonly disposed: boolean; /** Create, register, and transfer ownership of a physics collider source. */ addPhysics(physics: GPUInteractionPhysicsEngine, options?: GPUInteractionPhysicsOptions): TSource; /** Attach a simulation without transferring ownership of that simulation. */ addSimulation(simulation: TSimulation, options?: GPUInteractionSimulationOptions): TSimulation; /** Detach a simulation without disposing it. */ removeSimulation(simulation: GPUInteractionSimulation): boolean; /** Allocate the shared world after all sources and simulations are registered. */ initialize(renderer: THREE.Renderer): Promise; /** Execute one non-overlapping interaction frame in the documented order. */ step(renderer?: THREE.Renderer | null, deltaTime?: number): Promise; /** Return the current frozen CPU-visible counter snapshot. */ getMetrics(): GPUInteractionStats; /** Explicitly refresh bounded GPU counters; avoid calling every frame. */ requestMetricsReadback(): Promise; /** Inspect WebGPU and configured renderer-limit compatibility. */ getCapabilityReport(renderer?: THREE.Renderer | null): GPUInteractionCapabilityReport; /** Return fixed-capacity and estimated-storage diagnostics. */ getSizingReport(): GPUInteractionSizingReport; /** Return limits to request when constructing the renderer, before initialization. */ getRequiredRendererLimits(): GPUInteractionRequiredRendererLimits; /** Detach simulations and dispose the owned world and physics sources. */ dispose(): void; } interface GPUInteractionSystemConstructor { /** Construct an uninitialized scheduler and its owned world. */ new (options?: GPUInteractionSystemOptions): GPUInteractionSystem; /** Runtime prototype. */ readonly prototype: GPUInteractionSystem; } /** Runtime system constructor with scheduler registries and renderer state hidden. */ export declare const GPUInteractionSystem: GPUInteractionSystemConstructor; /** Supported high-level shape descriptors for a CPU-driven kinematic source. */ export type KinematicInteractionShape = { type: 'sphere'; radius: number; } | { type: 'box'; halfExtents: readonly [number, number, number]; } | { type: 'capsule'; radius: number; halfHeight: number; }; /** Construction controls for {@link KinematicInteractionSource}. */ export interface KinematicInteractionSourceOptions { /** Local collider shape sampled at the target object's world transform. */ shape?: KinematicInteractionShape | undefined; /** Simulation families that sense this collider. */ affects?: readonly ('boids' | 'fluid' | 'smoke')[] | undefined; /** Interaction layer bit field. */ layer?: number | undefined; /** Interaction mask bit field. */ mask?: number | undefined; /** Surface friction coefficient. */ friction?: number | undefined; /** Surface restitution coefficient. */ restitution?: number | undefined; } /** * CPU-driven single-collider source. * * Set a target before world initialization and keep the object's world transform * current before each system/world frame. The source derives linear velocity * from consecutive target positions. Once registered, the world owns disposal; * the target object itself remains application-owned. */ export interface KinematicInteractionSource extends GPUInteractionSource { /** This source always reserves one collider slot. */ readonly capacity: 1; /** Application-owned object sampled during the next world frame. */ readonly target: THREE.Object3D | null; /** Select the application-owned object to sample, or `null` to disable it. */ setTarget(object: THREE.Object3D | null): this; /** Detach from the world without disposing the target object. */ detach(): void; /** Release the world association and target reference. */ dispose(): void; } interface KinematicInteractionSourceConstructor { /** Construct a one-collider CPU transform source. */ new (options?: KinematicInteractionSourceOptions): KinematicInteractionSource; /** Runtime prototype. */ readonly prototype: KinematicInteractionSource; } /** Runtime kinematic-source constructor with buffer-writing state hidden. */ export declare const KinematicInteractionSource: KinematicInteractionSourceConstructor; export {};