@forgeax/engine-render 0.1.26 → 0.1.28
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/README.md +215 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +31 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +11 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -2
- package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
- package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
- package/dist/{chunk-HKXTW355.mjs → chunk-IQMKJLNU.mjs} +3 -3
- package/dist/{chunk-HKXTW355.mjs.map → chunk-IQMKJLNU.mjs.map} +1 -1
- package/dist/{chunk-KM2NOX2I.mjs → chunk-J52NMQKR.mjs} +462 -6
- package/dist/chunk-J52NMQKR.mjs.map +1 -0
- package/dist/{chunk-ZZ4YQ474.mjs → chunk-J6KACNOH.mjs} +2 -2
- package/dist/{chunk-ZZ4YQ474.mjs.map → chunk-J6KACNOH.mjs.map} +1 -1
- package/dist/{chunk-ADHHVYLW.mjs → chunk-JAASCMXA.mjs} +3 -3
- package/dist/{chunk-ADHHVYLW.mjs.map → chunk-JAASCMXA.mjs.map} +1 -1
- package/dist/{chunk-TMIASV2N.mjs → chunk-MBU4ZVE7.mjs} +20 -12
- package/dist/chunk-MBU4ZVE7.mjs.map +1 -0
- package/dist/{chunk-E34VL5VI.mjs → chunk-MYJ5RPJO.mjs} +3 -3
- package/dist/{chunk-E34VL5VI.mjs.map → chunk-MYJ5RPJO.mjs.map} +1 -1
- package/dist/{chunk-JDWARUOI.mjs → chunk-RBDBZ5R7.mjs} +17 -3
- package/dist/chunk-RBDBZ5R7.mjs.map +1 -0
- package/dist/{chunk-YUQXSEHG.mjs → chunk-VSL23LZE.mjs} +26 -12
- package/dist/chunk-VSL23LZE.mjs.map +1 -0
- package/dist/construct-renderer.mjs +862 -106
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +10 -5
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/mesh-residency-lifetime.d.ts +21 -0
- package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
- package/dist/dynamic-geometry.d.ts +125 -0
- package/dist/dynamic-geometry.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +7 -6
- package/dist/index.mjs.map +1 -1
- package/dist/internal.mjs +7 -7
- package/dist/record/frame.d.ts +1 -1
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +2 -0
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/render-contract.d.ts +12 -0
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +6 -0
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +7 -0
- package/dist/render-system.d.ts.map +1 -1
- package/dist/temporal/index.mjs +4 -4
- package/package.json +20 -20
- package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
- package/src/__tests__/factory-contract.integration.test.ts +6 -14
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +1 -1
- package/src/assembly/dynamic-geometry-host.ts +839 -0
- package/src/assembly/host-contract.ts +26 -0
- package/src/assembly/renderer-facade.ts +17 -0
- package/src/assembly/webgpu-renderer.ts +49 -2
- package/src/components/sprite-animation.ts +1 -1
- package/src/device/gpu-residency.ts +62 -62
- package/src/device/mesh-residency-lifetime.ts +73 -0
- package/src/dynamic-geometry.ts +736 -0
- package/src/index.ts +16 -0
- package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +68 -1
- package/src/record/frame.ts +2 -0
- package/src/record/main-pass-geometry.ts +13 -4
- package/src/record/main-pass-sprite-draws.ts +2 -0
- package/src/record/render-context.ts +2 -0
- package/src/record/typed-frame-graph.ts +2 -9
- package/src/render-contract.ts +24 -0
- package/src/render-system-extract-tail.ts +3 -2
- package/src/render-system-extract.ts +30 -1
- package/src/render-system.ts +42 -0
- package/dist/chunk-FJ6P52EE.mjs.map +0 -1
- package/dist/chunk-JDWARUOI.mjs.map +0 -1
- package/dist/chunk-KM2NOX2I.mjs.map +0 -1
- package/dist/chunk-TMIASV2N.mjs.map +0 -1
- package/dist/chunk-YUQXSEHG.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/points-lines/admission.ts","../src/point-shadow-inspection.ts","../src/volume/inspection.ts","../src/capture/cube-views.ts","../src/reflection/filter.ts","../src/reflection/gpu-table.ts","../src/reflection/inspection.ts","../src/reflection/projection.ts","../src/scene/visibility/inspection.ts","../src/ssr/admission.ts"],"names":["pass","primitiveKey","failure"],"mappings":"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","file":"chunk-KM2NOX2I.mjs","sourcesContent":["import { err, type MaterialAsset, type MeshAsset, ok, type Result } from '@forgeax/engine-types';\nimport { type PointShape, PointShapeValue, pointShapeFromU32 } from '../components/points';\nimport type {\n PointsLinesBudgetExceededError,\n PointsLinesInvalidStyleError,\n PointsLinesMaterialUnsupportedError,\n PointsLinesStyleUnsupportedError,\n PointsLinesTopologyMismatchError,\n} from '../errors/render';\nimport {\n PointsLinesBudgetExceededError as BudgetError,\n PointsLinesInvalidStyleError as InvalidStyleError,\n PointsLinesMaterialUnsupportedError as MaterialError,\n PointsLinesStyleUnsupportedError as StyleError,\n PointsLinesTopologyMismatchError as TopologyError,\n} from '../errors/render';\n\nexport interface PointsStyleInput {\n readonly sizePx?: number;\n readonly shape?: number;\n}\n\nexport interface LinesStyleInput {\n readonly widthPx?: number;\n}\n\nexport interface PointsLinesAdmissionLimits {\n readonly maxPoints?: number;\n readonly maxSegments?: number;\n}\n\nexport interface PointsLinesAdmissionInput {\n readonly entity: number;\n readonly points?: PointsStyleInput;\n readonly lines?: LinesStyleInput;\n readonly mesh: MeshAsset;\n readonly material: MaterialAsset;\n readonly limits?: PointsLinesAdmissionLimits;\n readonly materialId?: string;\n}\n\nexport interface PointsLinesAdmission {\n readonly component: 'Points' | 'Lines';\n readonly shape?: PointShape;\n readonly sizePx?: number;\n readonly widthPx?: number;\n readonly pointCount: number;\n readonly segmentCount: number;\n readonly submeshes: readonly number[];\n}\n\nexport type PointsLinesAdmissionError =\n | PointsLinesInvalidStyleError\n | PointsLinesTopologyMismatchError\n | PointsLinesStyleUnsupportedError\n | PointsLinesMaterialUnsupportedError\n | PointsLinesBudgetExceededError;\n\nfunction invalidStyle(\n input: PointsLinesAdmissionInput,\n component: 'Points' | 'Lines' | 'Points/Lines',\n field: string,\n value: number | string | undefined,\n expected: string,\n): Result<never, PointsLinesAdmissionError> {\n return err(new InvalidStyleError({ entity: input.entity, component, field, value, expected }));\n}\n\nfunction topologyMismatch(\n input: PointsLinesAdmissionInput,\n submesh: number,\n expected: string,\n actual: string,\n): Result<never, PointsLinesAdmissionError> {\n return err(new TopologyError({ entity: input.entity, submesh, expected, actual }));\n}\n\nfunction checkStyle(\n input: PointsLinesAdmissionInput,\n): Result<\n { component: 'Points' | 'Lines'; shape?: PointShape; sizePx?: number; widthPx?: number },\n PointsLinesAdmissionError\n> {\n const hasPoints = input.points !== undefined;\n const hasLines = input.lines !== undefined;\n if (hasPoints && hasLines) {\n return invalidStyle(\n input,\n 'Points/Lines',\n 'components',\n 'Points + Lines',\n 'exactly one style component',\n );\n }\n if (!hasPoints && !hasLines) {\n return invalidStyle(input, 'Points/Lines', 'components', undefined, 'one style component');\n }\n\n if (hasPoints) {\n const sizePx = input.points?.sizePx ?? 4;\n const shapeValue = input.points?.shape ?? PointShapeValue.square;\n const shape = pointShapeFromU32(shapeValue);\n if (!Number.isFinite(sizePx) || sizePx <= 0) {\n return invalidStyle(input, 'Points', 'sizePx', sizePx, 'finite sizePx > 0');\n }\n if (shape === undefined) {\n return invalidStyle(input, 'Points', 'shape', shapeValue, \"shape is 'square' or 'circle'\");\n }\n return ok({ component: 'Points', shape, sizePx });\n }\n\n const widthPx = input.lines?.widthPx ?? 1;\n if (!Number.isFinite(widthPx) || widthPx <= 0) {\n return invalidStyle(input, 'Lines', 'widthPx', widthPx, 'finite widthPx > 0');\n }\n return ok({ component: 'Lines', widthPx });\n}\n\nfunction checkTopology(\n input: PointsLinesAdmissionInput,\n component: 'Points' | 'Lines',\n): Result<\n { pointCount: number; segmentCount: number; submeshes: readonly number[] },\n PointsLinesAdmissionError\n> {\n const expected = component === 'Points' ? 'point-list' : 'line-list';\n let pointCount = 0;\n let segmentCount = 0;\n const acceptedSubmeshes: number[] = [];\n let sawNonEmpty = false;\n\n for (const [submeshIndex, submesh] of input.mesh.submeshes.entries()) {\n const indexed = input.mesh.indices !== undefined && submesh.indexCount > 0;\n const elementCount = indexed ? submesh.indexCount : submesh.vertexCount;\n if (elementCount === 0) continue;\n sawNonEmpty = true;\n\n if (component === 'Lines' && submesh.topology === 'line-strip') {\n return err(\n new StyleError({\n lane: 'admission',\n field: 'topology',\n member: 'line-strip',\n supported: ['line-list'],\n }),\n );\n }\n if (submesh.topology !== expected) {\n return topologyMismatch(input, submeshIndex, expected, submesh.topology);\n }\n if (component === 'Lines' && elementCount % 2 !== 0) {\n return topologyMismatch(input, submeshIndex, 'line-list pairs', 'line-list odd tail');\n }\n acceptedSubmeshes.push(submeshIndex);\n if (component === 'Points') pointCount += elementCount;\n else segmentCount += elementCount / 2;\n }\n\n if (!sawNonEmpty) return topologyMismatch(input, 0, expected, 'empty-range');\n return ok({ pointCount, segmentCount, submeshes: acceptedSubmeshes });\n}\n\nfunction checkMaterial(input: PointsLinesAdmissionInput): Result<void, PointsLinesAdmissionError> {\n const passes = input.material.passes ?? [];\n const unlitModules = new Set(['forgeax_material::unlit', 'forgeax::default-unlit']);\n if (passes.length !== 1 || passes[0] === undefined) {\n const pass =\n passes.find(\n (candidate) => candidate.name === 'deferred' || candidate.name === 'shadow-caster',\n ) ?? passes[0];\n return err(\n new MaterialError({\n entity: input.entity,\n material: input.materialId ?? '<anonymous>',\n pass: pass?.name ?? '<empty>',\n module: pass?.program.module ?? '<empty>',\n reason: 'points-lines admission requires one unlit forward pass',\n }),\n );\n }\n const pass = passes[0];\n const lightMode = (pass.renderState?.tags as Record<string, unknown> | undefined)?.LightMode;\n if (\n !unlitModules.has(pass.program.module) ||\n pass.name !== 'forward' ||\n lightMode === 'ShadowCaster'\n ) {\n return err(\n new MaterialError({\n entity: input.entity,\n material: input.materialId ?? '<anonymous>',\n pass: pass.name,\n module: pass.program.module,\n reason: 'points-lines admission requires an engine-owned unlit forward pass',\n }),\n );\n }\n return ok(undefined);\n}\n\n/** Validate one complete Points/Lines candidate before any renderer publication. */\nexport function admitPointsLines(\n input: PointsLinesAdmissionInput,\n): Result<PointsLinesAdmission, PointsLinesAdmissionError> {\n const style = checkStyle(input);\n if (!style.ok) return style;\n const topology = checkTopology(input, style.value.component);\n if (!topology.ok) return topology;\n const material = checkMaterial(input);\n if (!material.ok) return material;\n\n if (style.value.component === 'Points' && input.limits?.maxPoints !== undefined) {\n if (topology.value.pointCount > input.limits.maxPoints) {\n return err(\n new BudgetError({\n lane: 'admission',\n requested: topology.value.pointCount,\n limit: input.limits.maxPoints,\n unit: 'points',\n }),\n );\n }\n }\n if (style.value.component === 'Lines' && input.limits?.maxSegments !== undefined) {\n if (topology.value.segmentCount > input.limits.maxSegments) {\n return err(\n new BudgetError({\n lane: 'admission',\n requested: topology.value.segmentCount,\n limit: input.limits.maxSegments,\n unit: 'segments',\n }),\n );\n }\n }\n\n return ok({ ...style.value, ...topology.value });\n}\n","import type { PointShadowSnapshot } from './render-system-extract';\n\n/**\n * Detached point-shadow budget facts from one completed extract/record frame.\n *\n * `requested` is the number of PointLight + PointLightShadow pairs. The\n * renderer owns the bounded cube-array atlas, so `admitted`, `shadowed`, and\n * `shadowAtlasOccupancy` are all derived from the layer sentinel emitted by\n * the same extract owner. No consumer needs to maintain a second budget\n * ledger.\n */\nexport interface PointShadowInspection {\n readonly status: 'inactive' | 'ready' | 'over-budget';\n readonly requested: number;\n readonly admitted: number;\n readonly shadowed: number;\n readonly shadowAtlasOccupancy: number;\n readonly shadowAtlasCapacity: number;\n}\n\n/** Project point-shadow snapshots to the public, JSON-safe inspection shape. */\nexport function inspectPointShadow(\n snapshots: readonly PointShadowSnapshot[],\n shadowAtlasCapacity: number,\n): PointShadowInspection {\n const requested = snapshots.length;\n const admitted = snapshots.reduce(\n (count, snapshot) =>\n snapshot.shadowAtlasLayer >= 0 && snapshot.shadowAtlasLayer < shadowAtlasCapacity\n ? count + 1\n : count,\n 0,\n );\n // Never publish a misleading `ready` state when any requested shadow owns\n // no atlas layer. The extract sentinel is the single admission projection;\n // a partial or all-sentinel frame is therefore a failed/over-budget\n // admission, not an active shadow path with incomplete output.\n const status =\n requested === 0\n ? ('inactive' as const)\n : requested > shadowAtlasCapacity || admitted !== requested\n ? ('over-budget' as const)\n : ('ready' as const);\n return Object.freeze({\n status,\n requested,\n admitted,\n // A point shadow only samples an atlas after it owns an atlas layer. Keep\n // these names explicit for AI diagnostics while deriving both from the\n // one layer projection above.\n shadowed: admitted,\n shadowAtlasOccupancy: admitted,\n shadowAtlasCapacity,\n });\n}\n","import type { TextureFormat } from '@forgeax/engine-rhi';\nimport type { VolumeRecoveryState, VolumeSelectedLightFacts } from './recovery';\nimport type { VolumetricFogResourceFacts } from './resources';\n\nexport type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable' | 'degraded';\n\nexport type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';\n\nexport interface VolumetricFogInspection {\n readonly status: VolumetricFogInspectionStatus;\n readonly resourceStage: VolumetricFogResourceStage;\n readonly guid: string | undefined;\n readonly generation: number | undefined;\n readonly digest: string | undefined;\n readonly candidateGeneration: number | undefined;\n readonly candidateDigest: string | undefined;\n readonly lkgGeneration: number | undefined;\n readonly candidateFailure: VolumeRecoveryState['candidateFailure'];\n readonly deviceEpoch: number;\n readonly format: TextureFormat | undefined;\n readonly passCount: number;\n readonly sampleCount: number;\n readonly memoryBytes: number;\n readonly resourceFacts: VolumetricFogResourceFacts | undefined;\n readonly selectedLight: VolumeSelectedLightFacts | undefined;\n readonly candidateSelectedLight: VolumeSelectedLightFacts | undefined;\n}\n\nexport interface VolumetricFogInspectionInput {\n readonly authored: boolean;\n readonly capability: 'available' | 'unavailable';\n readonly degraded?: boolean;\n readonly recovery?: VolumeRecoveryState;\n readonly acceptedDigest?: string;\n readonly format?: TextureFormat;\n readonly passCount?: number;\n readonly sampleCount?: number;\n readonly memoryBytes?: number;\n readonly resourceFacts?: VolumetricFogResourceFacts;\n}\n\nfunction resourceStage(input: VolumetricFogInspectionInput): VolumetricFogResourceStage {\n if (!input.authored || input.recovery === undefined) return 'none';\n if (input.recovery.status === 'candidate') return 'candidate';\n if (input.recovery.status === 'recovering') return 'recovering';\n if (input.recovery.status === 'degraded') return 'lkg';\n return 'accepted';\n}\n\nexport function inspectVolumetricFog(input: VolumetricFogInspectionInput): VolumetricFogInspection {\n const recovery = input.recovery;\n const status: VolumetricFogInspectionStatus = !input.authored\n ? 'off'\n : input.capability === 'unavailable'\n ? 'unavailable'\n : input.degraded === true || recovery?.status === 'degraded'\n ? 'degraded'\n : 'available';\n return Object.freeze({\n status,\n resourceStage: resourceStage(input),\n guid: recovery?.guid,\n generation: recovery?.generation,\n digest: input.acceptedDigest,\n candidateGeneration: recovery?.candidateGeneration,\n candidateDigest: recovery?.candidateDigest,\n lkgGeneration: recovery?.lkgGeneration,\n candidateFailure: recovery?.candidateFailure,\n deviceEpoch: recovery?.deviceEpoch ?? 0,\n format: input.format,\n passCount: input.passCount ?? 0,\n sampleCount: input.sampleCount ?? 0,\n memoryBytes: input.memoryBytes ?? 0,\n resourceFacts: input.resourceFacts,\n selectedLight: recovery?.selectedLight,\n candidateSelectedLight: recovery?.candidateSelectedLight,\n });\n}\n","import { type Mat4, mat4, type Vec3Like } from '@forgeax/engine-math';\nimport { CUBE_CAMERA_FACE_ORDER, type CubeCameraFace } from '../components/cube-camera';\n\nexport interface CubeCameraFaceView {\n readonly position: Vec3Like;\n readonly face: CubeCameraFace;\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n readonly near: number;\n readonly far: number;\n readonly view: Mat4;\n readonly projection: Mat4;\n readonly viewProjection: Mat4;\n}\n\nexport interface CubeCameraFaceViewInput {\n readonly position: Vec3Like;\n readonly near: number;\n readonly far: number;\n}\n\nconst FACE_ORIENTATION: ReadonlyArray<{\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n}> = [\n { direction: [1, 0, 0], up: [0, 1, 0] },\n { direction: [-1, 0, 0], up: [0, 1, 0] },\n { direction: [0, 1, 0], up: [0, 0, -1] },\n { direction: [0, -1, 0], up: [0, 0, 1] },\n { direction: [0, 0, 1], up: [0, 1, 0] },\n { direction: [0, 0, -1], up: [0, 1, 0] },\n];\n\nfunction assertRange(near: number, far: number): void {\n if (!Number.isFinite(near) || near <= 0 || !Number.isFinite(far) || far <= near) {\n throw new RangeError('CubeCamera requires finite near > 0 and far > near.');\n }\n}\n\n/** Build the only supported +X,-X,+Y,-Y,+Z,-Z cube orientation. */\nexport function buildCubeCameraFaceViews(input: CubeCameraFaceViewInput): CubeCameraFaceView[] {\n assertRange(input.near, input.far);\n const views: CubeCameraFaceView[] = [];\n for (const [index, face] of CUBE_CAMERA_FACE_ORDER.entries()) {\n const orientation = FACE_ORIENTATION[index];\n if (orientation === undefined)\n throw new Error(`CubeCamera face orientation missing at ${index}`);\n const target: Vec3Like = [\n (input.position[0] ?? 0) + orientation.direction[0],\n (input.position[1] ?? 0) + orientation.direction[1],\n (input.position[2] ?? 0) + orientation.direction[2],\n ];\n const view = mat4.lookAt(mat4.create(), input.position, target, orientation.up);\n const projection = mat4.perspective(mat4.create(), Math.PI / 2, 1, input.near, input.far);\n const viewProjection = mat4.multiply(mat4.create(), projection, view);\n views.push({\n position: input.position,\n face,\n direction: orientation.direction,\n up: orientation.up,\n near: input.near,\n far: input.far,\n view,\n projection,\n viewProjection,\n });\n }\n return views;\n}\n","export interface ProbeFilterState {\n readonly probeIndex: number;\n readonly faceCount: number;\n readonly mipCount: number;\n readonly cursor: number;\n readonly activeGeneration: number;\n}\n\nexport function createProbeFilterState(input: {\n readonly probeIndex: number;\n readonly faceCount?: number;\n readonly mipCount: number;\n readonly activeGeneration?: number;\n}): ProbeFilterState {\n return {\n probeIndex: input.probeIndex,\n faceCount: input.faceCount ?? 6,\n mipCount: input.mipCount,\n cursor: 0,\n activeGeneration: input.activeGeneration ?? 0,\n };\n}\n\nexport function advanceProbeFilter(\n state: ProbeFilterState,\n):\n | { readonly probeIndex: number; readonly faceIndex: number; readonly mipLevel: number }\n | undefined {\n const total = state.faceCount * state.mipCount;\n if (state.cursor >= total) return undefined;\n return {\n probeIndex: state.probeIndex,\n faceIndex: state.cursor % state.faceCount,\n mipLevel: Math.floor(state.cursor / state.faceCount),\n };\n}\n\nexport function commitProbeFilterStep(state: ProbeFilterState, success: boolean): ProbeFilterState {\n if (!success) return state;\n const nextCursor = state.cursor + 1;\n const complete = nextCursor >= state.faceCount * state.mipCount;\n return {\n ...state,\n cursor: nextCursor,\n activeGeneration: complete ? state.activeGeneration + 1 : state.activeGeneration,\n };\n}\n\nexport function probeFilterIsSteady(state: ProbeFilterState): boolean {\n return state.cursor >= state.faceCount * state.mipCount;\n}\n\nfunction normalize(vector: readonly [number, number, number]): [number, number, number] {\n const length = Math.hypot(vector[0], vector[1], vector[2]);\n if (length === 0) return [0, 0, 1];\n return [vector[0] / length, vector[1] / length, vector[2] / length];\n}\n\nexport function boxProjectReflectionDirection(\n direction: readonly [number, number, number],\n boxCenter: readonly [number, number, number],\n halfExtents: readonly [number, number, number],\n point: readonly [number, number, number],\n): [number, number, number] {\n const ray = normalize(direction);\n let distance = Number.POSITIVE_INFINITY;\n for (let axis = 0; axis < 3; axis += 1) {\n const component = ray[axis] ?? 0;\n if (component === 0) continue;\n const extent = halfExtents[axis] ?? 0;\n const edge = component > 0 ? (boxCenter[axis] ?? 0) + extent : (boxCenter[axis] ?? 0) - extent;\n const candidate = (edge - (point[axis] ?? 0)) / component;\n if (candidate > 0) distance = Math.min(distance, candidate);\n }\n if (!Number.isFinite(distance)) return ray;\n return normalize([\n (point[0] ?? 0) + ray[0] * distance - (boxCenter[0] ?? 0),\n (point[1] ?? 0) + ray[1] * distance - (boxCenter[1] ?? 0),\n (point[2] ?? 0) + ray[2] * distance - (boxCenter[2] ?? 0),\n ]);\n}\n","import type { Buffer, Sampler, TextureView } from '@forgeax/engine-rhi';\n\nexport interface ReflectionProbeTableRow {\n readonly primitiveKey?: string;\n readonly index: number;\n readonly worldId: number;\n readonly entityKey: number;\n readonly center: readonly [number, number, number];\n readonly halfExtents: readonly [number, number, number];\n readonly intensity: number;\n readonly generation: number;\n /** Renderer-owned filtered cube used by the Standard material lane. */\n readonly filteredView?: TextureView;\n /** Renderer-owned sampler paired with filteredView. */\n readonly sampler?: Sampler;\n /** Per-probe uniform payload; keeps MaterialAsset ABI unchanged. */\n readonly uniformBuffer?: Buffer;\n}\n\nexport interface ReflectionProbeTable {\n readonly rows: readonly ReflectionProbeTableRow[];\n readonly cpuIndexByPrimitive: (primitiveKey: string) => number | undefined;\n readonly gpuIndexByPrimitive: (primitiveKey: string) => number | undefined;\n}\n\nexport function buildReflectionProbeTable(\n rows: readonly ReflectionProbeTableRow[],\n): ReflectionProbeTable {\n const ordered = rows.slice().sort((a, b) => a.index - b.index);\n const indices = new Map<string, number>();\n for (const row of ordered) {\n if (row.primitiveKey !== undefined) indices.set(row.primitiveKey, row.index);\n }\n const indexFor = (primitiveKey: string): number | undefined => indices.get(primitiveKey);\n return {\n rows: Object.freeze(ordered),\n cpuIndexByPrimitive: indexFor,\n gpuIndexByPrimitive: indexFor,\n };\n}\n\nexport function reflectionProbeTableBytes(table: ReflectionProbeTable): number {\n return table.rows.length * 48;\n}\n","import type {\n ReflectionFallbackFailureStage,\n ReflectionFallbackInspection,\n ReflectionFallbackReceipt,\n ReflectionFallbackRecoveryAction,\n} from '../inspection-types';\n\nexport interface ReflectionFallbackFailureInput {\n readonly stage: ReflectionFallbackFailureStage;\n readonly code: string;\n readonly expected: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nfunction recoveryFor(\n receipt: ReflectionFallbackReceipt,\n failure?: ReflectionFallbackFailureInput,\n): ReflectionFallbackRecoveryAction {\n if (failure !== undefined) {\n const code = failure.code.toLowerCase();\n if (code.includes('device') || code.includes('format') || code.includes('capability')) {\n return 'rebuild';\n }\n if (failure.stage === 'prepare' || failure.stage === 'filter') return 'recapture';\n if (failure.stage === 'build' || failure.stage === 'encode') return 'rebuild';\n if (failure.stage === 'finish' || failure.stage === 'submit') return 'retry';\n // Completion failures may still retain a source-identical committed row;\n // use it as LKG, otherwise retry the producer completion.\n if (failure.stage === 'completion') {\n if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {\n return 'use-LKG';\n }\n if (\n receipt.source === 'skylight' &&\n (receipt.state === 'active' || receipt.state === 'lkg')\n ) {\n return 'use-Skylight';\n }\n if (receipt.source === 'neutral' && receipt.state === 'neutral') return 'use-neutral';\n return 'retry';\n }\n }\n if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {\n return 'use-LKG';\n }\n if (receipt.source === 'skylight' || receipt.state === 'lkg') return 'use-Skylight';\n return 'use-neutral';\n}\n\n/** Projects producer state and the latest closed failure into detached facts. */\nexport function inspectReflectionFallback(\n receipt: ReflectionFallbackReceipt,\n failure?: ReflectionFallbackFailureInput,\n): ReflectionFallbackInspection {\n return {\n receipt,\n recoveryAction: recoveryFor(receipt, failure),\n ...(failure === undefined\n ? {}\n : {\n failureStage: failure.stage,\n failureCode: failure.code,\n expected: failure.expected,\n ...(failure.detail === undefined ? {} : { detail: failure.detail }),\n }),\n };\n}\n","import type { ReflectionProbeUpdateIntent } from '../components/reflection-probe';\n\nexport const REFLECTION_PROBE_BYTES_PER_TEXEL = 8;\nexport const DEFAULT_REFLECTION_PROBE_LIMITS = Object.freeze({\n maxProbes: 16,\n maxResolution: 256,\n maxBytes: 64 * 1024 * 1024,\n});\n\nexport interface ReflectionProbeInput {\n readonly halfExtents: readonly [number, number, number];\n readonly priority: number;\n readonly intensity: number;\n readonly resolution: number;\n}\n\nexport interface ReflectionProbeFact extends ReflectionProbeInput {\n readonly worldId: number;\n readonly entityKey: number;\n readonly center: readonly [number, number, number];\n readonly revision: number;\n readonly updateIntent?: ReflectionProbeUpdateIntent;\n readonly invalidationVersion?: number;\n}\n\nexport interface ReflectionProbeAdmissionLimits {\n readonly maxProbes?: number;\n readonly maxResolution?: number;\n readonly maxBytes?: number;\n}\n\nexport interface ReflectionProbeInvalidInput {\n readonly code: 'reflection-probe-input-invalid';\n readonly field: string;\n readonly value: unknown;\n readonly expected: string;\n}\n\nexport interface ReflectionProbeBudgetFailure {\n readonly code: 'reflection-probe-budget-exceeded';\n readonly requested: number;\n readonly activeCount: number;\n readonly activeBytes: number;\n readonly maxProbes: number;\n readonly maxBytes: number;\n}\n\nexport type ReflectionProbeAdmission =\n | { readonly ok: true; readonly acceptedBytes: number }\n | { readonly ok: false; readonly error: ReflectionProbeBudgetFailure };\n\nexport function validateReflectionProbeInput(\n input: ReflectionProbeInput,\n): { readonly ok: true } | { readonly ok: false; readonly error: ReflectionProbeInvalidInput } {\n for (let index = 0; index < input.halfExtents.length; index += 1) {\n const value = input.halfExtents[index];\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: `halfExtents[${index}]`,\n value,\n expected: 'a finite number greater than zero',\n },\n };\n }\n }\n if (!Number.isFinite(input.priority)) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'priority',\n value: input.priority,\n expected: 'a finite number',\n },\n };\n }\n if (!Number.isFinite(input.intensity) || input.intensity < 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'intensity',\n value: input.intensity,\n expected: 'a finite number greater than or equal to zero',\n },\n };\n }\n if (!Number.isInteger(input.resolution) || input.resolution <= 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-input-invalid',\n field: 'resolution',\n value: input.resolution,\n expected: 'a positive integer',\n },\n };\n }\n return { ok: true };\n}\n\nexport function estimateReflectionProbeBytes(\n resolution: number,\n limits: ReflectionProbeAdmissionLimits = DEFAULT_REFLECTION_PROBE_LIMITS,\n): number {\n const maxResolution = limits.maxResolution ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxResolution;\n const clamped = Math.min(resolution, maxResolution);\n let mipTexels = 0;\n for (let size = clamped; size >= 1; size = Math.floor(size / 2)) {\n mipTexels += size * size;\n }\n return mipTexels * 6 * REFLECTION_PROBE_BYTES_PER_TEXEL;\n}\n\nexport function admitReflectionProbe(\n input: ReflectionProbeInput,\n current: { readonly acceptedCount: number; readonly acceptedBytes: number },\n limits: ReflectionProbeAdmissionLimits = DEFAULT_REFLECTION_PROBE_LIMITS,\n): ReflectionProbeAdmission {\n const maxProbes = limits.maxProbes ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxProbes;\n const maxBytes = limits.maxBytes ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxBytes;\n const maxResolution = limits.maxResolution ?? DEFAULT_REFLECTION_PROBE_LIMITS.maxResolution;\n const requested = estimateReflectionProbeBytes(input.resolution, { maxResolution });\n if (\n input.resolution > maxResolution ||\n current.acceptedCount >= maxProbes ||\n current.acceptedBytes + requested > maxBytes\n ) {\n return {\n ok: false,\n error: {\n code: 'reflection-probe-budget-exceeded',\n requested,\n activeCount: current.acceptedCount,\n activeBytes: current.acceptedBytes,\n maxProbes,\n maxBytes,\n },\n };\n }\n return { ok: true, acceptedBytes: current.acceptedBytes + requested };\n}\n\nexport interface ReflectionProbeSelection {\n readonly kind: 'probe';\n readonly worldId: number;\n readonly entityKey: number;\n readonly normalizedDistance: number;\n}\n\nexport interface SkylightSelection {\n readonly kind: 'skylight';\n}\n\nexport type ReflectionProbeSelectionResult = ReflectionProbeSelection | SkylightSelection;\n\nexport type ReflectionFallbackSource = 'probe' | 'skylight' | 'neutral';\n\nexport interface ReflectionFallbackProjectionInput {\n /** Stable renderable identity used to join the main-pass projection. */\n readonly renderableKey?: string;\n /** Stable producer source identity; never a live GPU handle. */\n readonly sourceKey?: string;\n readonly source: ReflectionFallbackSource;\n readonly coverage: number;\n readonly extent?: readonly [number, number, number];\n readonly linearHdr: readonly [number, number, number, number];\n readonly brdfSignature: string;\n}\n\nexport interface ReflectionFallbackProjection extends ReflectionFallbackProjectionInput {\n readonly source: ReflectionFallbackSource;\n}\n\nexport type ReflectionFallbackMismatchKind = 'source' | 'coverage' | 'extent' | 'brdf';\n\nexport interface ReflectionFallbackMismatch {\n readonly code:\n | 'reflection-fallback-source-mismatch'\n | 'reflection-fallback-coverage-mismatch'\n | 'reflection-fallback-extent-mismatch'\n | 'reflection-fallback-brdf-mismatch';\n readonly expected: string;\n readonly actual: string;\n}\n\nexport interface ReflectionFallbackInputInvalid {\n readonly code: 'reflection-fallback-input-invalid';\n readonly field: string;\n readonly expected: string;\n}\n\nexport type ReflectionFallbackProjectionResult =\n | { readonly ok: true; readonly value: ReflectionFallbackProjection }\n | { readonly ok: false; readonly error: ReflectionFallbackInputInvalid };\n\nexport function resolveReflectionFallbackSource(\n selection: ReflectionProbeSelectionResult,\n probeReady: boolean,\n skylightAvailable = true,\n): ReflectionFallbackSource {\n if (selection.kind === 'probe' && probeReady) return 'probe';\n // An unavailable probe follows the producer recovery order: use the active\n // Skylight when one exists, then the producer-owned neutral zero. Returning\n // neutral directly here would make the main Standard lighting lane and the\n // detached fallback projection disagree.\n if (skylightAvailable) return 'skylight';\n return 'neutral';\n}\n\nexport function reflectionFallbackCoverage(\n source: ReflectionFallbackSource,\n fact: ReflectionProbeFact | undefined,\n selection: ReflectionProbeSelectionResult,\n): number {\n if (source === 'neutral') return 0;\n if (source === 'skylight') return 1;\n if (fact === undefined || selection.kind !== 'probe') return 0;\n const normalized = Math.sqrt(Math.max(0, selection.normalizedDistance));\n return Math.max(0, Math.min(1, 1 - normalized / Math.sqrt(3)));\n}\n\nexport function reflectionFallbackSourceKey(\n source: ReflectionFallbackSource,\n selection: ReflectionProbeSelectionResult,\n skylight?: { readonly entityHandle: number; readonly equirectHandle: number },\n): string {\n if (source === 'probe' && selection.kind === 'probe') {\n return `probe:${selection.worldId}:${selection.entityKey}`;\n }\n if (source === 'skylight' && skylight !== undefined) {\n return `skylight:${skylight.entityHandle}:${skylight.equirectHandle}`;\n }\n return source;\n}\n\nexport function reflectionFallbackProjectionSignature(\n input: ReflectionFallbackProjectionInput,\n): string {\n return JSON.stringify({\n renderableKey: input.renderableKey,\n sourceKey: input.sourceKey,\n source: input.source,\n coverage: input.coverage,\n extent: input.extent,\n brdfSignature: input.brdfSignature,\n });\n}\n\nexport function deriveReflectionFallbackProjection(\n input: ReflectionFallbackProjectionInput,\n): ReflectionFallbackProjectionResult {\n if (!Number.isFinite(input.coverage) || input.coverage < 0 || input.coverage > 1) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'coverage',\n expected: 'a finite number between zero and one',\n },\n };\n }\n if (input.extent?.some((value) => !Number.isFinite(value) || value <= 0)) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'extent',\n expected: 'three finite numbers greater than zero',\n },\n };\n }\n if (input.linearHdr.some((value) => !Number.isFinite(value))) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'linearHdr',\n expected: 'four finite linear HDR values',\n },\n };\n }\n if (input.brdfSignature.length === 0) {\n return {\n ok: false,\n error: {\n code: 'reflection-fallback-input-invalid',\n field: 'brdfSignature',\n expected: 'a non-empty BRDF signature',\n },\n };\n }\n const linearHdr = input.source === 'neutral' ? ([0, 0, 0, 0] as const) : [...input.linearHdr];\n return {\n ok: true,\n value: Object.freeze({\n ...(input.renderableKey === undefined ? {} : { renderableKey: input.renderableKey }),\n ...(input.sourceKey === undefined ? {} : { sourceKey: input.sourceKey }),\n source: input.source,\n coverage: input.coverage,\n ...(input.extent === undefined\n ? {}\n : {\n extent: Object.freeze([...input.extent]) as readonly [number, number, number],\n }),\n linearHdr: Object.freeze(linearHdr) as ReflectionFallbackProjection['linearHdr'],\n brdfSignature: input.brdfSignature,\n }),\n };\n}\n\nexport function validateReflectionFallbackCompatibility(\n expected: ReflectionFallbackProjectionInput,\n actual: ReflectionFallbackProjectionInput,\n): { readonly ok: true } | { readonly ok: false; readonly error: ReflectionFallbackMismatch } {\n const mismatch = (\n kind: ReflectionFallbackMismatchKind,\n expectedValue: string,\n actualValue: string,\n ): { readonly ok: false; readonly error: ReflectionFallbackMismatch } => ({\n ok: false,\n error: {\n code: `reflection-fallback-${kind}-mismatch` as ReflectionFallbackMismatch['code'],\n expected: expectedValue,\n actual: actualValue,\n },\n });\n if (expected.source !== actual.source) {\n return mismatch('source', expected.source, actual.source);\n }\n if (expected.coverage !== actual.coverage) {\n return mismatch('coverage', String(expected.coverage), String(actual.coverage));\n }\n const expectedExtent = expected.extent;\n const actualExtent = actual.extent;\n if (\n (expectedExtent === undefined && actualExtent !== undefined) ||\n (expectedExtent !== undefined &&\n (actualExtent === undefined ||\n expectedExtent.some((value, index) => value !== actualExtent[index])))\n ) {\n return mismatch('extent', JSON.stringify(expectedExtent), JSON.stringify(actualExtent));\n }\n if (expected.brdfSignature !== actual.brdfSignature) {\n return mismatch('brdf', expected.brdfSignature, actual.brdfSignature);\n }\n return { ok: true };\n}\n\nfunction contains(fact: ReflectionProbeFact, point: readonly [number, number, number]): boolean {\n return fact.halfExtents.every((extent, axis) => {\n const center = fact.center[axis] ?? 0;\n const coordinate = point[axis] ?? 0;\n return Math.abs(coordinate - center) <= extent;\n });\n}\n\nfunction normalizedDistance(\n fact: ReflectionProbeFact,\n point: readonly [number, number, number],\n): number {\n let squared = 0;\n for (let axis = 0; axis < 3; axis += 1) {\n const delta = (point[axis] ?? 0) - (fact.center[axis] ?? 0);\n const extent = fact.halfExtents[axis] ?? 1;\n squared += (delta / extent) ** 2;\n }\n return squared;\n}\n\nfunction isBetter(\n candidate: ReflectionProbeSelection,\n current: ReflectionProbeSelection,\n facts: readonly ReflectionProbeFact[],\n): boolean {\n const candidateFact = facts.find(\n (fact) => fact.worldId === candidate.worldId && fact.entityKey === candidate.entityKey,\n );\n const currentFact = facts.find(\n (fact) => fact.worldId === current.worldId && fact.entityKey === current.entityKey,\n );\n if (candidateFact === undefined || currentFact === undefined) return false;\n if (candidateFact.priority !== currentFact.priority)\n return candidateFact.priority > currentFact.priority;\n if (candidate.normalizedDistance !== current.normalizedDistance) {\n return candidate.normalizedDistance < current.normalizedDistance;\n }\n return (\n candidate.worldId < current.worldId ||\n (candidate.worldId === current.worldId && candidate.entityKey < current.entityKey)\n );\n}\n\nexport function selectReflectionProbe(\n facts: readonly ReflectionProbeFact[],\n primitiveCenter: readonly [number, number, number],\n): ReflectionProbeSelectionResult {\n let selected: ReflectionProbeSelection | undefined;\n for (const fact of facts) {\n if (!contains(fact, primitiveCenter)) continue;\n const candidate: ReflectionProbeSelection = {\n kind: 'probe',\n worldId: fact.worldId,\n entityKey: fact.entityKey,\n normalizedDistance: normalizedDistance(fact, primitiveCenter),\n };\n if (selected === undefined || isBetter(candidate, selected, facts)) selected = candidate;\n }\n return selected ?? { kind: 'skylight' };\n}\n\nexport interface ReflectionProbePrimitive {\n readonly worldId: number;\n readonly entityKey: number;\n /** Main-pass renderable key; world/entity is retained as the compatibility fallback. */\n readonly renderableKey?: string;\n readonly center: readonly [number, number, number];\n}\n\nexport interface ReflectionProbeProjectionSnapshot {\n readonly revision: number;\n readonly facts: readonly ReflectionProbeFact[];\n readonly selected: ReadonlyMap<string, ReflectionProbeSelectionResult>;\n readonly scannedPrimitives: number;\n}\n\nfunction primitiveKey(worldId: number, entityKey: number): string {\n return `${worldId}:${entityKey}`;\n}\n\nexport class ReflectionProbeProjection {\n private revision = 0;\n private facts: readonly ReflectionProbeFact[] = [];\n private selected = new Map<string, ReflectionProbeSelectionResult>();\n private signature = '';\n private scannedPrimitives = 0;\n\n update(\n facts: readonly ReflectionProbeFact[],\n primitives: readonly ReflectionProbePrimitive[],\n ): ReflectionProbeProjectionSnapshot {\n const nextFacts = facts\n .slice()\n .sort((a, b) => a.worldId - b.worldId || a.entityKey - b.entityKey);\n const signature = JSON.stringify({ facts: nextFacts, primitives });\n if (signature === this.signature) return this.snapshot();\n this.signature = signature;\n this.facts = nextFacts;\n this.selected = new Map();\n for (const primitive of primitives) {\n this.selected.set(\n primitive.renderableKey ?? primitiveKey(primitive.worldId, primitive.entityKey),\n selectReflectionProbe(nextFacts, primitive.center),\n );\n }\n this.scannedPrimitives = primitives.length;\n this.revision += 1;\n return this.snapshot();\n }\n\n snapshot(): ReflectionProbeProjectionSnapshot {\n return {\n revision: this.revision,\n facts: this.facts,\n selected: this.selected,\n scannedPrimitives: this.scannedPrimitives,\n };\n }\n\n selection(worldId: number, entityKey: number): ReflectionProbeSelectionResult {\n return this.selected.get(primitiveKey(worldId, entityKey)) ?? { kind: 'skylight' };\n }\n}\n","import { createVisibilityBudget } from './budget';\n\n/** Detached, bounded LOD/occlusion facts for renderer inspection consumers. */\n\nexport const LOD_OCCLUSION_INSPECTION_SCHEMA = 'forgeax::lod-occlusion-inspection::v2' as const;\nexport const LOD_OCCLUSION_INSPECTION_MAX_BYTES = 16 * 1024;\nconst MAX_INSPECTION_SAMPLES = 64;\n\nexport type LodOcclusionInspectionError = {\n readonly code: string;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, string | number | boolean>>;\n};\n\nexport type LodOcclusionFallback =\n | { readonly active: false }\n | {\n readonly active: true;\n readonly reason: 'producer-failed' | 'page-exhausted' | 'query-failed' | 'device-loss';\n readonly error: LodOcclusionInspectionError;\n };\n\nexport type LodOcclusionDegradation =\n | { readonly active: false }\n | { readonly active: true; readonly reason: 'all-visible' | 'query-unavailable' };\n\nexport interface LodOcclusionInspectionSample {\n readonly primitiveSlot: number;\n readonly level: number;\n readonly visible: boolean;\n}\n\nexport interface LodOcclusionInspectionRow {\n readonly root: { readonly guid: string; readonly sourceKey: string };\n readonly view: {\n readonly attachmentId: string;\n readonly cameraEntity: number;\n readonly viewRole: 'main' | 'shadow' | 'reflection' | 'probe';\n readonly viewGeneration: number;\n };\n readonly slot: { readonly primitiveSlot: number; readonly slotGeneration: number };\n readonly generation: number;\n readonly count: {\n readonly candidates: number;\n readonly visible: number;\n readonly occluded: number;\n };\n readonly lodHistogram: readonly { readonly level: number; readonly count: number }[];\n /** Map latency for the most recently completed query page (bounded POD). */\n readonly queryLatencyUs: {\n readonly median: number;\n readonly p95: number;\n readonly last: number;\n };\n readonly pagePressure: { readonly used: number; readonly capacity: number };\n readonly fallback: LodOcclusionFallback;\n readonly degradation: LodOcclusionDegradation;\n readonly samples: readonly LodOcclusionInspectionSample[];\n}\n\nexport interface LodOcclusionInspectionSubmit {\n readonly frameId: number;\n readonly build: string;\n readonly deviceGeneration: number;\n}\n\n/**\n * Per-World attribution is only authoritative when the renderer publishes\n * the GPU facts from the same submit that owns the parent inspection. The\n * normal projection path remains useful diagnostics, but it must not be used\n * as evidence for a World-reorder or per-World LOD claim.\n */\nexport type LodOcclusionWorldAttribution =\n | { readonly status: 'unavailable'; readonly reason: 'projection-only' }\n | { readonly status: 'same-submit'; readonly submit: LodOcclusionInspectionSubmit };\n\nexport interface LodOcclusionWorldInspection {\n readonly attachmentId: string;\n readonly rows: readonly LodOcclusionInspectionRow[];\n readonly attribution: LodOcclusionWorldAttribution;\n}\n\nexport interface LodOcclusionInspectionBudget {\n readonly configuredQueryBudget: number;\n readonly effectiveQueryBudget: number;\n readonly settleSubmits: number;\n readonly retestSubmits: number;\n readonly expirySubmits: number;\n}\n\nexport interface LodOcclusionInspection extends LodOcclusionInspectionRow {\n readonly schema: typeof LOD_OCCLUSION_INSPECTION_SCHEMA;\n /** Atomic identity for the submit that produced every row below. */\n readonly submit: LodOcclusionInspectionSubmit;\n /** Immutable budget values used by the query and confidence owners. */\n readonly budget: LodOcclusionInspectionBudget;\n /** Stable attachment identity; array order is never an attribution key. */\n readonly worlds: readonly LodOcclusionWorldInspection[];\n}\n\nexport type LodOcclusionInspectionInput = Omit<\n LodOcclusionInspection,\n 'schema' | 'submit' | 'budget' | 'worlds'\n> & {\n readonly submit?: LodOcclusionInspectionSubmit;\n readonly budget?: LodOcclusionInspectionBudget;\n readonly worlds?: readonly LodOcclusionWorldInspectionInput[];\n};\n\nexport type LodOcclusionWorldInspectionInput = Omit<LodOcclusionWorldInspection, 'attribution'> & {\n readonly attribution?: LodOcclusionWorldAttribution;\n};\n\nexport type LodOcclusionInspectionAction =\n | { readonly action: 'none' }\n | { readonly action: 'rebuild'; readonly sourceKey: string; readonly reason: string }\n | { readonly action: 'cold-cook'; readonly sourceKey: string; readonly reason: string }\n | { readonly action: 'retry'; readonly sourceKey: string; readonly reason: string };\n\nfunction nonNegativeInteger(name: string, value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new Error(`${name} must be a non-negative integer`);\n return value;\n}\n\nfunction copyError(error: LodOcclusionInspectionError): LodOcclusionInspectionError {\n return Object.freeze({\n code: error.code,\n expected: error.expected,\n hint: error.hint,\n ...(error.detail === undefined ? {} : { detail: Object.freeze({ ...error.detail }) }),\n });\n}\n\nfunction copyFallback(fallback: LodOcclusionFallback): LodOcclusionFallback {\n return fallback.active\n ? Object.freeze({ ...fallback, error: copyError(fallback.error) })\n : Object.freeze({ active: false });\n}\n\nfunction copySamples(\n samples: readonly LodOcclusionInspectionSample[],\n): readonly LodOcclusionInspectionSample[] {\n return Object.freeze(\n [...samples]\n .sort((left, right) => left.primitiveSlot - right.primitiveSlot)\n .slice(0, MAX_INSPECTION_SAMPLES)\n .map((sample) =>\n Object.freeze({\n primitiveSlot: nonNegativeInteger('sample.primitiveSlot', sample.primitiveSlot),\n level: nonNegativeInteger('sample.level', sample.level),\n visible: sample.visible,\n }),\n ),\n );\n}\n\nfunction copyWorldAttribution(\n attribution: LodOcclusionWorldAttribution | undefined,\n): LodOcclusionWorldAttribution {\n if (attribution === undefined) {\n return Object.freeze({ status: 'unavailable', reason: 'projection-only' });\n }\n if (attribution.status === 'same-submit') {\n if (typeof attribution.submit.build !== 'string' || attribution.submit.build.length === 0) {\n throw new Error('world.attribution.submit.build must be a non-empty string');\n }\n nonNegativeInteger('world.attribution.submit.frameId', attribution.submit.frameId);\n nonNegativeInteger(\n 'world.attribution.submit.deviceGeneration',\n attribution.submit.deviceGeneration,\n );\n return Object.freeze({\n status: 'same-submit',\n submit: Object.freeze({ ...attribution.submit }),\n });\n }\n if (attribution.status !== 'unavailable' || attribution.reason !== 'projection-only') {\n throw new Error('world.attribution must declare same-submit or projection-only');\n }\n return Object.freeze({ status: 'unavailable', reason: 'projection-only' });\n}\n\nfunction copyRow(row: LodOcclusionInspectionRow): LodOcclusionInspectionRow {\n for (const [name, value] of Object.entries({\n generation: row.generation,\n candidates: row.count.candidates,\n visible: row.count.visible,\n occluded: row.count.occluded,\n median: row.queryLatencyUs.median,\n p95: row.queryLatencyUs.p95,\n last: row.queryLatencyUs.last,\n pageUsed: row.pagePressure.used,\n pageCapacity: row.pagePressure.capacity,\n }))\n nonNegativeInteger(`inspection.${name}`, value);\n if (\n row.view.cameraEntity < 0 ||\n row.view.viewGeneration < 0 ||\n row.slot.primitiveSlot < 0 ||\n row.slot.slotGeneration < 0\n ) {\n throw new Error('inspection identity values must be non-negative');\n }\n if (row.pagePressure.used > row.pagePressure.capacity) {\n throw new Error('inspection page pressure exceeds capacity');\n }\n return Object.freeze({\n root: Object.freeze({ ...row.root }),\n view: Object.freeze({ ...row.view }),\n slot: Object.freeze({ ...row.slot }),\n generation: row.generation,\n count: Object.freeze({ ...row.count }),\n lodHistogram: Object.freeze(\n row.lodHistogram.map((histogram) =>\n Object.freeze({\n level: nonNegativeInteger('histogram.level', histogram.level),\n count: nonNegativeInteger('histogram.count', histogram.count),\n }),\n ),\n ),\n queryLatencyUs: Object.freeze({ ...row.queryLatencyUs }),\n pagePressure: Object.freeze({ ...row.pagePressure }),\n fallback: copyFallback(row.fallback),\n degradation: Object.freeze({ ...row.degradation }),\n samples: copySamples(row.samples),\n });\n}\n\nfunction copyWorlds(\n worlds: readonly LodOcclusionWorldInspectionInput[] | undefined,\n fallback: LodOcclusionInspectionRow,\n): readonly LodOcclusionWorldInspection[] {\n const source = worlds ?? [{ attachmentId: fallback.view.attachmentId, rows: [fallback] }];\n return Object.freeze(\n source.map((world) =>\n Object.freeze({\n attachmentId: world.attachmentId,\n rows: Object.freeze(world.rows.map((row) => copyRow(row))),\n attribution: copyWorldAttribution(world.attribution),\n }),\n ),\n );\n}\n\nexport function inspectLodOcclusion(input: LodOcclusionInspectionInput): LodOcclusionInspection {\n const row = copyRow(input);\n const defaultBudget = createVisibilityBudget();\n const budget = input.budget ?? {\n configuredQueryBudget: defaultBudget.configuredQueryBudget,\n effectiveQueryBudget: defaultBudget.effectiveQueryBudget,\n settleSubmits: defaultBudget.settleSubmits,\n retestSubmits: defaultBudget.retestSubmits,\n expirySubmits: defaultBudget.expirySubmits,\n };\n for (const [name, value] of Object.entries(budget))\n nonNegativeInteger(`inspection.budget.${name}`, value);\n const submit = input.submit ?? {\n frameId: input.generation,\n build: 'unknown',\n deviceGeneration: 0,\n };\n nonNegativeInteger('inspection.submit.frameId', submit.frameId);\n nonNegativeInteger('inspection.submit.deviceGeneration', submit.deviceGeneration);\n if (typeof submit.build !== 'string' || submit.build.length === 0) {\n throw new Error('inspection.submit.build must be a non-empty string');\n }\n const worlds = copyWorlds(input.worlds, row);\n for (const world of worlds) {\n if (\n world.attribution.status === 'same-submit' &&\n (world.attribution.submit.frameId !== submit.frameId ||\n world.attribution.submit.build !== submit.build ||\n world.attribution.submit.deviceGeneration !== submit.deviceGeneration)\n ) {\n throw new Error('world attribution must reference the parent inspection submit');\n }\n }\n const inspection: LodOcclusionInspection = Object.freeze({\n schema: LOD_OCCLUSION_INSPECTION_SCHEMA,\n ...row,\n submit: Object.freeze({ ...submit }),\n budget: Object.freeze({ ...budget }),\n worlds,\n });\n if (JSON.stringify(inspection).length > LOD_OCCLUSION_INSPECTION_MAX_BYTES) {\n throw new Error(`LOD occlusion inspection exceeds ${LOD_OCCLUSION_INSPECTION_MAX_BYTES} bytes`);\n }\n return inspection;\n}\n\nexport function serializeLodOcclusionInspection(inspection: LodOcclusionInspection): string {\n const serialized = JSON.stringify(inspection);\n if (serialized.length > LOD_OCCLUSION_INSPECTION_MAX_BYTES) {\n throw new Error(`LOD occlusion inspection exceeds ${LOD_OCCLUSION_INSPECTION_MAX_BYTES} bytes`);\n }\n return serialized;\n}\n\nexport function consumeLodOcclusionInspection(\n inspection: LodOcclusionInspection,\n): LodOcclusionInspectionAction {\n if (!inspection.fallback.active) return { action: 'none' };\n const { reason, error } = inspection.fallback;\n const action =\n error.code.startsWith('asset-') || reason === 'producer-failed'\n ? 'rebuild'\n : reason === 'query-failed' || reason === 'page-exhausted' || reason === 'device-loss'\n ? 'retry'\n : 'cold-cook';\n return { action, sourceKey: inspection.root.sourceKey, reason };\n}\n","/**\n * Consumer-only SSR M0 admission.\n *\n * This module consumes detached producer receipts. It owns no capture,\n * device, graph, or recovery handle and therefore cannot repair a missing\n * producer. A complete receipt set is the only route to an admitted result.\n */\n\nimport {\n type RhiTextureFormatCapabilityReceipt,\n validateR32FloatReceipt,\n} from '@forgeax/engine-rhi';\nimport type { ReflectionFallbackReceipt } from '../inspection-types';\nimport type { SsrOwnerRecoveryAction } from './errors';\nimport type { SsrAdmissionIdentity } from './identity';\n\nexport const SSR_FORMAT_PROFILE = 'r32float-mip-sampled-storage' as const;\n\nexport const SSR_FORMAT_STAGES = Object.freeze([\n 'texture-create',\n 'mip-view',\n 'sampled-storage-bind-group',\n 'pipeline-bind',\n 'finish',\n 'submit',\n 'completion',\n 'readback',\n] as const);\n\nexport type { SsrAdmissionIdentity } from './identity';\n\nexport type SsrFormatStage = (typeof SSR_FORMAT_STAGES)[number];\n\n/**\n * The admission input is the real renderer owner receipt plus the one\n * integration identity supplied by the host. It deliberately does not\n * recreate submitted/source/LKG boolean flags.\n */\nexport type SsrReflectionFallbackReceipt = ReflectionFallbackReceipt & {\n readonly identity: SsrAdmissionIdentity;\n};\n\n/** RHI capability receipt with the same host-supplied integration identity. */\nexport type SsrFormatReceipt = RhiTextureFormatCapabilityReceipt & {\n readonly identity: SsrAdmissionIdentity;\n};\n\nexport interface SsrTemporalReceipt {\n readonly identity: SsrAdmissionIdentity;\n readonly successfulSubmit: true;\n readonly generation: number;\n}\n\nexport interface SsrAdmissionWork {\n readonly attachmentCount: number;\n readonly passCount: number;\n readonly bindingCount: number;\n readonly resourceCount: number;\n readonly historyCount: 0;\n readonly temporalDemand: 0;\n}\n\nexport interface SsrAdmissionBudget {\n readonly probeExecutions: 0 | 1;\n readonly resetCount: 0;\n readonly rebuildCount: 0;\n}\n\nexport interface SsrAdmissionFailure {\n readonly code:\n | 'ssr-not-requested'\n | 'ssr-reflection-fallback-unavailable'\n | 'ssr-format-unavailable'\n | 'ssr-temporal-unavailable'\n | 'ssr-receipt-identity-mismatch'\n | 'ssr-receipt-stale';\n readonly expected: string;\n readonly hint: string;\n readonly detail: Readonly<{\n readonly owner: 'producer' | 'format' | 'temporal' | 'consumer';\n /** Owner-directed action an AI consumer can take without parsing hint text. */\n readonly action: SsrOwnerRecoveryAction;\n readonly generation?: number;\n readonly identityField?: keyof SsrAdmissionIdentity;\n }>;\n}\n\nexport type SsrAdmissionResult =\n | {\n readonly status: 'admitted';\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly generation: number;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure?: undefined;\n }\n | {\n readonly status: 'fallback-only';\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly generation: number;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure: SsrAdmissionFailure;\n };\n\nexport interface SsrAdmissionInput {\n readonly requested: boolean;\n readonly identity: SsrAdmissionIdentity;\n readonly reflectionFallback?: SsrReflectionFallbackReceipt;\n readonly format?: SsrFormatReceipt;\n readonly temporal?: SsrTemporalReceipt;\n readonly previousGeneration?: number;\n}\n\n/** Public renderer projection consumed by the parent SSR feature. */\nexport interface SsrDependenciesInspection {\n readonly status: 'admitted' | 'fallback-only';\n /** Absent until the host binds an exact source/tree/lock/build identity. */\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly requested: boolean;\n readonly reflectionFallback: ReflectionFallbackReceipt | undefined;\n readonly format: SsrFormatReceipt | undefined;\n readonly temporal: SsrTemporalReceipt | undefined;\n readonly admission: SsrAdmissionResult;\n readonly work: SsrAdmissionWork;\n readonly budget: SsrAdmissionBudget;\n readonly failure: SsrAdmissionFailure | undefined;\n}\n\nconst ZERO_WORK: SsrAdmissionWork = Object.freeze({\n attachmentCount: 0,\n passCount: 0,\n bindingCount: 0,\n resourceCount: 0,\n historyCount: 0,\n temporalDemand: 0,\n});\n\nconst ADMITTED_WORK: SsrAdmissionWork = Object.freeze({\n attachmentCount: 1,\n passCount: 1,\n bindingCount: 1,\n resourceCount: 1,\n historyCount: 0,\n temporalDemand: 0,\n});\n\nconst ZERO_BUDGET: SsrAdmissionBudget = Object.freeze({\n probeExecutions: 0,\n resetCount: 0,\n rebuildCount: 0,\n});\n\nconst ADMITTED_BUDGET: SsrAdmissionBudget = Object.freeze({\n probeExecutions: 1,\n resetCount: 0,\n rebuildCount: 0,\n});\n\nfunction identityFieldMismatch(\n expected: SsrAdmissionIdentity,\n actual: SsrAdmissionIdentity,\n): keyof SsrAdmissionIdentity | undefined {\n for (const field of ['sourceHead', 'sourceTree', 'lockSha256', 'buildSha256'] as const) {\n if (expected[field] !== actual[field]) return field;\n }\n return undefined;\n}\n\nfunction blocked(\n identity: SsrAdmissionIdentity | undefined,\n failure: SsrAdmissionFailure,\n generation = 0,\n): SsrAdmissionResult {\n return Object.freeze({\n status: 'fallback-only',\n identity,\n generation,\n work: ZERO_WORK,\n budget: ZERO_BUDGET,\n failure,\n });\n}\n\nfunction failure(\n code: SsrAdmissionFailure['code'],\n owner: SsrAdmissionFailure['detail']['owner'],\n hint: string,\n detail: Omit<SsrAdmissionFailure['detail'], 'owner' | 'action'> = {},\n): SsrAdmissionFailure {\n const action: SsrOwnerRecoveryAction = recoveryActionFor(code);\n return Object.freeze({\n code,\n expected: 'all producer, format, and temporal receipts share one admitted identity',\n hint,\n detail: Object.freeze({ owner, action, ...detail }),\n });\n}\n\nfunction recoveryActionFor(code: SsrAdmissionFailure['code']): SsrOwnerRecoveryAction {\n switch (code) {\n case 'ssr-reflection-fallback-unavailable':\n case 'ssr-receipt-identity-mismatch':\n return 'rebuild';\n case 'ssr-not-requested':\n case 'ssr-format-unavailable':\n case 'ssr-temporal-unavailable':\n case 'ssr-receipt-stale':\n return 'retry';\n }\n}\n\nfunction receiptFailure(\n input: SsrAdmissionInput,\n receipt: { readonly identity: SsrAdmissionIdentity },\n owner: SsrAdmissionFailure['detail']['owner'],\n): SsrAdmissionResult | undefined {\n const field = identityFieldMismatch(input.identity, receipt.identity);\n if (field === undefined) return undefined;\n return blocked(\n input.identity,\n failure('ssr-receipt-identity-mismatch', owner, 'rebuild the owner receipt for this identity', {\n identityField: field,\n }),\n );\n}\n\nfunction validFallback(receipt: SsrReflectionFallbackReceipt | undefined): boolean {\n return (\n receipt !== undefined &&\n receipt.candidateVisible === false &&\n Number.isFinite(receipt.coverage) &&\n receipt.coverage >= 0 &&\n receipt.coverage <= 1 &&\n (receipt.sourceKey === undefined || receipt.sourceKey.length > 0) &&\n (receipt.extent === undefined ||\n (receipt.extent.length === 3 &&\n receipt.extent.every((value) => Number.isFinite(value) && value > 0))) &&\n Number.isInteger(receipt.sourceGeneration) &&\n receipt.sourceGeneration >= 0 &&\n Number.isInteger(receipt.projectionGeneration) &&\n receipt.projectionGeneration >= 0 &&\n Number.isInteger(receipt.deviceGeneration) &&\n receipt.deviceGeneration >= 0 &&\n receipt.brdfSignature === 'standard-pbr-ibl-v1' &&\n ((receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) ||\n (receipt.source === 'skylight' && (receipt.state === 'active' || receipt.state === 'lkg')) ||\n (receipt.source === 'neutral' && receipt.state === 'neutral'))\n );\n}\n\nfunction validFormat(receipt: SsrFormatReceipt | undefined): boolean {\n if (\n receipt?.profile !== SSR_FORMAT_PROFILE ||\n receipt.verdict !== 'admitted' ||\n receipt.evidence !== 'real' ||\n !Number.isInteger(receipt.deviceGeneration) ||\n receipt.deviceGeneration < 0\n ) {\n return false;\n }\n if (\n !SSR_FORMAT_STAGES.every((stage) =>\n receipt.stages.some((entry) => entry.stage === stage && entry.verdict === 'admitted'),\n )\n ) {\n return false;\n }\n return validateR32FloatReceipt(receipt).ok;\n}\n\nfunction validTemporal(receipt: SsrTemporalReceipt | undefined): boolean {\n return (\n receipt?.successfulSubmit === true &&\n Number.isInteger(receipt.generation) &&\n receipt.generation >= 0\n );\n}\n\nexport function admitSsrM0(input: SsrAdmissionInput): SsrAdmissionResult {\n if (!input.requested) {\n return blocked(\n input.identity,\n failure('ssr-not-requested', 'consumer', 'request SSR before evaluating M0 admission'),\n );\n }\n if (input.reflectionFallback === undefined) {\n return blocked(\n input.identity,\n failure('ssr-reflection-fallback-unavailable', 'producer', 'use LKG, Skylight, or neutral'),\n );\n }\n const fallbackIdentityFailure = receiptFailure(input, input.reflectionFallback, 'producer');\n if (fallbackIdentityFailure !== undefined) return fallbackIdentityFailure;\n if (!validFallback(input.reflectionFallback)) {\n return blocked(\n input.identity,\n failure(\n 'ssr-reflection-fallback-unavailable',\n 'producer',\n 'inspect and rebuild the producer receipt',\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (input.format === undefined) {\n return blocked(\n input.identity,\n failure('ssr-format-unavailable', 'format', 'probe the exact format profile for this device'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n const formatIdentityFailure = receiptFailure(input, input.format, 'format');\n if (formatIdentityFailure !== undefined) return formatIdentityFailure;\n if (!validFormat(input.format)) {\n return blocked(\n input.identity,\n failure('ssr-format-unavailable', 'format', 'complete the full r32float profile probe'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (input.temporal === undefined) {\n return blocked(\n input.identity,\n failure(\n 'ssr-temporal-unavailable',\n 'temporal',\n 'submit the matching temporal producer receipt',\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n const temporalIdentityFailure = receiptFailure(input, input.temporal, 'temporal');\n if (temporalIdentityFailure !== undefined) return temporalIdentityFailure;\n if (!validTemporal(input.temporal)) {\n return blocked(\n input.identity,\n failure('ssr-temporal-unavailable', 'temporal', 'inspect and rebuild the temporal receipt'),\n input.reflectionFallback.projectionGeneration,\n );\n }\n if (\n input.previousGeneration !== undefined &&\n input.previousGeneration !== input.reflectionFallback.projectionGeneration\n ) {\n return blocked(\n input.identity,\n failure(\n 'ssr-receipt-stale',\n 'consumer',\n 'discard stale completion and reinspect the owners',\n {\n generation: input.reflectionFallback.projectionGeneration,\n },\n ),\n input.reflectionFallback.projectionGeneration,\n );\n }\n return Object.freeze({\n status: 'admitted',\n identity: input.identity,\n generation: input.reflectionFallback.projectionGeneration,\n work: ADMITTED_WORK,\n budget: ADMITTED_BUDGET,\n });\n}\n\n/**\n * Joins the live owner projections at the renderer boundary. The only casts\n * here add the host identity to receipts that otherwise remain canonical RHI\n * or ReflectionProbe PODs; no producer fact is copied or renamed.\n */\nexport function projectSsrDependencies(input: {\n readonly requested: boolean;\n readonly identity: SsrAdmissionIdentity | undefined;\n readonly reflectionFallback: ReflectionFallbackReceipt | undefined;\n readonly format: RhiTextureFormatCapabilityReceipt | undefined;\n readonly temporal: { readonly successfulSubmit: true; readonly generation: number } | undefined;\n readonly previousGeneration?: number;\n}): SsrDependenciesInspection {\n const identity = input.identity;\n const reflectionFallback =\n identity === undefined || input.reflectionFallback?.identity === undefined\n ? undefined\n : (input.reflectionFallback as SsrReflectionFallbackReceipt);\n const format =\n identity === undefined || input.format === undefined\n ? undefined\n : ({ ...input.format, identity } satisfies SsrFormatReceipt);\n const temporal =\n identity === undefined || input.temporal === undefined\n ? undefined\n : ({ identity, ...input.temporal } satisfies SsrTemporalReceipt);\n const admission =\n identity === undefined\n ? blocked(\n undefined,\n failure(\n input.requested ? 'ssr-receipt-identity-mismatch' : 'ssr-not-requested',\n 'consumer',\n input.requested\n ? 'bind the exact source, tree, lock, and build identity before admission'\n : 'request SSR before evaluating M0 admission',\n input.requested ? { identityField: 'sourceHead' } : {},\n ),\n )\n : admitSsrM0({\n requested: input.requested,\n identity,\n ...(reflectionFallback === undefined ? {} : { reflectionFallback }),\n ...(format === undefined ? {} : { format }),\n ...(temporal === undefined ? {} : { temporal }),\n ...(input.previousGeneration === undefined\n ? {}\n : { previousGeneration: input.previousGeneration }),\n });\n return Object.freeze({\n status: admission.status,\n identity,\n requested: input.requested,\n reflectionFallback: input.reflectionFallback,\n format,\n temporal,\n admission,\n work: admission.work,\n budget: admission.budget,\n failure: admission.failure,\n });\n}\n\nexport function zeroSsrAdmissionWork(): SsrAdmissionWork {\n return ZERO_WORK;\n}\n\n/**\n * Projects the admission decision into the existing temporal reset seam.\n * Admission never creates temporal history; only a changed committed\n * producer generation can request a reset through the coordinator.\n */\nexport function resolveSsrAdmissionGeneration(\n previousGeneration: number | undefined,\n nextGeneration: number | undefined,\n): { readonly changed: boolean; readonly generation: number | undefined } {\n return {\n changed:\n previousGeneration !== undefined &&\n nextGeneration !== undefined &&\n previousGeneration !== nextGeneration,\n generation: nextGeneration,\n };\n}\n"]}
|