@opsydyn/effect-three-foldkit 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +99 -2
  4. package/dist/assets.d.ts +53 -0
  5. package/dist/assets.d.ts.map +1 -0
  6. package/dist/dom/animationFrames.d.ts +12 -0
  7. package/dist/dom/animationFrames.d.ts.map +1 -0
  8. package/dist/dom/canvas.d.ts +26 -0
  9. package/dist/dom/canvas.d.ts.map +1 -0
  10. package/dist/dom/latch.d.ts +15 -0
  11. package/dist/dom/latch.d.ts.map +1 -0
  12. package/dist/dom/models.d.ts +10 -0
  13. package/dist/dom/models.d.ts.map +1 -0
  14. package/dist/dom/overlays.d.ts +24 -0
  15. package/dist/dom/overlays.d.ts.map +1 -0
  16. package/dist/dom/pointer.d.ts +49 -0
  17. package/dist/dom/pointer.d.ts.map +1 -0
  18. package/dist/dom/postprocessing.d.ts +22 -0
  19. package/dist/dom/postprocessing.d.ts.map +1 -0
  20. package/dist/dom/property.d.ts +15 -0
  21. package/dist/dom/property.d.ts.map +1 -0
  22. package/dist/dom/reconciled.d.ts +10 -0
  23. package/dist/dom/reconciled.d.ts.map +1 -0
  24. package/dist/dom/renderSettings.d.ts +58 -0
  25. package/dist/dom/renderSettings.d.ts.map +1 -0
  26. package/dist/dom/typedScenes.d.ts +14 -0
  27. package/dist/dom/typedScenes.d.ts.map +1 -0
  28. package/dist/dom/updates.d.ts +8 -0
  29. package/dist/dom/updates.d.ts.map +1 -0
  30. package/dist/dom/viewport.d.ts +40 -0
  31. package/dist/dom/viewport.d.ts.map +1 -0
  32. package/dist/dom/webgl.d.ts +12 -0
  33. package/dist/dom/webgl.d.ts.map +1 -0
  34. package/dist/dom/webgpu.d.ts +23 -0
  35. package/dist/dom/webgpu.d.ts.map +1 -0
  36. package/dist/dom/webgpuPostprocessing.d.ts +4 -0
  37. package/dist/dom/webgpuPostprocessing.d.ts.map +1 -0
  38. package/dist/dom/xr.d.ts +53 -0
  39. package/dist/dom/xr.d.ts.map +1 -0
  40. package/dist/dom/xrGlide.d.ts +49 -0
  41. package/dist/dom/xrGlide.d.ts.map +1 -0
  42. package/dist/dom/xrHub.d.ts +45 -0
  43. package/dist/dom/xrHub.d.ts.map +1 -0
  44. package/dist/dom/xrInputs.d.ts +40 -0
  45. package/dist/dom/xrInputs.d.ts.map +1 -0
  46. package/dist/dom/xrSpaces.d.ts +33 -0
  47. package/dist/dom/xrSpaces.d.ts.map +1 -0
  48. package/dist/dom/xrTarget.d.ts +36 -0
  49. package/dist/dom/xrTarget.d.ts.map +1 -0
  50. package/dist/element.d.ts +771 -0
  51. package/dist/element.d.ts.map +1 -0
  52. package/dist/environment.d.ts +64 -0
  53. package/dist/environment.d.ts.map +1 -0
  54. package/dist/index.d.ts +32 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +2037 -0
  57. package/dist/index.js.map +38 -0
  58. package/dist/mount.d.ts +14 -0
  59. package/dist/mount.d.ts.map +1 -0
  60. package/dist/overlayView.d.ts +23 -0
  61. package/dist/overlayView.d.ts.map +1 -0
  62. package/dist/view.d.ts +179 -0
  63. package/dist/view.d.ts.map +1 -0
  64. package/dist/xr.d.ts +34 -0
  65. package/dist/xr.d.ts.map +1 -0
  66. package/package.json +72 -4
  67. package/src/assets.ts +151 -0
  68. package/src/dom/animationFrames.ts +32 -0
  69. package/src/dom/canvas.ts +54 -0
  70. package/src/dom/latch.ts +36 -0
  71. package/src/dom/models.ts +37 -0
  72. package/src/dom/overlays.ts +63 -0
  73. package/src/dom/pointer.ts +163 -0
  74. package/src/dom/postprocessing.ts +116 -0
  75. package/src/dom/property.ts +43 -0
  76. package/src/dom/reconciled.ts +51 -0
  77. package/src/dom/renderSettings.ts +117 -0
  78. package/src/dom/typedScenes.ts +21 -0
  79. package/src/dom/updates.ts +14 -0
  80. package/src/dom/viewport.ts +97 -0
  81. package/src/dom/webgl.ts +216 -0
  82. package/src/dom/webgpu.ts +204 -0
  83. package/src/dom/webgpuPostprocessing.ts +95 -0
  84. package/src/dom/xr.ts +211 -0
  85. package/src/dom/xrGlide.ts +114 -0
  86. package/src/dom/xrHub.ts +118 -0
  87. package/src/dom/xrInputs.ts +309 -0
  88. package/src/dom/xrSpaces.ts +287 -0
  89. package/src/dom/xrTarget.ts +71 -0
  90. package/src/element.ts +114 -0
  91. package/src/environment.ts +78 -0
  92. package/src/index.ts +71 -0
  93. package/src/mount.ts +305 -0
  94. package/src/overlayView.ts +71 -0
  95. package/src/view.ts +254 -0
  96. package/src/xr.ts +36 -0
@@ -0,0 +1,38 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/assets.ts", "../src/dom/models.ts", "../src/dom/animationFrames.ts", "../src/dom/pointer.ts", "../src/dom/viewport.ts", "../src/dom/webgl.ts", "../src/dom/postprocessing.ts", "../src/dom/renderSettings.ts", "../src/dom/webgpu.ts", "../src/dom/webgpuPostprocessing.ts", "../src/element.ts", "../src/xr.ts", "../src/dom/reconciled.ts", "../src/environment.ts", "../src/dom/xr.ts", "../src/dom/xrGlide.ts", "../src/dom/xrInputs.ts", "../src/dom/xrSpaces.ts", "../src/dom/xrHub.ts", "../src/mount.ts", "../src/dom/canvas.ts", "../src/dom/latch.ts", "../src/dom/overlays.ts", "../src/dom/property.ts", "../src/dom/typedScenes.ts", "../src/dom/updates.ts", "../src/dom/xrTarget.ts", "../src/view.ts", "../src/overlayView.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Loading textures, glTF models and typeface fonts by URL, as Effects an application runs\n * from a Foldkit Command and settles into `AsyncData`. Each asset is lent to the shared\n * resource store under an id: materials use a texture with `map: id`, a `borrowed({ id })`\n * node shows a model, and `text({ font: id })` geometry draws with a font. The environment owns what it loads: loading an id again replaces and disposes\n * the earlier asset, and `unload` or the environment's `dispose` frees it.\n *\n * @module\n */\nimport type { ResourceStore } from '@opsydyn/effect-three';\nimport { Data, Effect } from 'effect';\nimport {\n EquirectangularReflectionMapping,\n type Object3D,\n SRGBColorSpace,\n type Texture,\n TextureLoader,\n} from 'three';\nimport { type Font, FontLoader } from 'three/addons/loaders/FontLoader.js';\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { HDRLoader } from 'three/addons/loaders/HDRLoader.js';\n\nimport { disposeModel, namesIn } from './dom/models.ts';\n\n/** An asset could not be fetched or decoded. */\nexport class AssetLoadError extends Data.TaggedError('AssetLoadError')<{\n readonly url: string;\n readonly cause: unknown;\n}> {}\n\n/** What a loaded model offers: named parts to match hits against, and animation clips. */\nexport type ModelInfo = {\n readonly id: string;\n /** Names of the objects inside the model, as hits report them in `part`. */\n readonly parts: ReadonlyArray<string>;\n /** Names of the model's animation clips. */\n readonly clips: ReadonlyArray<string>;\n};\n\n/** Creates the asset loader for a store. One per environment. */\nexport const makeAssets = (store: ResourceStore) => {\n const releases = new Map<string, () => void>();\n\n /** Takes ownership of an asset under `id`, first releasing whatever was there. */\n const own = (id: string, release: () => void): void => {\n releases.get(id)?.();\n releases.set(id, release);\n };\n\n const lendTexture = (id: string) => (texture: Texture) => {\n texture.colorSpace = SRGBColorSpace;\n const withdraw = store.lendTexture(id, texture);\n own(id, () => {\n withdraw();\n texture.dispose();\n });\n return id;\n };\n\n const lendModel =\n (id: string) =>\n (gltf: { readonly scene: Object3D; readonly animations: Object3D['animations'] }) => {\n // Keep the clips with the object, so a borrowed node can play them by name.\n gltf.scene.animations = gltf.animations;\n const withdraw = store.lend(id, gltf.scene);\n own(id, () => {\n withdraw();\n disposeModel(gltf.scene);\n });\n const info: ModelInfo = {\n id,\n parts: namesIn(gltf.scene),\n clips: gltf.animations.map((clip) => clip.name),\n };\n return info;\n };\n\n /** Lends an HDR panorama for `environment({ map })`: linear, mapped for reflection. */\n const lendEnvironment = (id: string) => (texture: Texture) => {\n texture.mapping = EquirectangularReflectionMapping;\n const withdraw = store.lendTexture(id, texture);\n own(id, () => {\n withdraw();\n texture.dispose();\n });\n return id;\n };\n\n const lendFont = (id: string) => (font: Font) => {\n // Fonts hold no GPU resources: withdrawing the loan frees them.\n own(id, store.lendFont(id, font));\n return id;\n };\n\n const releaseAll = (): void => {\n for (const release of releases.values()) release();\n releases.clear();\n };\n\n return {\n /** Loads a colour texture (sRGB) and lends it under `id`. Succeeds with the id. */\n loadTexture: (id: string, url: string) => {\n const load = Effect.tryPromise({\n try: () => new TextureLoader().loadAsync(url),\n catch: (cause) => new AssetLoadError({ url, cause }),\n });\n return Effect.map(load, lendTexture(id));\n },\n /** Loads a glTF or GLB model and lends its scene under `id`, with its clips. */\n loadModel: (id: string, url: string) => {\n const load = Effect.tryPromise({\n try: () => new GLTFLoader().loadAsync(url),\n catch: (cause) => new AssetLoadError({ url, cause }),\n });\n return Effect.map(load, lendModel(id));\n },\n /**\n * Loads an equirectangular HDR panorama (`.hdr`, three.js's `HDRLoader`) and lends it\n * under `id` for `environment({ map: id })`. Succeeds with the id. Image panoramas\n * load with `loadTexture`; the scene maps them for reflection.\n */\n loadEnvironment: (id: string, url: string) => {\n const load = Effect.tryPromise({\n try: () => new HDRLoader().loadAsync(url),\n catch: (cause) => new AssetLoadError({ url, cause }),\n });\n return Effect.map(load, lendEnvironment(id));\n },\n /**\n * Loads a typeface JSON font (three.js's `FontLoader` format, as Drei's `Text3D` takes)\n * and lends it under `id`. Succeeds with the id.\n */\n loadFont: (id: string, url: string) => {\n const load = Effect.tryPromise({\n try: () => new FontLoader().loadAsync(url),\n catch: (cause) => new AssetLoadError({ url, cause }),\n });\n return Effect.map(load, lendFont(id));\n },\n /** Withdraws and disposes the asset loaded under `id`, if any. */\n unload: (id: string) =>\n Effect.sync(() => {\n releases.get(id)?.();\n releases.delete(id);\n }),\n /** Withdraws and disposes every loaded asset. */\n dispose: releaseAll,\n };\n};\n\nexport type Assets = ReturnType<typeof makeAssets>;\n",
6
+ "/**\n * Plain three.js helpers for loaded models.\n *\n * @module\n */\nimport { type Material, Mesh, type Object3D, Texture } from 'three';\n\n/** Disposes every texture a material holds (maps of any kind). */\nconst disposeMaterial = (material: Material): void => {\n for (const value of Object.values(material)) {\n if (value instanceof Texture) value.dispose();\n }\n material.dispose();\n};\n\n/** Disposes a mesh's geometry and materials; other objects hold nothing to free. */\nfunction disposeMesh(object: Object3D): void {\n if (!(object instanceof Mesh)) return;\n object.geometry.dispose();\n const materials: ReadonlyArray<Material> = Array.isArray(object.material)\n ? object.material\n : [object.material];\n for (const material of materials) disposeMaterial(material);\n}\n\n/** Disposes a loaded model's GPU resources: it was ours, not the application's. */\nexport const disposeModel = (root: Object3D): void => {\n root.traverse(disposeMesh);\n};\n\nexport const namesIn = (root: Object3D): ReadonlyArray<string> => {\n const names: Array<string> = [];\n root.traverse((object) => {\n if (object !== root && object.name !== '') names.push(object.name);\n });\n return names;\n};\n",
7
+ "/**\n * A `requestAnimationFrame` scheduler shared by every scene on the page: one browser\n * callback per frame, running only while at least one scene is subscribed.\n *\n * @module\n */\nimport type { FrameScheduler } from '@opsydyn/effect-three';\n\n/** The part of `Window` the scheduler needs. */\nexport type AnimationFrameHost = Pick<Window, 'requestAnimationFrame' | 'cancelAnimationFrame'>;\n\n/** Creates a shared animation-frame scheduler for `host` (normally `window`). */\nexport const animationFrameScheduler = (host: AnimationFrameHost): FrameScheduler => {\n const callbacks = new Set<() => void>();\n let handle: number | undefined;\n const tick = (): void => {\n handle = host.requestAnimationFrame(tick);\n for (const onFrame of Array.from(callbacks)) onFrame();\n };\n return {\n subscribe: (onFrame) => {\n callbacks.add(onFrame);\n handle ??= host.requestAnimationFrame(tick);\n return () => {\n callbacks.delete(onFrame);\n if (callbacks.size > 0 || handle === undefined) return;\n host.cancelAnimationFrame(handle);\n handle = undefined;\n };\n },\n };\n};\n",
8
+ "/**\n * DOM pointer events to the kernel's normalised device coordinates.\n *\n * @module\n */\nimport type { Gestures, Modifiers, PointerInput, SceneEvent } from '@opsydyn/effect-three';\n\n/** The part of `DOMRect` the conversion needs. */\nexport type Rect = {\n readonly left: number;\n readonly top: number;\n readonly width: number;\n readonly height: number;\n};\n\n/** Client coordinates to NDC: x and y in [-1, 1], y up. A zero-sized rect maps to the centre. */\nexport const toNdc = (\n rect: Rect,\n clientX: number,\n clientY: number,\n): { readonly x: number; readonly y: number } => {\n if (rect.width === 0 || rect.height === 0) return { x: 0, y: 0 };\n return {\n x: ((clientX - rect.left) / rect.width) * 2 - 1,\n y: -(((clientY - rect.top) / rect.height) * 2 - 1),\n };\n};\n\nconst modifiersOf = (event: MouseEvent): Modifiers => ({\n shift: event.shiftKey,\n control: event.ctrlKey,\n meta: event.metaKey,\n alt: event.altKey,\n});\n\n/** The pointer's id, or 0 for mouse events that are not pointer events. */\nconst pointerIdOf = (event: MouseEvent): number =>\n event instanceof PointerEvent ? event.pointerId : 0;\n\n/**\n * Wheel deltas in CSS pixels: line and page modes scaled as three.js's `OrbitControls`\n * scales them (`_customWheelEvent`: 16 and 100).\n */\nconst wheelScale = [1, 16, 100] as const;\n\n/**\n * Converts a DOM pointer, mouse or wheel event into kernel input, or `undefined` for\n * other event types. Pointer cancel is treated as leaving the surface.\n */\nexport const toPointerInput = (event: MouseEvent, rect: Rect): PointerInput | undefined => {\n if (event.type === 'pointerleave' || event.type === 'pointercancel') {\n return { _tag: 'PointerLeave' };\n }\n const { x, y } = toNdc(rect, event.clientX, event.clientY);\n const pointer = pointerIdOf(event);\n switch (event.type) {\n case 'pointermove':\n return { _tag: 'PointerMove', x, y, pointer };\n case 'pointerdown':\n return {\n _tag: 'PointerDown',\n x,\n y,\n button: event.button,\n pointer,\n modifiers: modifiersOf(event),\n };\n case 'pointerup':\n return { _tag: 'PointerUp', x, y, button: event.button, pointer };\n case 'dblclick':\n return { _tag: 'DoubleClick', x, y, button: event.button };\n case 'contextmenu':\n return { _tag: 'ContextMenu', x, y };\n case 'wheel':\n return event instanceof WheelEvent\n ? {\n _tag: 'Wheel',\n x,\n y,\n deltaX: event.deltaX * (wheelScale[event.deltaMode] ?? 1),\n deltaY: event.deltaY * (wheelScale[event.deltaMode] ?? 1),\n modifiers: modifiersOf(event),\n }\n : undefined;\n default:\n return undefined;\n }\n};\n\n/** True when a press landed on an interactive mesh, which then captures the pointer. */\nexport const capturesPointer = (events: ReadonlyArray<SceneEvent>): boolean =>\n events.some((event) => event._tag === 'PointerDown');\n\n/** True when the scene handled a context-menu input, so the browser menu should not open. */\nexport const claimsContextMenu = (events: ReadonlyArray<SceneEvent>): boolean =>\n events.some((event) => event._tag === 'ContextMenu');\n\nconst eventTypes = [\n 'pointermove',\n 'pointerdown',\n 'pointerup',\n 'pointerleave',\n 'pointercancel',\n 'dblclick',\n 'contextmenu',\n 'wheel',\n] as const;\n\n/**\n * Forwards pointer, mouse and wheel input from `element`. `onInput` returns the scene\n * events it produced. By default the page keeps its gestures: wheel and touch scroll it,\n * and the browser's menu opens except over an interactive mesh that handles it. A press\n * on a mesh captures the pointer.\n *\n * While `claimsGestures()` is true the scene owns them, as three.js's `OrbitControls` does\n * when connected: every press captures the pointer, the wheel does not scroll the page,\n * and the context menu stays shut (the right button pans). Returns a function that\n * removes every listener.\n */\nexport const listenForPointer = (\n element: HTMLElement,\n onInput: (input: PointerInput) => ReadonlyArray<SceneEvent>,\n claimsGestures: () => boolean = () => false,\n): (() => void) => {\n const listener = (event: Event): void => {\n if (!(event instanceof MouseEvent)) return;\n const input = toPointerInput(event, element.getBoundingClientRect());\n if (input === undefined) return;\n const events = onInput(input);\n const claimed = claimsGestures();\n if (claimed && (event.type === 'wheel' || event.type === 'contextmenu')) {\n event.preventDefault();\n }\n if (event.type === 'contextmenu' && claimsContextMenu(events)) event.preventDefault();\n // Keep the drag's moves and release coming here even off the canvas, as React Three\n // Fiber's setPointerCapture does. The browser releases capture on pointer up.\n if (\n event instanceof PointerEvent &&\n event.type === 'pointerdown' &&\n (claimed || capturesPointer(events))\n ) {\n element.setPointerCapture(event.pointerId);\n }\n };\n // Not passive, so a claimed wheel can stop the page scrolling; unclaimed wheels are\n // left alone.\n for (const type of eventTypes) element.addEventListener(type, listener, { passive: false });\n return () => {\n for (const type of eventTypes) element.removeEventListener(type, listener);\n };\n};\n\n/** Whatever reports the scene's claim on gestures: its graph. */\ntype GestureOwner = { readonly gestures: () => Gestures };\n\n/** Whether the scene currently claims the pointer's gestures. */\nexport const claimsGestures = (owner: GestureOwner) => (): boolean => owner.gestures() === 'scene';\n\n/** Lets the browser pan and zoom on touch, or not while the scene claims gestures. */\nexport const touchActionSync = (element: HTMLElement, owner: GestureOwner) => (): void => {\n const touchAction = claimsGestures(owner)() ? 'none' : '';\n if (element.style.touchAction !== touchAction) element.style.touchAction = touchAction;\n};\n",
9
+ "/**\n * Element size, visibility and motion preference.\n *\n * @module\n */\nimport type { Viewport } from '@opsydyn/effect-three';\n\n/**\n * The drawing buffer's pixel ratio: a fixed number, or `[min, max]` to follow the device\n * within bounds. React Three Fiber's `dpr`, with its `[1, 2]` default (`calculateDpr` in\n * `core/utils.tsx` at `d74622e`): ratios above 2 cost GPU time for little visible gain.\n */\nexport type PixelRatio = number | readonly [min: number, max: number];\n\nexport const defaultPixelRatio: PixelRatio = [1, 2];\n\n/** Resolves a pixel ratio setting against the device's ratio. */\nexport const resolvePixelRatio = (devicePixelRatio: number, setting: PixelRatio): number =>\n typeof setting === 'number'\n ? setting\n : Math.min(Math.max(setting[0], devicePixelRatio), setting[1]);\n\n/** The element's current viewport, with the pixel ratio resolved. */\nexport const measureViewport = (\n element: Element,\n devicePixelRatio: number,\n pixelRatio: PixelRatio = defaultPixelRatio,\n): Viewport => {\n const rect = element.getBoundingClientRect();\n return {\n width: Math.max(1, rect.width),\n height: Math.max(1, rect.height),\n pixelRatio: resolvePixelRatio(devicePixelRatio, pixelRatio),\n };\n};\n\n/** Calls `onResize` whenever the element's size changes. Returns a disconnect function. */\nexport const observeSize = (element: Element, onResize: () => void): (() => void) => {\n const observer = new ResizeObserver(onResize);\n observer.observe(element);\n return () => observer.disconnect();\n};\n\n/** Calls `onVisible` with whether any part of the element is on screen. */\nexport const observeVisibility = (\n element: Element,\n onVisible: (visible: boolean) => void,\n): (() => void) => {\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) onVisible(entry.isIntersecting);\n });\n observer.observe(element);\n return () => observer.disconnect();\n};\n\n/** Calls `onChange` with the current reduced-motion preference, then on every change. */\nexport const observeReducedMotion = (\n view: Pick<Window, 'matchMedia'>,\n onChange: (reduced: boolean) => void,\n): (() => void) => {\n const query = view.matchMedia('(prefers-reduced-motion: reduce)');\n const listener = (event: MediaQueryListEvent): void => onChange(event.matches);\n onChange(query.matches);\n query.addEventListener('change', listener);\n return () => query.removeEventListener('change', listener);\n};\n\n/** The media query calls the pixel-ratio watch needs; `window` provides them. */\ntype ChangeTarget = {\n addEventListener(type: 'change', listener: () => void): void;\n removeEventListener(type: 'change', listener: () => void): void;\n};\n\nexport type PixelRatioHost = {\n readonly devicePixelRatio: number;\n readonly matchMedia: (query: string) => ChangeTarget;\n};\n\n/**\n * Calls `onChange` whenever the device pixel ratio changes (moving to another display, or\n * zooming), which resizes nothing. As React Three Fiber's `watchDpr`: a media query for\n * the current resolution, re-armed for the new ratio after each change.\n */\nexport const observePixelRatio = (view: PixelRatioHost, onChange: () => void): (() => void) => {\n let query: ChangeTarget | undefined;\n const listener = (): void => {\n query?.removeEventListener('change', listener);\n arm();\n onChange();\n };\n const arm = (): void => {\n query = view.matchMedia(`(resolution: ${view.devicePixelRatio}dppx)`);\n query.addEventListener('change', listener);\n };\n arm();\n return () => query?.removeEventListener('change', listener);\n};\n",
10
+ "/**\n * The WebGL2 renderer behind the core's backend-neutral renderer contract.\n *\n * @module\n */\nimport type { RendererFactory, RenderSettings, RenderTarget } from '@opsydyn/effect-three';\nimport { webglKit } from '@opsydyn/effect-three/webgl';\nimport {\n type Camera,\n HalfFloatType,\n LinearFilter,\n type Object3D,\n PMREMGenerator,\n type Scene,\n Vector2,\n WebGLRenderer,\n type WebGLRendererParameters,\n WebGLRenderTarget,\n} from 'three';\nimport { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';\n\nimport { createPostProcessing } from './postprocessing.ts';\nimport {\n colorSpaces,\n forgetPresentable,\n recompileMaterials,\n registerPresentable,\n shadowTypes,\n toneMappings,\n} from './renderSettings.ts';\n\n/** Options passed through to three's `WebGLRenderer`. The canvas is always the scene's own. */\nexport type WebGLOptions = Omit<WebGLRendererParameters, 'canvas'>;\n\n/**\n * Applies scene render settings; a change of shadow mode re-renders the shadow maps.\n * Returns whether shadows were switched on or off, which materials must be recompiled for.\n */\nconst configure = (renderer: WebGLRenderer, settings: RenderSettings): boolean => {\n const shadowMap = renderer.shadowMap;\n const enabled = settings.shadows !== 'off';\n const switched = shadowMap.enabled !== enabled;\n const type = enabled ? shadowTypes[settings.shadows] : shadowMap.type;\n if (switched || shadowMap.type !== type) shadowMap.needsUpdate = true;\n shadowMap.enabled = enabled;\n shadowMap.type = type;\n renderer.toneMapping = toneMappings[settings.toneMapping];\n renderer.toneMappingExposure = settings.exposure;\n renderer.outputColorSpace = colorSpaces[settings.colorSpace];\n return switched;\n};\n\nconst drawingSize = new Vector2();\n\n/**\n * A render texture's target, as Drei's `useFBO` makes one for `RenderTexture` (drei\n * `bf6f4ad`, `src/core/Fbo.tsx`): half-float colour, linear filtering, multisampled, with\n * a depth buffer.\n */\nconst createTarget = (\n targets: WeakMap<RenderTarget, WebGLRenderTarget>,\n width: number,\n height: number,\n): RenderTarget => {\n const target = new WebGLRenderTarget(width, height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n type: HalfFloatType,\n samples: 8,\n });\n const handle = { texture: target.texture, dispose: () => target.dispose() };\n targets.set(handle, target);\n return handle;\n};\n\n/**\n * three.js's `RoomEnvironment`, prefiltered for image-based lighting, as three's examples\n * set it up (`PMREMGenerator.fromScene(new RoomEnvironment(), 0.04)`).\n */\nconst createRoom = (renderer: WebGLRenderer): RenderTarget => {\n const generator = new PMREMGenerator(renderer);\n const room = new RoomEnvironment();\n const target = generator.fromScene(room, 0.04);\n room.dispose();\n generator.dispose();\n return { texture: target.texture, dispose: () => target.dispose() };\n};\n\n/**\n * Draws a frame of an immersive session. In AR the room shows through: three clears to\n * transparent there, but a background (an environment shown as one) would cover it, so it\n * is left out of the frame.\n */\nconst drawPresenting = (renderer: WebGLRenderer, scene: Scene, camera: Camera): void => {\n const passthrough = renderer.xr.getEnvironmentBlendMode() !== 'opaque';\n if (!passthrough || scene.background === null) {\n renderer.render(scene, camera);\n return;\n }\n const background = scene.background;\n scene.background = null;\n renderer.render(scene, camera);\n scene.background = background;\n};\n\n/** A factory for a WebGL2 renderer drawing into `canvas`. `create` throws if WebGL2 is unavailable. */\nexport const webglRendererFactory = (\n canvas: HTMLCanvasElement,\n options: WebGLOptions = {},\n): RendererFactory => ({\n // The GLSL parts of a scene (sky, shader grid, contact shadows) go with this renderer.\n kit: webglKit,\n create: () => {\n const renderer = new WebGLRenderer({ antialias: true, ...options, canvas });\n registerPresentable(canvas, renderer, {\n xr: renderer.xr,\n setXrLoop: (callback) => renderer.xr.setAnimationLoop(callback),\n });\n const post = createPostProcessing(renderer);\n const targets = new WeakMap<RenderTarget, WebGLRenderTarget>();\n // The pixel ratio is the viewport's, scaled by the scene's resolution setting.\n let pixelRatio = 1;\n let resolution = 1;\n let scissored = false;\n // Counts shadow switches; each scene drawn (main or render texture) recompiles its\n // materials once after a switch.\n let shadowSwitches = 0;\n const compiledAt = new WeakMap<Object3D, number>();\n const applyPixelRatio = (): void => {\n if (renderer.getPixelRatio() !== pixelRatio * resolution) {\n renderer.setPixelRatio(pixelRatio * resolution);\n }\n const { width, height } = renderer.getSize(drawingSize);\n post.setSize(width, height, pixelRatio * resolution);\n };\n return {\n render: (scene, camera, area, target) => {\n if (shadowSwitches > 0 && compiledAt.get(scene) !== shadowSwitches) {\n recompileMaterials(scene);\n compiledAt.set(scene, shadowSwitches);\n }\n const webglTarget = target === undefined ? undefined : targets.get(target);\n if (webglTarget !== undefined) {\n // As Drei's RenderTexture draws (src/core/RenderTexture.tsx): into the target, then\n // back to whatever was bound. A target keeps its own viewport and scissor.\n // Targets start transparent, whatever the canvas clears to: what the scene does\n // not cover stays see-through (a render texture without a background, contact\n // shadows away from objects).\n // Offscreen passes keep their own camera, even while presenting in XR (three\n // would otherwise draw them from the headset).\n const previous = renderer.getRenderTarget();\n const clearAlpha = renderer.getClearAlpha();\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n renderer.setClearAlpha(0);\n renderer.setRenderTarget(webglTarget);\n renderer.render(scene, camera);\n renderer.setRenderTarget(previous);\n renderer.setClearAlpha(clearAlpha);\n renderer.xr.enabled = xrEnabled;\n return;\n }\n // Presenting in XR, three draws the headset's views itself: no areas, no effects.\n if (renderer.xr.isPresenting) {\n drawPresenting(renderer, scene, camera);\n return;\n }\n const { width, height } = renderer.getSize(drawingSize);\n if (area === undefined) {\n if (scissored) {\n renderer.setScissorTest(false);\n renderer.setViewport(0, 0, width, height);\n scissored = false;\n }\n if (!post.render(scene, camera)) renderer.render(scene, camera);\n return;\n }\n // three's viewport and scissor origin is the bottom left; areas are from the top.\n const bottom = height - area.y - area.height;\n renderer.setViewport(area.x, bottom, area.width, area.height);\n renderer.setScissor(area.x, bottom, area.width, area.height);\n renderer.setScissorTest(true);\n scissored = true;\n // Effects apply to the single full view only; views draw straight to the screen.\n renderer.render(scene, camera);\n },\n createTarget: (width, height) => createTarget(targets, width, height),\n createEnvironment: () => createRoom(renderer),\n configure: (settings) => {\n if (configure(renderer, settings)) shadowSwitches++;\n resolution = settings.resolution;\n post.configure(settings.effects);\n applyPixelRatio();\n },\n setViewport: (viewport) => {\n pixelRatio = viewport.pixelRatio;\n applyPixelRatio();\n renderer.setSize(viewport.width, viewport.height, false);\n post.setSize(viewport.width, viewport.height, pixelRatio * resolution);\n },\n memory: () => ({\n geometries: renderer.info.memory.geometries,\n textures: renderer.info.memory.textures,\n }),\n // dispose() frees three's GPU objects but not the WebGL context. Browsers cap live\n // contexts (about 16 in Chromium), so release it now rather than at garbage collection.\n dispose: () => {\n forgetPresentable(canvas);\n void renderer.xr.getSession()?.end();\n post.dispose();\n renderer.dispose();\n renderer.forceContextLoss();\n },\n };\n },\n});\n",
11
+ "/**\n * Post-processing for the WebGL renderer: three.js's `EffectComposer`, built from the\n * scene's `render.effects` and rebuilt only when they change. With no effects the scene\n * renders straight to the screen and no composer exists.\n *\n * The composer renders into a multisampled target, so antialiasing survives, and ends\n * with three's `OutputPass`, which applies tone mapping and the output colour space.\n *\n * @module\n */\nimport { effectsEqual, type PostEffect } from '@opsydyn/effect-three';\nimport {\n type Camera,\n HalfFloatType,\n PerspectiveCamera,\n type Scene,\n Scene as EmptyScene,\n Vector2,\n type WebGLRenderer,\n WebGLRenderTarget,\n} from 'three';\nimport { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';\nimport { FilmPass } from 'three/addons/postprocessing/FilmPass.js';\nimport { OutputPass } from 'three/addons/postprocessing/OutputPass.js';\nimport type { Pass } from 'three/addons/postprocessing/Pass.js';\nimport { RenderPass } from 'three/addons/postprocessing/RenderPass.js';\nimport { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';\nimport { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';\nimport { VignetteShader } from 'three/addons/shaders/VignetteShader.js';\n\ntype Size = { width: number; height: number; pixelRatio: number };\n\nconst passFor = (effect: PostEffect, size: Size): Pass => {\n switch (effect._tag) {\n case 'Bloom':\n return new UnrealBloomPass(\n new Vector2(size.width, size.height),\n effect.strength,\n effect.radius,\n effect.threshold,\n );\n case 'Vignette': {\n const pass = new ShaderPass(VignetteShader);\n pass.uniforms['offset'] = { value: effect.offset };\n pass.uniforms['darkness'] = { value: effect.darkness };\n return pass;\n }\n case 'Film':\n return new FilmPass(effect.intensity, effect.grayscale);\n }\n};\n\nexport type PostProcessing = {\n /** Rebuilds the passes when `effects` differ from the current ones. */\n readonly configure: (effects: ReadonlyArray<PostEffect>) => void;\n readonly setSize: (width: number, height: number, pixelRatio: number) => void;\n /** Renders through the effects; returns false when there are none to apply. */\n readonly render: (scene: Scene, camera: Camera) => boolean;\n readonly dispose: () => void;\n};\n\nexport const createPostProcessing = (renderer: WebGLRenderer): PostProcessing => {\n let effects: ReadonlyArray<PostEffect> = [];\n let composer: EffectComposer | undefined;\n let renderPass: RenderPass | undefined;\n const size: Size = { width: 1, height: 1, pixelRatio: 1 };\n\n const dispose = (): void => {\n if (composer === undefined) return;\n for (const pass of composer.passes) pass.dispose();\n composer.dispose();\n composer = undefined;\n renderPass = undefined;\n };\n\n const build = (): void => {\n dispose();\n if (effects.length === 0) return;\n const target = new WebGLRenderTarget(size.width, size.height, {\n type: HalfFloatType,\n samples: 4,\n });\n const next = new EffectComposer(renderer, target);\n const first = new RenderPass(new EmptyScene(), new PerspectiveCamera());\n next.addPass(first);\n for (const effect of effects) next.addPass(passFor(effect, size));\n next.addPass(new OutputPass());\n next.setPixelRatio(size.pixelRatio);\n next.setSize(size.width, size.height);\n composer = next;\n renderPass = first;\n };\n\n return {\n configure: (next) => {\n if (effectsEqual(next, effects)) return;\n effects = next;\n build();\n },\n setSize: (width, height, pixelRatio) => {\n size.width = width;\n size.height = height;\n size.pixelRatio = pixelRatio;\n composer?.setPixelRatio(pixelRatio);\n composer?.setSize(width, height);\n },\n render: (scene, camera) => {\n if (composer === undefined || renderPass === undefined) return false;\n renderPass.scene = scene;\n renderPass.camera = camera;\n composer.render();\n return true;\n },\n dispose,\n };\n};\n",
12
+ "/**\n * What the WebGL and WebGPU renderers share: the scene's render settings by three.js's\n * names, recompiling materials when shadows switch, and which renderer draws each\n * canvas, for presenting it in an immersive session.\n *\n * @module\n */\nimport type { RenderSettings } from '@opsydyn/effect-three';\nimport {\n ACESFilmicToneMapping,\n AgXToneMapping,\n BasicShadowMap,\n CineonToneMapping,\n type ColorSpace,\n LinearSRGBColorSpace,\n LinearToneMapping,\n Material,\n NeutralToneMapping,\n NoToneMapping,\n type Object3D,\n PCFShadowMap,\n ReinhardToneMapping,\n type ShadowMapType,\n SRGBColorSpace,\n type ToneMapping,\n VSMShadowMap,\n type WebGLRenderer,\n} from 'three';\nimport type { WebGPURenderer } from 'three/webgpu';\n\n/**\n * Shadow map types by React Three Fiber's names (`core/configuration.ts` at `d74622e`).\n * three 0.186 folded PCF soft into PCF (softness is per light), so `soft` maps to PCF\n * here; R3F's PCFSoftShadowMap would only log a removal warning on this version.\n */\nexport const shadowTypes = {\n basic: BasicShadowMap,\n percentage: PCFShadowMap,\n soft: PCFShadowMap,\n variance: VSMShadowMap,\n} satisfies Record<Exclude<RenderSettings['shadows'], 'off'>, ShadowMapType>;\n\nexport const toneMappings = {\n none: NoToneMapping,\n linear: LinearToneMapping,\n reinhard: ReinhardToneMapping,\n cineon: CineonToneMapping,\n aces: ACESFilmicToneMapping,\n agx: AgXToneMapping,\n neutral: NeutralToneMapping,\n} satisfies Record<RenderSettings['toneMapping'], ToneMapping>;\n\nexport const colorSpaces = {\n srgb: SRGBColorSpace,\n linear: LinearSRGBColorSpace,\n} satisfies Record<RenderSettings['colorSpace'], ColorSpace>;\n\n/**\n * Flags every material in the scene for recompilation. three.js keeps a shader built\n * with shadows sampling its last shadow map after `shadowMap.enabled` turns off (and\n * without shadows after it turns on) until its material is updated.\n */\nexport const recompileMaterials = (scene: Object3D): void => {\n scene.traverse((object) => {\n const material: unknown = Reflect.get(object, 'material');\n const materials = Array.isArray(material) ? material : [material];\n for (const each of materials) if (each instanceof Material) each.needsUpdate = true;\n });\n};\n\n/** What presenting a renderer in WebXR uses; three's WebGL and WebGPU renderers both have it. */\nexport type PresentableRenderer = {\n readonly xr: {\n enabled: boolean;\n readonly isPresenting: boolean;\n setReferenceSpaceType: (type: XRReferenceSpaceType) => void;\n setFramebufferScaleFactor: (scale: number) => void;\n setSession: (session: XRSession) => Promise<void>;\n getReferenceSpace: () => XRReferenceSpace | null;\n setReferenceSpace: (space: XRReferenceSpace) => void;\n getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined;\n };\n /**\n * Hands the session's frames to `callback` (`null` stops), set before the session starts:\n * WebGL's `xr.setAnimationLoop`, or WebGPU's `setAnimationLoop`, which its XR manager\n * captures when the session starts. It may also be called outside the session.\n */\n readonly setXrLoop: (callback: ((time: number, frame?: XRFrame) => void) | null) => void;\n};\n\n/** Each canvas's three.js renderer, for presenting it in a WebXR session. */\nconst presentable = new WeakMap<HTMLCanvasElement, PresentableRenderer>();\n/** Each canvas's three.js renderer itself, for tests that read three's own state. */\nconst drawing = new WeakMap<HTMLCanvasElement, WebGLRenderer | WebGPURenderer>();\n\nexport const registerPresentable = (\n canvas: HTMLCanvasElement,\n renderer: WebGLRenderer | WebGPURenderer,\n presenting: PresentableRenderer,\n): void => {\n presentable.set(canvas, presenting);\n drawing.set(canvas, renderer);\n};\n\nexport const forgetPresentable = (canvas: HTMLCanvasElement): void => {\n presentable.delete(canvas);\n drawing.delete(canvas);\n};\n\n/** The three.js renderer drawing into `canvas` (WebGL or WebGPU), if one does. */\nexport const threeRendererOf = (\n canvas: HTMLCanvasElement,\n): WebGLRenderer | WebGPURenderer | undefined => drawing.get(canvas);\n\n/** The three.js renderer drawing into `canvas`, if one does. */\nexport const presentableRendererOf = (canvas: HTMLCanvasElement): PresentableRenderer | undefined =>\n presentable.get(canvas);\n",
13
+ "/**\n * three.js's `WebGPURenderer` behind the core's renderer contract: WebGPU where the browser\n * has it, otherwise its WebGL 2 backend (or always, with `forceWebGL`), drawing the same\n * node materials either way. It carries the WebGPU render kit (the sky, shader grid and\n * contact shadows in TSL), post-processes with `RenderPipeline`, and presents in WebXR.\n * It starts asynchronously (`init()`), which the runtime waits for.\n *\n * Not drawn under it: labels, which troika makes from WebGL shaders; a label engine's\n * labels are silently empty here.\n *\n * @module\n */\nimport type { RendererFactory, RenderSettings, RenderTarget } from '@opsydyn/effect-three';\nimport { webgpuKit } from '@opsydyn/effect-three/webgpu';\nimport {\n type Camera,\n HalfFloatType,\n LinearFilter,\n type Object3D,\n RenderTarget as ThreeRenderTarget,\n type Scene,\n Vector2,\n} from 'three';\nimport { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';\nimport { PMREMGenerator, WebGPURenderer } from 'three/webgpu';\n\nimport {\n colorSpaces,\n forgetPresentable,\n recompileMaterials,\n registerPresentable,\n shadowTypes,\n toneMappings,\n} from './renderSettings.ts';\nimport { createWebGPUPostProcessing } from './webgpuPostprocessing.ts';\n\n/** Options for three's `WebGPURenderer`. The canvas is always the scene's own. */\nexport type WebGPUOptions = {\n /** Use the WebGL 2 backend even where WebGPU is available. */\n readonly forceWebGL?: boolean;\n readonly alpha?: boolean;\n readonly antialias?: boolean;\n};\n\n/** Applies scene render settings; returns whether shadows were switched on or off. */\nconst configure = (renderer: WebGPURenderer, settings: RenderSettings): boolean => {\n const shadowMap = renderer.shadowMap;\n const enabled = settings.shadows !== 'off';\n const switched = shadowMap.enabled !== enabled;\n shadowMap.enabled = enabled;\n if (enabled) shadowMap.type = shadowTypes[settings.shadows];\n renderer.toneMapping = toneMappings[settings.toneMapping];\n renderer.toneMappingExposure = settings.exposure;\n renderer.outputColorSpace = colorSpaces[settings.colorSpace];\n return switched;\n};\n\nconst drawingSize = new Vector2();\n\n/**\n * A render texture's target, as the WebGL renderer makes one (Drei's `useFBO`): half-float\n * colour, linear filtering, multisampled (4, WebGPU's only multisample count), with depth.\n */\nconst createTarget = (\n targets: WeakMap<RenderTarget, ThreeRenderTarget>,\n width: number,\n height: number,\n): RenderTarget => {\n const target = new ThreeRenderTarget(width, height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n type: HalfFloatType,\n samples: 4,\n });\n const handle = { texture: target.texture, dispose: () => target.dispose() };\n targets.set(handle, target);\n return handle;\n};\n\n/** three.js's `RoomEnvironment`, prefiltered by the WebGPU renderer's PMREM generator. */\nconst createRoom = (renderer: WebGPURenderer): RenderTarget => {\n const generator = new PMREMGenerator(renderer);\n const room = new RoomEnvironment();\n const target = generator.fromScene(room, 0.04);\n room.dispose();\n generator.dispose();\n return { texture: target.texture, dispose: () => target.dispose() };\n};\n\n/**\n * Draws a frame of an immersive session. In AR the room shows through, so a background\n * (an environment shown as one) is left out of the frame, as the WebGL renderer does.\n */\nconst drawPresenting = (renderer: WebGPURenderer, scene: Scene, camera: Camera): void => {\n const passthrough = renderer.xr.getEnvironmentBlendMode() !== 'opaque';\n if (!passthrough || scene.background === null) {\n renderer.render(scene, camera);\n return;\n }\n const background = scene.background;\n scene.background = null;\n renderer.render(scene, camera);\n scene.background = background;\n};\n\n/** A factory for three's `WebGPURenderer` drawing into `canvas`. */\nexport const webgpuRendererFactory = (\n canvas: HTMLCanvasElement,\n options: WebGPUOptions = {},\n): RendererFactory => ({\n // The TSL parts of a scene (sky, shader grid, contact shadows) go with this renderer.\n kit: webgpuKit,\n create: () => {\n // Opaque by default, as three's WebGLRenderer is (WebGPURenderer's own default is alpha).\n const renderer = new WebGPURenderer({ antialias: true, alpha: false, ...options, canvas });\n registerPresentable(canvas, renderer, {\n xr: renderer.xr,\n setXrLoop: (callback) => {\n void renderer.setAnimationLoop(callback);\n },\n });\n const post = createWebGPUPostProcessing(renderer);\n const targets = new WeakMap<RenderTarget, ThreeRenderTarget>();\n let pixelRatio = 1;\n let resolution = 1;\n let scissored = false;\n let shadowSwitches = 0;\n const compiledAt = new WeakMap<Object3D, number>();\n const applyPixelRatio = (): void => {\n if (renderer.getPixelRatio() !== pixelRatio * resolution) {\n renderer.setPixelRatio(pixelRatio * resolution);\n }\n };\n return {\n ready: () => renderer.init().then(() => undefined),\n render: (scene, camera, area, target) => {\n if (shadowSwitches > 0 && compiledAt.get(scene) !== shadowSwitches) {\n recompileMaterials(scene);\n compiledAt.set(scene, shadowSwitches);\n }\n const offscreen = target === undefined ? undefined : targets.get(target);\n if (offscreen !== undefined) {\n // As the WebGL renderer: into the target, transparent, never from the headset.\n const previous = renderer.getRenderTarget();\n const clearAlpha = renderer.getClearAlpha();\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n renderer.setClearAlpha(0);\n renderer.setRenderTarget(offscreen);\n renderer.render(scene, camera);\n renderer.setRenderTarget(previous);\n renderer.setClearAlpha(clearAlpha);\n renderer.xr.enabled = xrEnabled;\n return;\n }\n // Presenting in XR, three draws the headset's views itself: no areas, no effects.\n if (renderer.xr.isPresenting) {\n drawPresenting(renderer, scene, camera);\n return;\n }\n const { width, height } = renderer.getSize(drawingSize);\n if (area === undefined) {\n if (scissored) {\n renderer.setScissorTest(false);\n renderer.setViewport(0, 0, width, height);\n scissored = false;\n }\n if (!post.render(scene, camera)) renderer.render(scene, camera);\n return;\n }\n // three's viewport and scissor origin is the bottom left; areas are from the top.\n const bottom = height - area.y - area.height;\n renderer.setViewport(area.x, bottom, area.width, area.height);\n renderer.setScissor(area.x, bottom, area.width, area.height);\n renderer.setScissorTest(true);\n scissored = true;\n renderer.render(scene, camera);\n },\n createTarget: (width, height) => createTarget(targets, width, height),\n createEnvironment: () => createRoom(renderer),\n configure: (settings) => {\n if (configure(renderer, settings)) shadowSwitches++;\n resolution = settings.resolution;\n post.configure(settings.effects);\n applyPixelRatio();\n },\n setViewport: (viewport) => {\n pixelRatio = viewport.pixelRatio;\n applyPixelRatio();\n renderer.setSize(viewport.width, viewport.height, false);\n },\n memory: () => ({\n geometries: renderer.info.memory.geometries,\n textures: renderer.info.memory.textures,\n }),\n dispose: () => {\n forgetPresentable(canvas);\n void renderer.xr.getSession()?.end();\n post.dispose();\n void renderer.dispose();\n },\n };\n },\n});\n",
14
+ "/**\n * Post-processing for the WebGPU renderer: three.js's `RenderPipeline` with TSL nodes for\n * the same effects the WebGL renderer composes (`postprocessing.ts`): bloom\n * (`tsl/display/BloomNode.js`, added to the scene as three's examples add it), film\n * (`tsl/display/FilmNode.js`'s grain, written here, with grayscale by luminance as\n * `FilmPass` offers) and\n * vignette (three's `VignetteShader`, as TSL). The pipeline's output transform applies\n * tone mapping and the output colour space, as the WebGL composer's `OutputPass` does.\n *\n * @module\n */\nimport { effectsEqual, type PostEffect } from '@opsydyn/effect-three';\nimport type { Camera, Scene } from 'three';\nimport { bloom } from 'three/addons/tsl/display/BloomNode.js';\nimport {\n clamp,\n dot,\n fract,\n luminance,\n mix,\n pass,\n rand,\n screenUV,\n time,\n uv,\n vec3,\n vec4,\n} from 'three/tsl';\nimport { type Node, RenderPipeline, type WebGPURenderer } from 'three/webgpu';\n\nimport type { PostProcessing } from './postprocessing.ts';\n\ntype Colour = Node<'vec4'>;\n\n/** One effect applied to the colour so far. */\nconst applied = (input: Colour, effect: PostEffect): Colour => {\n switch (effect._tag) {\n case 'Bloom':\n return input.add(bloom(input, effect.strength, effect.radius, effect.threshold));\n case 'Vignette': {\n // three's VignetteShader: towards `1 − darkness` with distance from the middle.\n const centred = screenUV.sub(0.5).mul(effect.offset);\n return vec4(mix(input.rgb, vec3(1 - effect.darkness), dot(centred, centred)), input.a);\n }\n case 'Film': {\n // three's FilmNode: noise added in proportion to the colour, mixed in by intensity.\n const base = input.rgb;\n const noise = rand(fract(uv().add(time)));\n const grained = mix(base, base.add(base.mul(clamp(noise.add(0.1), 0, 1))), effect.intensity);\n return vec4(effect.grayscale ? vec3(luminance(grained)) : grained, input.a);\n }\n }\n};\n\nexport const createWebGPUPostProcessing = (renderer: WebGPURenderer): PostProcessing => {\n let effects: ReadonlyArray<PostEffect> = [];\n let pipeline: RenderPipeline | undefined;\n // The scene and camera the pipeline's scene pass draws: a new one rebuilds it.\n let drawn: { readonly scene: Scene; readonly camera: Camera } | undefined;\n\n const dispose = (): void => {\n pipeline?.dispose();\n pipeline = undefined;\n drawn = undefined;\n };\n\n const build = (scene: Scene, camera: Camera): RenderPipeline => {\n dispose();\n const output = effects.reduce<Colour>(applied, pass(scene, camera));\n const next = new RenderPipeline(renderer, output);\n pipeline = next;\n drawn = { scene, camera };\n return next;\n };\n\n return {\n configure: (next) => {\n if (effectsEqual(next, effects)) return;\n effects = next;\n dispose();\n },\n // The pipeline follows the renderer's size.\n setSize: () => undefined,\n render: (scene, camera) => {\n if (effects.length === 0) return false;\n const current =\n pipeline !== undefined && drawn?.scene === scene && drawn.camera === camera\n ? pipeline\n : build(scene, camera);\n current.render();\n return true;\n },\n dispose,\n };\n};\n",
15
+ "/**\n * The `<effect-three-scene>` element: a typed `scene` property that Foldkit diffs on\n * every render, and Schema-decoded events that become the app's typed Messages.\n *\n * The tag is never registered with `customElements`; the scene Mount intercepts the\n * property instead (ADR-002), so there is nothing to re-register under HMR or SSR.\n *\n * @module\n */\nimport { SceneSchema, type SceneEvent } from '@opsydyn/effect-three';\nimport { Schema } from 'effect';\nimport { CustomElement } from 'foldkit';\nimport { defineMessageUnion } from 'foldkit/message';\n\n/** A scene update that could not be applied. The scene keeps its last good state. */\nexport const SceneError = Schema.Union([\n ...SceneSchema.DescriptionError.members,\n Schema.TaggedStruct('MalformedScene', { issue: Schema.String }),\n]);\nexport type SceneError = typeof SceneError.Type;\n\nconst Counts = Schema.Struct({ live: Schema.Int, created: Schema.Int, disposed: Schema.Int });\n\n/** What one scene update did, and the GPU resources held afterwards. */\nexport const ReconciledDetail = Schema.Struct({\n ops: Schema.Struct({\n created: Schema.Int,\n updated: Schema.Int,\n moved: Schema.Int,\n removed: Schema.Int,\n replaced: Schema.Int,\n reordered: Schema.Int,\n configured: Schema.Int,\n }),\n resources: Schema.Struct({ geometries: Counts, materials: Counts }),\n});\nexport type ReconciledDetail = typeof ReconciledDetail.Type;\n\n/** An immersive session began presenting the scene in `mode`, or ended (`null`). */\nexport const XrSessionDetail = Schema.Struct({\n mode: Schema.NullOr(Schema.Literals(['immersive-vr', 'immersive-ar'])),\n});\nexport type XrSessionDetail = typeof XrSessionDetail.Type;\n\nexport const sceneElement = CustomElement.define({\n tag: 'effect-three-scene',\n properties: { scene: SceneSchema.SceneDescription },\n events: {\n 'scene-click': SceneSchema.ButtonDetail,\n 'scene-double-click': SceneSchema.ButtonDetail,\n 'scene-context-menu': SceneSchema.HitDetail,\n 'scene-pointer-down': SceneSchema.ButtonDetail,\n 'scene-pointer-up': SceneSchema.ButtonDetail,\n 'scene-pointer-enter': SceneSchema.HitDetail,\n 'scene-pointer-move': SceneSchema.HitDetail,\n 'scene-pointer-leave': SceneSchema.KeyDetail,\n 'scene-pointer-missed': SceneSchema.MissDetail,\n 'scene-wheel': SceneSchema.WheelDetail,\n 'scene-drag': SceneSchema.DragDetail,\n 'scene-drag-end': SceneSchema.DragDetail,\n 'scene-gesture': SceneSchema.GestureDetail,\n 'scene-auto-rotated': SceneSchema.AutoRotatedDetail,\n 'scene-collision': SceneSchema.CollisionDetail,\n 'scene-contact-force': SceneSchema.ContactForceDetail,\n 'scene-measured': SceneSchema.MeasuredDetail,\n 'scene-label-measured': SceneSchema.LabelMeasuredDetail,\n 'scene-xr': XrSessionDetail,\n 'scene-xr-stick': SceneSchema.XrStickDetail,\n 'scene-xr-button': SceneSchema.XrButtonDetail,\n 'scene-xr-surface': SceneSchema.XrSurfaceDetail,\n 'scene-xr-moved': SceneSchema.XrMovedDetail,\n 'scene-xr-planes': SceneSchema.XrPlanesDetail,\n 'scene-xr-meshes': SceneSchema.XrMeshesDetail,\n 'scene-performance': SceneSchema.PerformanceDetail,\n 'scene-error': Schema.Struct({ error: SceneError }),\n 'scene-reconciled': ReconciledDetail,\n },\n});\n\n/** The DOM event name for each kernel scene event. */\nexport const domEventName = {\n Click: 'scene-click',\n DoubleClick: 'scene-double-click',\n ContextMenu: 'scene-context-menu',\n PointerDown: 'scene-pointer-down',\n PointerUp: 'scene-pointer-up',\n PointerEnter: 'scene-pointer-enter',\n PointerMove: 'scene-pointer-move',\n PointerLeave: 'scene-pointer-leave',\n PointerMissed: 'scene-pointer-missed',\n Wheel: 'scene-wheel',\n Drag: 'scene-drag',\n DragEnd: 'scene-drag-end',\n Gesture: 'scene-gesture',\n AutoRotated: 'scene-auto-rotated',\n Collision: 'scene-collision',\n ContactForce: 'scene-contact-force',\n Measured: 'scene-measured',\n LabelMeasured: 'scene-label-measured',\n XrStick: 'scene-xr-stick',\n XrButton: 'scene-xr-button',\n XrSurface: 'scene-xr-surface',\n XrMoved: 'scene-xr-moved',\n XrPlanes: 'scene-xr-planes',\n XrMeshes: 'scene-xr-meshes',\n PerformanceChanged: 'scene-performance',\n} as const satisfies Record<SceneEvent['_tag'], keyof typeof sceneElement.events>;\n\n/** Outcome of mounting a scene. Map these into the app's Messages with `onLifecycle`. */\nexport const SceneLifecycle = defineMessageUnion({\n StartedScene: {},\n FailedScene: { reason: Schema.String },\n});\nexport type SceneLifecycle = typeof SceneLifecycle.Type;\n",
16
+ "/**\n * Immersive sessions as Effects an application runs from Foldkit Commands: whether a mode\n * is supported, entering it from a user gesture, and leaving it. The scene presented is\n * the mounted one whose description has `xr`; while presenting, the session drives its\n * frames and the view's `onXRSession` reports the session starting and ending.\n *\n * @module\n */\nimport { Data, Effect } from 'effect';\n\nimport type { XrHub, XrMode } from './dom/xrHub.ts';\n\n/** A session could not start: no WebXR, no scene describing `xr`, or the request refused. */\nexport class XrUnavailable extends Data.TaggedError('XrUnavailable')<{\n readonly mode: XrMode;\n readonly cause: unknown;\n}> {}\n\n/** The immersive session controls for an environment's hub. */\nexport const makeXr = (hub: XrHub) => ({\n /** Whether the browser can present `mode` (false without WebXR). */\n supported: (mode: XrMode) => Effect.promise(() => hub.supported(mode)),\n /**\n * Enters `mode`, presenting the mounted scene that describes `xr`. Run it from the\n * Command a click (or other user gesture) produces: browsers require one.\n */\n enter: (mode: XrMode) =>\n Effect.tryPromise({\n try: () => hub.enter(mode),\n catch: (cause) => new XrUnavailable({ mode, cause }),\n }),\n /** Ends the session, if there is one. */\n exit: Effect.promise(() => hub.exit()),\n});\n\nexport type XrControls = ReturnType<typeof makeXr>;\n",
17
+ "/**\n * Summaries of scene updates, for the `scene-reconciled` event.\n *\n * @module\n */\nimport type { Op, ResourceStats } from '@opsydyn/effect-three';\n\nimport type { ReconciledDetail } from '../element.ts';\n\n/** Counts operations by kind and snapshots resource counters. */\nexport const summarise = (ops: ReadonlyArray<Op>, stats: ResourceStats): ReconciledDetail => {\n const counts = {\n created: 0,\n updated: 0,\n moved: 0,\n removed: 0,\n replaced: 0,\n reordered: 0,\n configured: 0,\n };\n for (const op of ops) {\n switch (op._tag) {\n case 'Create':\n counts.created++;\n break;\n case 'Update':\n counts.updated++;\n break;\n case 'Move':\n counts.moved++;\n break;\n case 'Remove':\n counts.removed++;\n break;\n case 'Replace':\n counts.replaced++;\n break;\n case 'Order':\n counts.reordered++;\n break;\n case 'SetCamera':\n case 'DefineResources':\n counts.configured++;\n break;\n }\n }\n return {\n ops: counts,\n resources: { geometries: { ...stats.geometries }, materials: { ...stats.materials } },\n };\n};\n",
18
+ "/**\n * App-wide state shared by every scene element: one GPU resource store and one\n * animation-frame scheduler. Create it once at the application entry point.\n *\n * @module\n */\nimport {\n type Behaviour,\n createResourceStore,\n type LabelEngine,\n type PhysicsEngine,\n type RendererFactory,\n type ResourceStore,\n} from '@opsydyn/effect-three';\n\nimport { makeAssets } from './assets.ts';\nimport { animationFrameScheduler, type AnimationFrameHost } from './dom/animationFrames.ts';\nimport { defaultPixelRatio, type PixelRatio } from './dom/viewport.ts';\nimport { webglRendererFactory } from './dom/webgl.ts';\nimport { createXrHub } from './dom/xrHub.ts';\nimport { makeXr } from './xr.ts';\n\n/** The browser APIs the adapter uses; normally `window`. */\nexport type EnvironmentHost = AnimationFrameHost &\n Pick<Window, 'matchMedia' | 'devicePixelRatio'> &\n Partial<Pick<Window, 'navigator'>>;\n\nexport type EnvironmentOptions = {\n /** Creates each scene's renderer from its canvas. Defaults to WebGL2. */\n readonly renderer?: (canvas: HTMLCanvasElement) => RendererFactory;\n /** Drawing-buffer pixel ratio: fixed, or `[min, max]` around the device's. Default `[1, 2]`. */\n readonly pixelRatio?: PixelRatio;\n /** Behaviours scenes may name with `behave(name)`, beside the built-in `float`. */\n readonly behaviours?: Readonly<Record<string, Behaviour>>;\n /**\n * The physics engine for scenes with `physics`, or the promise of one: pass\n * `loadRapier()` from `@opsydyn/effect-three-rapier` as it is, and scenes start once it\n * has loaded. Without one, bodies stay where they are described.\n */\n readonly physics?: PhysicsEngine | Promise<PhysicsEngine>;\n /**\n * Draws `label` nodes: pass `troikaLabels()` from `@opsydyn/effect-three-troika`.\n * Without one, labels are empty.\n */\n readonly labels?: LabelEngine;\n};\n\n/** Creates the shared environment for `host`. Call `dispose` when the app shuts down. */\nexport const makeEnvironment = (host: EnvironmentHost, options: EnvironmentOptions = {}) => {\n const store: ResourceStore = createResourceStore();\n const assets = makeAssets(store);\n const xrHub = createXrHub(() => host.navigator?.xr);\n return {\n host,\n store,\n frames: animationFrameScheduler(host),\n renderer: options.renderer ?? ((canvas: HTMLCanvasElement) => webglRendererFactory(canvas)),\n pixelRatio: options.pixelRatio ?? defaultPixelRatio,\n behaviours: options.behaviours ?? {},\n /** The physics engine, once loaded; `undefined` when there is none. */\n physics: Promise.resolve(options.physics),\n /** The label engine; `undefined` when there is none. */\n labels: options.labels,\n /** Loads textures and glTF models by URL and lends them to the store. */\n assets,\n /** Enters and leaves immersive (WebXR) sessions, from Commands. */\n xr: makeXr(xrHub),\n /** The page's presentable scenes and its session; scene mounts register here. */\n xrHub,\n /** Disposes every loaded asset and every GPU resource still held. */\n dispose: () => {\n assets.dispose();\n store.dispose();\n },\n };\n};\n\nexport type Environment = ReturnType<typeof makeEnvironment>;\n",
19
+ "/**\n * Presenting a scene in a WebXR session through three.js's `WebXRManager`.\n *\n * Behavioural references: React Three Fiber `core/configuration.ts` at `d74622e` (on\n * `sessionstart` enable XR and hand frames to `xr.setAnimationLoop`; on `sessionend` take\n * them back and draw again), and pmndrs/xr at `0e1acd8` (`store.ts` `setupXRManager`:\n * reference space type and framebuffer scale before `setSession`; `init.ts`\n * `buildXRSessionInit`: the reference space required, other features optional). The\n * player's origin is an offset reference space, as three.js's teleport example moves\n * the viewer. Controller selects become rays, as `@react-three/xr`'s pointers hit-test\n * along each controller's target ray.\n *\n * @module\n */\nimport type { Xr, XrInput } from '@opsydyn/effect-three';\nimport { Group, type Object3D } from 'three';\n\nimport type { PresentableRenderer } from './renderSettings.ts';\nimport { floorFacing, type GlidePose, glideFrame, startGlider } from './xrGlide.ts';\nimport { rayOf, trackInputs, type XrInputs } from './xrInputs.ts';\nimport { type Follow, type LendGeometry, trackSpaces } from './xrSpaces.ts';\n\n/** Where an immersive session can come from: `navigator.xr`, or an emulator's. */\nexport type XrSystem = Pick<XRSystem, 'requestSession' | 'isSessionSupported'>;\n\n/** The immersive session modes. */\nexport type XrMode = 'immersive-vr' | 'immersive-ar';\n\n/**\n * The session request for a scene's settings: its reference space required, other\n * floors, hand tracking and anchors optional, and plane detection, a DOM overlay (on\n * `overlay`, the scene's element) and in AR hit testing when the scene asks for them\n * (pmndrs/xr's `buildXRSessionInit` asks for every feature it may use, optionally, and\n * roots the overlay on the element it is given). Anchors are asked for whether or not\n * the scene has any yet: it may place them mid-session.\n */\nexport const sessionInit = (\n settings: Xr,\n mode: XrMode = 'immersive-vr',\n overlay?: Element,\n): XRSessionInit => ({\n requiredFeatures: [settings.referenceSpace],\n optionalFeatures: [\n ...['local-floor', 'bounded-floor', 'hand-tracking', 'anchors'].filter(\n (feature) => feature !== settings.referenceSpace,\n ),\n ...(settings.planes ? ['plane-detection'] : []),\n ...(settings.meshes ? ['mesh-detection'] : []),\n ...(settings.domOverlay && overlay !== undefined ? ['dom-overlay'] : []),\n ...(mode === 'immersive-ar' && settings.hitTest ? ['hit-test'] : []),\n ],\n ...(settings.domOverlay && overlay !== undefined ? { domOverlay: { root: overlay } } : {}),\n});\n\n/**\n * The offset that puts the player at `origin` facing `heading`: a reference space whose\n * poses are the device's, rotated by the heading and moved to the origin.\n */\nconst originOffset = (settings: GlidePose): XRRigidTransform => {\n const [x, y, z] = settings.origin;\n const half = -settings.heading / 2;\n const cos = Math.cos(-settings.heading);\n const sin = Math.sin(-settings.heading);\n // The inverse of \"rotate by heading, then move to origin\": rotate by −heading the point −origin.\n return new XRRigidTransform(\n { x: -x * cos - z * sin, y: -y, z: x * sin - z * cos },\n { x: 0, y: Math.sin(half), z: 0, w: Math.cos(half) },\n );\n};\n\n/**\n * Forwards each source's select as a ray in the presented space (the scene's, since the\n * reference space is offset to the player's origin); a select ending in AR also reports\n * the surface its ray met. Returns a function that stops.\n */\nconst listenForSelects = (\n session: XRSession,\n space: () => XRReferenceSpace | null,\n inputs: XrInputs,\n input: (input: XrInput) => void,\n): (() => void) => {\n const forward = (tag: 'SelectStart' | 'SelectEnd') => (event: XRInputSourceEvent) => {\n const reference = space();\n const pose =\n reference === null\n ? undefined\n : event.frame.getPose(event.inputSource.targetRaySpace, reference);\n if (pose !== undefined && pose !== null) {\n input({ _tag: tag, source: inputs.idOf(event.inputSource), ray: rayOf(pose) });\n }\n if (tag === 'SelectEnd') inputs.selected(event.inputSource);\n };\n const started = forward('SelectStart');\n const ended = forward('SelectEnd');\n session.addEventListener('selectstart', started);\n session.addEventListener('selectend', ended);\n return () => {\n session.removeEventListener('selectstart', started);\n session.removeEventListener('selectend', ended);\n };\n};\n\nexport type Presentation = {\n /** Applies new settings mid-session: a new origin or heading moves the player. */\n readonly update: (settings: Xr) => void;\n readonly session: XRSession;\n};\n\n/** What a session presents: the scene, and how it is drawn, followed and told of input. */\nexport type Presented = {\n readonly scene: Object3D;\n readonly draw: () => void;\n /** Places the groups that follow tracked spaces (`group({ follow })`). */\n readonly follow: Follow;\n /** Lends detected meshes' geometry to the scene (`xrMesh(id)`). */\n readonly lend: LendGeometry;\n readonly input: (input: XrInput) => void;\n};\n\n/**\n * Presents into `session`: frames come from the session (each read for input and the\n * spaces groups follow, then drawn) until it ends, when `ended` is called and the page's\n * own frames take over again. Input sources are drawn into the scene while it presents.\n */\nexport const present = async (\n renderer: PresentableRenderer,\n session: XRSession,\n settings: Xr,\n presented: Presented,\n ended: () => void,\n): Promise<Presentation> => {\n const { scene, draw, input } = presented;\n const { xr } = renderer;\n xr.enabled = true;\n xr.setReferenceSpaceType(settings.referenceSpace);\n xr.setFramebufferScaleFactor(settings.framebufferScale);\n let inputs: XrInputs | undefined;\n const spaces = trackSpaces(session, () => current, presented.follow, input, presented.lend);\n let current = settings;\n // Gliding (`xr({ glide })`) moves the player from the description's place; the\n // description wins again whenever it changes.\n let glider = startGlider({ origin: settings.origin, heading: settings.heading });\n let lastTime: number | undefined;\n let base: XRReferenceSpace | null = null;\n const place = (pose: GlidePose): void => {\n if (base !== null) xr.setReferenceSpace(base.getOffsetReferenceSpace(originOffset(pose)));\n };\n\n /** One frame of gliding, when the description asks for it. */\n const glideStep = (time: number, frame: XRFrame, space: XRReferenceSpace): void => {\n const seconds = Math.min(0.1, Math.max(0, (time - (lastTime ?? time)) / 1000));\n lastTime = time;\n if (current.glide === null || inputs === undefined) return;\n const head = frame.getViewerPose(space);\n const facing = floorFacing(head?.transform.orientation ?? { x: 0, y: 0, z: 0, w: 1 });\n const { left, right } = inputs.sticks();\n const next = glideFrame(glider, current.glide, { move: left, turn: right }, facing, seconds);\n if (next.glider.pose !== glider.pose) place(next.glider.pose);\n glider = next.glider;\n if (next.stopped !== undefined) input({ _tag: 'Moved', ...next.stopped });\n };\n\n /** One session frame: its input read, then drawn. Frames outside the session are skipped. */\n function sessionFrame(time: number, frame?: XRFrame): void {\n if (!xr.isPresenting) return;\n const space = xr.getReferenceSpace();\n if (frame !== undefined && space !== null) {\n inputs?.frame(frame, space);\n glideStep(time, frame, space);\n // After gliding, so the spaces are where the player now stands.\n spaces.frame(frame, xr.getReferenceSpace() ?? space);\n }\n draw();\n }\n // Set before the session starts (WebGPU's XR manager takes the loop then).\n renderer.setXrLoop(sessionFrame);\n await xr.setSession(session);\n base = xr.getReferenceSpace();\n place(glider.pose);\n const shown = new Group();\n shown.name = 'xr-inputs';\n scene.add(shown);\n const tracked = trackInputs(session, shown, () => current, input);\n inputs = tracked;\n const stopSelects = listenForSelects(session, () => xr.getReferenceSpace(), tracked, input);\n session.addEventListener(\n 'end',\n () => {\n stopSelects();\n tracked.stop();\n spaces.stop();\n shown.removeFromParent();\n renderer.setXrLoop(null);\n xr.enabled = false;\n ended();\n },\n { once: true },\n );\n return {\n session,\n update: (next) => {\n const moved =\n next.origin.some((value, i) => value !== current.origin[i]) ||\n next.heading !== current.heading;\n current = next;\n if (!moved) return;\n glider = startGlider({ origin: next.origin, heading: next.heading });\n place(glider.pose);\n },\n };\n};\n",
20
+ "/**\n * Gliding with the thumbsticks while presenting (`xr({ glide })`), one frame at a time.\n *\n * Behavioural reference: pmndrs/xr at `0e1acd8`, `packages/xr/src/controller-locomotion.ts`:\n * the left stick moves the player along the head's facing, flattened onto the floor, at\n * `speed` metres per second at full stick (forward is the stick pushed away, negative y);\n * the right stick turns, smoothly at `turnSpeed`, or by `snapDegrees` once per push past\n * halfway, ready again once back under it. Unlike there, a still stick is a still player\n * (a small dead zone keeps resting thumbsticks from drifting), and the frame that stops\n * says where the player ended, for the Model.\n *\n * @module\n */\nimport type { Vec3, XrGlide } from '@opsydyn/effect-three';\n\n/** Where the player stands: the reference space's origin in the scene, and its heading. */\nexport type GlidePose = { readonly origin: Vec3; readonly heading: number };\n\n/** A thumbstick, `[x, y]`, each −1 to 1 (`y` negative pushed away). */\nexport type Stick = readonly [x: number, y: number];\n\n/** Gliding's state between frames. */\nexport type Glider = {\n readonly pose: GlidePose;\n /** Whether a snap turn is ready (the turning stick has been back under halfway). */\n readonly snapReady: boolean;\n /** Whether the pose moved since the last report. */\n readonly moved: boolean;\n};\n\n/** Thumbsticks rest a little off centre; under this they are still. */\nconst deadZone = 0.15;\n/** Past this the turning stick turns (pmndrs/xr's default dead zone, 0.5). */\nconst turnZone = 0.5;\n\nexport const startGlider = (pose: GlidePose): Glider => ({ pose, snapReady: true, moved: false });\n\n/** The head's facing on the floor, from its orientation quaternion: −z turned, flattened. */\nexport const floorFacing = (q: {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n readonly w: number;\n}): readonly [x: number, z: number] => {\n const x = -2 * (q.x * q.z + q.w * q.y);\n const z = -(1 - 2 * (q.x * q.x + q.y * q.y));\n const length = Math.hypot(x, z);\n return length < 1e-6 ? [0, -1] : [x / length, z / length];\n};\n\nconst still = (stick: Stick, zone: number): boolean =>\n Math.abs(stick[0]) < zone && Math.abs(stick[1]) < zone;\n\n/** One step of moving: along the head's facing and its right, by the stick. */\nconst moveBy = (\n origin: Vec3,\n stick: Stick,\n facing: readonly [number, number],\n distance: number,\n): Vec3 => {\n const [fx, fz] = facing;\n // The right of the facing (fx, fz) on the floor, y up: (−fz, fx).\n const forward = -stick[1] * distance;\n const right = stick[0] * distance;\n return [origin[0] + fx * forward - fz * right, origin[1], origin[2] + fz * forward + fx * right];\n};\n\n/** The heading after the turning stick, and whether a snap is ready next frame. */\nconst turnBy = (\n glider: Glider,\n glide: XrGlide,\n stick: Stick,\n seconds: number,\n): { readonly heading: number; readonly snapReady: boolean } => {\n const { heading } = glider.pose;\n const pushed = Math.abs(stick[0]) >= turnZone;\n if (glide.turn === 'smooth') {\n return {\n heading: pushed ? heading - stick[0] * glide.turnSpeed * seconds : heading,\n snapReady: true,\n };\n }\n if (!pushed) return { heading, snapReady: true };\n if (!glider.snapReady) return { heading, snapReady: false };\n // Pushed right turns right: the heading (about +y) goes down.\n return {\n heading: heading - (Math.sign(stick[0]) * (glide.snapDegrees * Math.PI)) / 180,\n snapReady: false,\n };\n};\n\n/**\n * One frame of gliding. Returns the next state, and the pose to report when the sticks\n * have just come to rest after moving it.\n */\nexport const glideFrame = (\n glider: Glider,\n glide: XrGlide,\n sticks: { readonly move: Stick; readonly turn: Stick },\n facing: readonly [number, number],\n seconds: number,\n): { readonly glider: Glider; readonly stopped: GlidePose | undefined } => {\n const moving = !still(sticks.move, deadZone);\n const origin = moving\n ? moveBy(glider.pose.origin, sticks.move, facing, glide.speed * seconds)\n : glider.pose.origin;\n const { heading, snapReady } = turnBy(glider, glide, sticks.turn, seconds);\n const changed = moving || heading !== glider.pose.heading;\n const resting = !moving && still(sticks.turn, turnZone);\n const moved = glider.moved || changed;\n const pose = { origin, heading };\n if (resting && moved) return { glider: { pose, snapReady, moved: false }, stopped: pose };\n return { glider: { pose, snapReady, moved }, stopped: undefined };\n};\n",
21
+ "/**\n * A session's input sources, each frame: where each points (`Aim`), its gamepad's sticks\n * and buttons, in AR where its ray meets a real surface, and drawing its ray and a hand's\n * joints into the presented scene.\n *\n * Behavioural references: pmndrs/xr at `0e1acd8` (`packages/xr/src/pointer` ray-casts\n * along every source's target ray each frame; `controller-locomotion.ts` reads the\n * `xr-standard` thumbstick, axes 2 and 3, forward negative; `hit-test.ts` requests a hit\n * test source per space and reads `getHitTestResults` each frame), and three.js's\n * `XRHandPrimitiveModel` at 0.186.1 (a sphere per hand joint, sized by its radius).\n *\n * @module\n */\nimport type {\n Ray,\n Vec3,\n Xr,\n XrButtonName,\n XrHand,\n XrInput,\n XrStickDirection,\n} from '@opsydyn/effect-three';\nimport {\n BufferGeometry,\n Float32BufferAttribute,\n Group,\n InstancedMesh,\n Line,\n LineBasicMaterial,\n Matrix4,\n MeshBasicMaterial,\n Quaternion,\n SphereGeometry,\n Vector3,\n} from 'three';\n\n/** A target ray pose as a ray in the reference space: from its position along its −z. */\nexport const rayOf = (pose: XRPose): Ray => {\n const { position, orientation } = pose.transform;\n const { x, y, z, w } = orientation;\n // −z rotated by the orientation quaternion.\n return {\n origin: [position.x, position.y, position.z],\n direction: [-2 * (x * z + w * y), -2 * (y * z - w * x), -(1 - 2 * (x * x + y * y))],\n };\n};\n\n/** The `xr-standard` mapping's buttons, by index. */\nconst buttonNames: ReadonlyArray<XrButtonName> = [\n 'trigger',\n 'squeeze',\n 'touchpad',\n 'thumbstick',\n 'primary',\n 'secondary',\n];\n\n/** Past this far a stick is pushed; back under the lower mark it is centred again. */\nconst stickThresholds = { push: 0.6, release: 0.3 } as const;\n\n/** Where a stick at `(x, y)` points, keeping `previous` until it clearly changes. */\nexport const stickDirection = (\n x: number,\n y: number,\n previous: XrStickDirection,\n): XrStickDirection => {\n if (Math.max(Math.abs(x), Math.abs(y)) < stickThresholds.release) return 'center';\n if (Math.max(Math.abs(x), Math.abs(y)) < stickThresholds.push) return previous;\n if (Math.abs(x) >= Math.abs(y)) return x < 0 ? 'left' : 'right';\n return y < 0 ? 'forward' : 'back';\n};\n\nconst handOf = (source: XRInputSource): XrHand => source.handedness;\n\n/** What the visuals show: a line along each ray, spheres on each hand's joints. */\nconst rayLength = 1.5;\nconst jointCount = 25;\nconst rayMaterial = new LineBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.6 });\nconst jointMaterial = new MeshBasicMaterial({ color: 0xe8e4dc });\nconst jointGeometry = new SphereGeometry(1, 10, 8);\n\ntype Visual = { readonly ray: Line; readonly joints: InstancedMesh | undefined };\n\nconst makeVisual = (source: XRInputSource, group: Group): Visual => {\n const geometry = new BufferGeometry();\n geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, -rayLength], 3));\n const ray = new Line(geometry, rayMaterial);\n ray.raycast = () => undefined;\n ray.matrixAutoUpdate = false;\n group.add(ray);\n const joints =\n source.hand === undefined\n ? undefined\n : new InstancedMesh(jointGeometry, jointMaterial, jointCount);\n if (joints !== undefined) {\n joints.raycast = () => undefined;\n joints.frustumCulled = false;\n group.add(joints);\n }\n return { ray, joints };\n};\n\nconst disposeVisual = (visual: Visual): void => {\n visual.ray.removeFromParent();\n visual.ray.geometry.dispose();\n visual.joints?.removeFromParent();\n visual.joints?.dispose();\n};\n\nconst matrix = new Matrix4();\nconst up = new Vector3(0, 1, 0);\nconst position = new Vector3();\nconst turn = new Quaternion();\nconst size = new Vector3();\n\n/** Places a hand's joint spheres from this frame's joint poses. */\nconst placeJoints = (\n joints: InstancedMesh,\n hand: XRHand,\n frame: XRFrame,\n space: XRReferenceSpace,\n): void => {\n let slot = 0;\n for (const jointSpace of hand.values()) {\n const pose = frame.getJointPose?.(jointSpace, space);\n if (pose !== undefined && pose !== null && slot < jointCount) {\n const { x, y, z } = pose.transform.position;\n const o = pose.transform.orientation;\n const radius = pose.radius ?? 0.008;\n matrix.compose(position.set(x, y, z), turn.set(o.x, o.y, o.z, o.w), size.setScalar(radius));\n joints.setMatrixAt(slot, matrix);\n slot++;\n }\n }\n joints.count = slot;\n joints.instanceMatrix.needsUpdate = true;\n};\n\ntype Tracked = {\n readonly id: number;\n visual: Visual | undefined;\n stick: XrStickDirection;\n /** The thumbstick's axes this frame, `[x, y]`. */\n axes: readonly [number, number];\n readonly pressed: Array<boolean>;\n hitTest: XRHitTestSource | undefined;\n /** Where its ray last met a real surface. */\n surface: { readonly point: Vec3; readonly normal: Vec3 } | undefined;\n};\n\n/** A hit test result's pose as a point and the surface's normal (the pose's +y). */\nconst surfaceOf = (pose: XRPose): { readonly point: Vec3; readonly normal: Vec3 } => {\n const { position: p, orientation: q } = pose.transform;\n // +y rotated by the orientation quaternion.\n return {\n point: [p.x, p.y, p.z],\n normal: [\n 2 * (q.x * q.y - q.w * q.z),\n 1 - 2 * (q.x * q.x + q.z * q.z),\n 2 * (q.y * q.z + q.w * q.x),\n ],\n };\n};\n\nexport type XrInputs = {\n /** Reads every input source in this frame, in `space` (the scene's). */\n readonly frame: (frame: XRFrame, space: XRReferenceSpace) => void;\n /** A source's id, the same for its selects as for its aims. */\n readonly idOf: (source: XRInputSource) => number;\n /** A select ended: in AR with hit tests, report where its ray met a surface. */\n readonly selected: (source: XRInputSource) => void;\n /** Ends tracking: every source is lost, and the visuals go. */\n readonly stop: () => void;\n /** Each hand's thumbstick this frame (`[0, 0]` without one). */\n readonly sticks: () => {\n readonly left: readonly [number, number];\n readonly right: readonly [number, number];\n };\n};\n\n/**\n * Tracks `session`'s input sources, sending what they do to `input` and drawing them into\n * `group` (added to the presented scene) while `settings().showInputs`.\n */\nexport const trackInputs = (\n session: XRSession,\n group: Group,\n settings: () => Xr | null,\n input: (input: XrInput) => void,\n): XrInputs => {\n const tracked = new Map<XRInputSource, Tracked>();\n let nextId = 0;\n\n const trackedOf = (source: XRInputSource): Tracked => {\n const known = tracked.get(source);\n if (known !== undefined) return known;\n const created: Tracked = {\n id: nextId++,\n visual: undefined,\n stick: 'center',\n axes: [0, 0],\n pressed: [],\n hitTest: undefined,\n surface: undefined,\n };\n tracked.set(source, created);\n if (settings()?.hitTest === true && session.requestHitTestSource !== undefined) {\n // Refused where the session lacks hit testing (it is optional): no surfaces, then.\n void session.requestHitTestSource({ space: source.targetRaySpace })?.then(\n (hitTest) => {\n if (tracked.get(source) === created) created.hitTest = hitTest;\n else hitTest.cancel();\n },\n () => undefined,\n );\n }\n return created;\n };\n\n const forget = (source: XRInputSource, state: Tracked): void => {\n tracked.delete(source);\n if (state.visual !== undefined) disposeVisual(state.visual);\n state.hitTest?.cancel();\n input({ _tag: 'Lost', source: state.id });\n };\n\n const gamepad = (source: XRInputSource, state: Tracked): void => {\n const pad = source.gamepad;\n if (pad === undefined || pad === null || pad.mapping !== 'xr-standard') return;\n const hand = handOf(source);\n buttonNames.forEach((button, index) => {\n const pressed = pad.buttons[index]?.pressed ?? false;\n if (pressed !== (state.pressed[index] ?? false)) {\n state.pressed[index] = pressed;\n input({ _tag: 'Button', source: state.id, hand, button, pressed });\n }\n });\n state.axes = [pad.axes[2] ?? 0, pad.axes[3] ?? 0];\n const direction = stickDirection(state.axes[0], state.axes[1], state.stick);\n if (direction !== state.stick) {\n state.stick = direction;\n input({ _tag: 'Stick', source: state.id, hand, direction });\n }\n };\n\n const show = (\n source: XRInputSource,\n state: Tracked,\n ray: Ray,\n frame: XRFrame,\n space: XRReferenceSpace,\n ) => {\n if (settings()?.showInputs !== true) {\n if (state.visual !== undefined) disposeVisual(state.visual);\n state.visual = undefined;\n return;\n }\n state.visual ??= makeVisual(source, group);\n const [ox, oy, oz] = ray.origin;\n const [dx, dy, dz] = ray.direction;\n // Turn −z (along which the line runs) to the ray: lookAt points +z from the target.\n matrix.lookAt(position.set(0, 0, 0), size.set(dx, dy, dz), up);\n matrix.setPosition(ox, oy, oz);\n state.visual.ray.matrix.copy(matrix);\n // A tracked hand points from its wrist; its joints show where it is, not a ray.\n state.visual.ray.visible = source.hand === undefined;\n if (state.visual.joints !== undefined && source.hand !== undefined) {\n placeJoints(state.visual.joints, source.hand, frame, space);\n }\n };\n\n return {\n frame: (frame, space) => {\n const present = new Set<XRInputSource>();\n for (const source of session.inputSources) {\n present.add(source);\n const state = trackedOf(source);\n const pose = frame.getPose(source.targetRaySpace, space);\n if (pose !== undefined && pose !== null) {\n const ray = rayOf(pose);\n input({ _tag: 'Aim', source: state.id, ray });\n show(source, state, ray, frame, space);\n }\n gamepad(source, state);\n if (state.hitTest !== undefined) {\n const result = frame.getHitTestResults(state.hitTest)[0]?.getPose(space);\n state.surface = result === undefined || result === null ? undefined : surfaceOf(result);\n }\n }\n for (const [source, state] of tracked) if (!present.has(source)) forget(source, state);\n },\n idOf: (source) => trackedOf(source).id,\n selected: (source) => {\n const state = tracked.get(source);\n if (state?.surface === undefined) return;\n input({ _tag: 'Surface', source: state.id, hand: handOf(source), ...state.surface });\n },\n sticks: () => {\n const axesOf = (hand: XrHand): readonly [number, number] => {\n for (const [source, state] of tracked) if (source.handedness === hand) return state.axes;\n return [0, 0];\n };\n return { left: axesOf('left'), right: axesOf('right') };\n },\n stop: () => {\n for (const [source, state] of tracked) forget(source, state);\n },\n };\n};\n",
22
+ "/**\n * What a session tracks for the scene's description, each frame: where every space a\n * group follows is (`group({ follow })`), the anchors the scene placed\n * (`xr({ anchors })`), and the planes the session detected (`xr({ planes: true })`).\n *\n * Behavioural reference: pmndrs/xr at `0e1acd8`: `space.ts` `createGetXRSpaceMatrix` (an\n * object on a space takes the space's pose in the reference space each frame, and none\n * while the frame has no pose for it), `anchor.ts` `requestXRAnchor` (`frame.createAnchor`\n * with a rigid transform in the origin's reference space), `store.ts` `updateSession` (the\n * frame's `detectedPlanes` and `detectedMeshes` read each frame, passed on when the set\n * changes), `plane.ts` (a plane is made again once it changes) and `mesh.ts` (a detected\n * mesh's geometry built from its `vertices` and `indices`, again when they change).\n *\n * @module\n */\nimport {\n type BodyPose,\n type Vec3,\n type Xr,\n type XrAnchor,\n type XrInput,\n type XrMesh,\n xrMeshGeometryId,\n type XrPlane,\n type XrSpace,\n} from '@opsydyn/effect-three';\nimport { BufferAttribute, BufferGeometry, Euler, Quaternion } from 'three';\n\n/** Places the scene's following groups where `locate` finds their spaces. */\nexport type Follow = (locate: (space: XrSpace) => BodyPose | undefined) => void;\n\n/** Lends a geometry to the scene's store under `id`; returns a function that withdraws it. */\nexport type LendGeometry = (id: string, geometry: BufferGeometry) => () => void;\n\nexport type XrSpaces = {\n /** Brings anchors and planes up to date in this frame, then places the following groups. */\n readonly frame: (frame: XRFrame, space: XRReferenceSpace) => void;\n /** Ends tracking: anchors are deleted, and every following group is hidden. */\n readonly stop: () => void;\n};\n\nconst turn = new Quaternion();\nconst angles = new Euler();\n\nconst poseOf = (pose: XRPose | null | undefined): BodyPose | undefined => {\n if (pose === null || pose === undefined) return undefined;\n const { position: p, orientation: o } = pose.transform;\n return { position: [p.x, p.y, p.z], quaternion: [o.x, o.y, o.z, o.w] };\n};\n\nconst sameVec3 = (a: Vec3, b: Vec3): boolean => a.every((value, i) => value === b[i]);\n\nconst sameAnchor = (a: XrAnchor, b: XrAnchor): boolean =>\n sameVec3(a.position, b.position) && sameVec3(a.rotation, b.rotation);\n\n/** An anchor's place as a rigid transform: its position, its Euler rotation turned. */\nconst transformOf = ({ position: [x, y, z], rotation }: XrAnchor): XRRigidTransform => {\n turn.setFromEuler(angles.fromArray([...rotation]));\n return new XRRigidTransform({ x, y, z }, { x: turn.x, y: turn.y, z: turn.z, w: turn.w });\n};\n\n/** A plane as the scene's data: its pose in the scene, its outline in its own space. */\nconst planeOf = (id: string, plane: XRPlane, pose: BodyPose): XrPlane => {\n angles.setFromQuaternion(turn.fromArray([...pose.quaternion]));\n return {\n id,\n orientation: plane.orientation,\n label: plane.semanticLabel ?? '',\n position: pose.position,\n rotation: [angles.x, angles.y, angles.z],\n polygon: plane.polygon.map((point): Vec3 => [point.x, point.y, point.z]),\n };\n};\n\n/** A plane's report in a few characters, to tell when one changes. */\nconst signatureOf = (plane: XrPlane): string =>\n [plane.id, plane.orientation, plane.label, ...plane.position, ...plane.rotation]\n .concat(plane.polygon.flat())\n .join(',');\n\n/** A detected mesh's report in a few characters, to tell when one changes. */\nconst meshSignatureOf = (mesh: XrMesh): string =>\n [mesh.id, mesh.label, ...mesh.position, ...mesh.rotation].join(',');\n\n/** A detected mesh's geometry, as pmndrs/xr's `updateXRMeshGeometry` builds it. */\nconst meshGeometryOf = (mesh: XRMesh): BufferGeometry => {\n const geometry = new BufferGeometry();\n geometry.setIndex(new BufferAttribute(mesh.indices, 1));\n geometry.setAttribute('position', new BufferAttribute(mesh.vertices, 3));\n geometry.computeVertexNormals();\n return geometry;\n};\n\n/** A detected mesh's lent geometry: what it was built from, and how to take it back. */\ntype Lent = {\n readonly vertices: Float32Array;\n readonly indices: Uint32Array;\n readonly geometry: BufferGeometry;\n readonly withdraw: () => void;\n};\n\nconst withdrawLent = (lent: Lent): void => {\n lent.withdraw();\n lent.geometry.dispose();\n};\n\ntype Made = { readonly spec: XrAnchor; anchor: XRAnchor | undefined };\n\n/**\n * Tracks the spaces `session` can locate for the description `settings()`, placing its\n * following groups with `follow` and reporting detected planes to `input`.\n */\nexport const trackSpaces = (\n session: XRSession,\n settings: () => Xr | null,\n follow: Follow,\n input: (input: XrInput) => void,\n lend: LendGeometry,\n): XrSpaces => {\n const anchors = new Map<string, Made>();\n const planeIds = new WeakMap<XRPlane, string>();\n const planes = new Map<string, XRPlane>();\n let nextPlane = 0;\n /** The planes last reported. */\n let reported: string | undefined;\n const meshIds = new WeakMap<XRMesh, string>();\n const meshes = new Map<string, XRMesh>();\n const lentMeshes = new Map<string, Lent>();\n let nextMesh = 0;\n let reportedMeshes: string | undefined;\n\n /** Anchors made, made again where they moved, and deleted where they went. */\n const syncAnchors = (frame: XRFrame, space: XRReferenceSpace): void => {\n const wanted = settings()?.anchors ?? [];\n const seen = new Set<string>();\n for (const spec of wanted) {\n seen.add(spec.id);\n const made = anchors.get(spec.id);\n if (made !== undefined && sameAnchor(made.spec, spec)) continue;\n made?.anchor?.delete();\n const entry: Made = { spec, anchor: undefined };\n anchors.set(spec.id, entry);\n // Refused where the session lacks anchors (they are optional): never found, then.\n void frame.createAnchor?.(transformOf(spec), space).then(\n (anchor) => {\n if (anchors.get(spec.id) === entry) entry.anchor = anchor;\n else anchor.delete();\n },\n () => undefined,\n );\n }\n for (const [id, made] of anchors) {\n if (seen.has(id)) continue;\n made.anchor?.delete();\n anchors.delete(id);\n }\n };\n\n /**\n * Reports the detected planes when what is reported changes: one found or lost,\n * reshaped, or seen from where the player has moved to. (Compared by content, not\n * `lastChangedTime`, which some runtimes move on every frame.)\n */\n const syncPlanes = (frame: XRFrame, space: XRReferenceSpace): void => {\n planes.clear();\n if (settings()?.planes !== true || frame.detectedPlanes === undefined) return;\n const found: Array<XrPlane> = [];\n for (const plane of frame.detectedPlanes) {\n const id = planeIds.get(plane) ?? `plane-${nextPlane++}`;\n planeIds.set(plane, id);\n planes.set(id, plane);\n const pose = poseOf(frame.getPose(plane.planeSpace, space));\n if (pose !== undefined) found.push(planeOf(id, plane, pose));\n }\n const now = found.map(signatureOf).join(' ');\n if (now === reported) return;\n reported = now;\n input({ _tag: 'Planes', planes: found });\n };\n\n /** Lends each detected mesh's geometry, again when its vertices change; takes back the lost. */\n const lendMesh = (id: string, mesh: XRMesh): void => {\n const lent = lentMeshes.get(id);\n // Runtimes hand over new arrays when a mesh changes (IWER moves `lastChangedTime` every\n // frame, keeping them): rebuild only then.\n if (lent?.vertices === mesh.vertices && lent.indices === mesh.indices) return;\n if (lent !== undefined) withdrawLent(lent);\n const geometry = meshGeometryOf(mesh);\n lentMeshes.set(id, {\n vertices: mesh.vertices,\n indices: mesh.indices,\n geometry,\n withdraw: lend(xrMeshGeometryId(id), geometry),\n });\n };\n\n /** Reports the detected meshes when what is reported changes, and lends their geometry. */\n const syncMeshes = (frame: XRFrame, space: XRReferenceSpace): void => {\n meshes.clear();\n if (settings()?.meshes === true && frame.detectedMeshes !== undefined) {\n const found: Array<XrMesh> = [];\n for (const mesh of frame.detectedMeshes) {\n const id = meshIds.get(mesh) ?? `mesh-${nextMesh++}`;\n meshIds.set(mesh, id);\n meshes.set(id, mesh);\n lendMesh(id, mesh);\n const pose = poseOf(frame.getPose(mesh.meshSpace, space));\n if (pose !== undefined) {\n angles.setFromQuaternion(turn.fromArray([...pose.quaternion]));\n found.push({\n id,\n label: mesh.semanticLabel ?? '',\n position: pose.position,\n rotation: [angles.x, angles.y, angles.z],\n });\n }\n }\n const now = found.map(meshSignatureOf).join(' ');\n if (now !== reportedMeshes) {\n reportedMeshes = now;\n input({ _tag: 'Meshes', meshes: found });\n }\n }\n for (const [id, lent] of lentMeshes) {\n if (meshes.has(id)) continue;\n withdrawLent(lent);\n lentMeshes.delete(id);\n }\n };\n\n const sourceOf = (hand: string, tracked: boolean): XRInputSource | undefined => {\n for (const source of session.inputSources) {\n if (source.handedness === hand && (source.hand !== undefined) === tracked) return source;\n }\n return undefined;\n };\n\n const locateIn =\n (frame: XRFrame, space: XRReferenceSpace) =>\n (target: XrSpace): BodyPose | undefined => {\n switch (target._tag) {\n case 'Head':\n return poseOf(frame.getViewerPose(space));\n case 'Joint': {\n const joint = sourceOf(target.hand, true)?.hand?.get(target.joint);\n return joint === undefined ? undefined : poseOf(frame.getJointPose?.(joint, space));\n }\n case 'Controller': {\n const source = sourceOf(target.hand, false);\n const located = target.space === 'grip' ? source?.gripSpace : source?.targetRaySpace;\n return located === undefined ? undefined : poseOf(frame.getPose(located, space));\n }\n case 'Anchor': {\n const anchor = anchors.get(target.id)?.anchor;\n return anchor === undefined\n ? undefined\n : poseOf(frame.getPose(anchor.anchorSpace, space));\n }\n case 'Plane': {\n const plane = planes.get(target.id);\n return plane === undefined ? undefined : poseOf(frame.getPose(plane.planeSpace, space));\n }\n case 'Mesh': {\n const mesh = meshes.get(target.id);\n return mesh === undefined ? undefined : poseOf(frame.getPose(mesh.meshSpace, space));\n }\n }\n };\n\n return {\n frame: (frame, space) => {\n syncAnchors(frame, space);\n syncPlanes(frame, space);\n syncMeshes(frame, space);\n follow(locateIn(frame, space));\n },\n stop: () => {\n for (const made of anchors.values()) made.anchor?.delete();\n anchors.clear();\n planes.clear();\n meshes.clear();\n for (const lent of lentMeshes.values()) withdrawLent(lent);\n lentMeshes.clear();\n follow(() => undefined);\n },\n };\n};\n",
23
+ "/**\n * The page's immersive sessions: which mounted scenes can be presented, and the one\n * session (WebXR allows one at a time) presenting a scene.\n *\n * @module\n */\nimport type { Xr, XrInput } from '@opsydyn/effect-three';\nimport type { Object3D } from 'three';\n\nimport { presentableRendererOf } from './renderSettings.ts';\nimport { type Presentation, present, sessionInit, type XrMode, type XrSystem } from './xr.ts';\nimport type { Follow, LendGeometry } from './xrSpaces.ts';\n\nexport type { XrMode } from './xr.ts';\n\n/** A mounted scene that can be presented. */\nexport type XrTarget = {\n readonly canvas: HTMLCanvasElement;\n /** The scene's current `xr` description; `null` while it does not ask to be presented. */\n readonly settings: () => Xr | null;\n /** Draws one frame now (the session calls it for each of its frames). */\n readonly draw: () => void;\n /** The scene's three.js root, where input sources are drawn while it presents. */\n readonly scene: Object3D;\n /** The scene's element: the DOM overlay's root, when the scene asks for one. */\n readonly element: Element;\n /** Places the groups that follow tracked spaces. */\n readonly follow: Follow;\n /** Lends a geometry to the scene's store, for detected meshes. */\n readonly lend: LendGeometry;\n /** Input from the session: aims, selects, sticks, buttons and surfaces. */\n readonly input: (input: XrInput) => void;\n /** The session began presenting this scene in `mode`, or (with `null`) ended. */\n readonly presenting: (mode: XrMode | null) => void;\n};\n\nexport type XrHub = {\n /** Makes a scene presentable; returns a function that withdraws it (ending its session). */\n readonly register: (target: XrTarget) => () => void;\n readonly supported: (mode: XrMode) => Promise<boolean>;\n /**\n * Requests a session and presents the first registered scene that describes `xr`.\n * Call from a user gesture's handling: browsers require one to start a session.\n */\n readonly enter: (mode: XrMode) => Promise<void>;\n readonly exit: () => Promise<void>;\n};\n\ntype Current = { readonly target: XrTarget; readonly presentation: Presentation };\n\n/** Creates the hub for a page; `system` is `navigator.xr` when the browser has WebXR. */\nexport const createXrHub = (system: () => XrSystem | undefined): XrHub => {\n const targets = new Set<XrTarget>();\n let current: Current | undefined;\n\n const presentable = (): { readonly target: XrTarget; readonly settings: Xr } | undefined => {\n for (const target of targets) {\n const settings = target.settings();\n if (settings !== null) return { target, settings };\n }\n return undefined;\n };\n\n const enter = async (mode: XrMode): Promise<void> => {\n if (current !== undefined) return;\n const xr = system();\n if (xr === undefined) throw new Error('WebXR is not available in this browser');\n const chosen = presentable();\n if (chosen === undefined) throw new Error('no mounted scene describes xr');\n const renderer = presentableRendererOf(chosen.target.canvas);\n if (renderer === undefined) throw new Error('the scene is not drawn by a three.js renderer');\n const session = await xr.requestSession(\n mode,\n sessionInit(chosen.settings, mode, chosen.target.element),\n );\n const { target } = chosen;\n // Each frame: follow the description (a new origin moves the player), then draw.\n const draw = (): void => {\n const settings = target.settings();\n if (settings !== null) current?.presentation.update(settings);\n target.draw();\n };\n const ended = (): void => {\n current = undefined;\n target.presenting(null);\n };\n const presentation = await present(\n renderer,\n session,\n chosen.settings,\n {\n scene: target.scene,\n draw,\n follow: target.follow,\n lend: target.lend,\n input: target.input,\n },\n ended,\n );\n current = { target, presentation };\n target.presenting(mode);\n };\n\n return {\n register: (target) => {\n targets.add(target);\n return () => {\n targets.delete(target);\n if (current?.target === target) void current.presentation.session.end();\n };\n },\n supported: async (mode) => (await system()?.isSessionSupported(mode)) ?? false,\n enter,\n exit: async () => {\n await current?.presentation.session.end();\n },\n };\n};\n",
24
+ "/**\n * The scene Mount (ADR-002): runs one scene for the lifetime of its element inside\n * Foldkit's runtime. Everything acquired here is released, in reverse order, when the\n * element unmounts.\n *\n * @module\n */\nimport {\n createGatedFrames,\n FrameSource,\n type GatedFrames,\n type PhysicsEngine,\n type PointerInput,\n ResourceRegistry,\n type SceneEvent,\n type SceneDescription,\n SceneRuntime,\n SceneSchema,\n} from '@opsydyn/effect-three';\nimport { type Cause, Data, Effect, Option, Queue, Schema, Stream } from 'effect';\nimport { Mount } from 'foldkit';\nimport type { ViewState } from 'foldkit/mount';\n\nimport {\n canvasIn,\n reconciledDispatch,\n removal,\n sceneErrorDispatch,\n sceneEventDispatch,\n} from './dom/canvas.ts';\nimport { applying, createLatch, type Latch, routedWhileOpen } from './dom/latch.ts';\nimport { containOverlays, createOverlayWriter, type OverlayWriter } from './dom/overlays.ts';\nimport { claimsGestures, listenForPointer, touchActionSync } from './dom/pointer.ts';\nimport { interceptProperty } from './dom/property.ts';\nimport { typedScene } from './dom/typedScenes.ts';\nimport { afterUpdate } from './dom/updates.ts';\nimport {\n measureViewport,\n observePixelRatio,\n observeReducedMotion,\n observeSize,\n observeVisibility,\n} from './dom/viewport.ts';\nimport { createFrameGate, type FrameGate, xrTarget } from './dom/xrTarget.ts';\nimport { SceneLifecycle } from './element.ts';\nimport type { Environment } from './environment.ts';\n\ntype SceneHandle = SceneRuntime.SceneHandle;\n\n/** Everything one mounted scene needs, gathered so helpers take one argument. */\ntype Mounted = {\n readonly environment: Environment;\n readonly element: Element;\n readonly canvas: HTMLCanvasElement;\n readonly overlays: OverlayWriter;\n readonly handle: SceneHandle;\n readonly live: Latch;\n readonly frames: GatedFrames;\n readonly gate: FrameGate;\n};\n\nconst decodeUnknownScene = Schema.decodeUnknownEffect(SceneSchema.SceneDescription);\n\n/** Typed scenes from `view` skip validation; anything else is Schema-decoded. */\nconst decodeScene = (value: unknown) =>\n Option.fromNullishOr(typedScene(value)).pipe(\n Option.match({ onNone: () => decodeUnknownScene(value), onSome: Effect.succeed }),\n );\n\nconst isLive = Schema.is(Schema.Literal('Live'));\n\nconst acquireCanvas = (element: Element) => {\n const create = Effect.sync(canvasIn(element));\n return Effect.acquireRelease(create, (canvas) => Effect.sync(removal(canvas)));\n};\n\nconst acquireSceneUpdates = () => {\n const create = Queue.sliding<unknown>(1);\n return Effect.acquireRelease(create, Queue.shutdown);\n};\n\nconst interception = (element: Element, updates: Queue.Queue<unknown>) => () =>\n interceptProperty(element, 'scene', (value) => Queue.offerUnsafe(updates, value));\n\nconst acquireInterception = (element: Element, updates: Queue.Queue<unknown>) => {\n const intercept = Effect.sync(interception(element, updates));\n return Effect.acquireRelease(intercept, (intercepted) => Effect.sync(intercepted.restore));\n};\n\nconst pointerListening =\n (\n canvas: HTMLElement,\n onInput: (input: PointerInput) => ReadonlyArray<SceneEvent>,\n claimsGestures: () => boolean,\n ) =>\n () =>\n listenForPointer(canvas, onInput, claimsGestures);\n\nconst acquirePointer = (canvas: HTMLElement, mounted: Mounted) => {\n const listen = Effect.sync(\n pointerListening(\n canvas,\n routedWhileOpen(mounted.live, mounted.handle.pointer),\n claimsGestures(mounted.handle.graph),\n ),\n );\n return Effect.acquireRelease(listen, Effect.sync);\n};\n\n/** Makes the scene presentable in the page's immersive sessions while it is mounted. */\nconst xrRegistration = (mounted: Mounted) => () =>\n mounted.environment.xrHub.register(\n xrTarget({\n element: mounted.element,\n canvas: mounted.canvas,\n live: mounted.live,\n gate: mounted.gate,\n settings: mounted.handle.graph.xr,\n draw: mounted.handle.drawNow,\n scene: mounted.handle.graph.scene,\n follow: mounted.handle.graph.follow,\n lend: mounted.handle.graph.store.lendGeometry,\n input: mounted.handle.xrInput,\n }),\n );\n\nconst acquireXrTarget = (mounted: Mounted) => {\n const register = Effect.sync(xrRegistration(mounted));\n return Effect.acquireRelease(register, Effect.sync);\n};\n\n/** A stream of values from a DOM observer that returns a disconnect function. */\nconst connectObserver =\n <A>(observe: (emit: (value: A) => void) => () => void) =>\n (queue: Queue.Queue<A, Cause.Done>) => {\n const connect = Effect.sync(applying(observe, (value: A) => Queue.offerUnsafe(queue, value)));\n return Effect.acquireRelease(connect, Effect.sync);\n };\n\nconst observed = <A>(observe: (emit: (value: A) => void) => () => void) =>\n Stream.callback<A>(connectObserver(observe));\n\nconst applyUpdate = (mounted: Mounted) => (value: unknown) => {\n const reportError = sceneErrorDispatch(mounted.element);\n const reportReconciled = afterUpdate(\n reconciledDispatch(mounted.element, mounted.environment.store),\n [touchActionSync(mounted.canvas, mounted.handle.graph), mounted.overlays.rewrite],\n );\n const decoded = decodeScene(value);\n const applied = decoded.pipe(\n Effect.flatMap(mounted.handle.update),\n Effect.flatMap((ops) => Effect.sync(reportReconciled(ops))),\n );\n return applied.pipe(\n Effect.catchTags({\n SchemaError: (error) =>\n Effect.sync(reportError({ _tag: 'MalformedScene', issue: error.message })),\n InvalidScene: ({ error }) => Effect.sync(reportError(error)),\n }),\n );\n};\n\nconst resize = (mounted: Mounted) => () =>\n mounted.handle.resize(\n measureViewport(\n mounted.element,\n mounted.environment.host.devicePixelRatio,\n mounted.environment.pixelRatio,\n ),\n );\n\nconst watchers = (\n mounted: Mounted,\n updates: Queue.Queue<unknown>,\n viewStateChanges: Stream.Stream<ViewState>,\n) => {\n const dispatchEvent = sceneEventDispatch(mounted.element, mounted.live);\n const sizes = observed<void>((emit) => observeSize(mounted.element, emit));\n const ratios = observed<void>((emit) => observePixelRatio(mounted.environment.host, emit));\n const visibility = observed<boolean>((emit) => observeVisibility(mounted.element, emit));\n const reducedMotion = observed<boolean>((emit) =>\n observeReducedMotion(mounted.environment.host, emit),\n );\n return [\n Stream.runForEach(Stream.fromQueue(updates), applyUpdate(mounted)),\n Stream.runForEach(mounted.handle.events, (event) => Effect.sync(dispatchEvent(event))),\n Stream.runForEach(viewStateChanges, (state) =>\n Effect.sync(applying(mounted.live.set, isLive(state))),\n ),\n Stream.runForEach(sizes, resize(mounted)),\n Stream.runForEach(ratios, resize(mounted)),\n Stream.runForEach(visibility, (visible) =>\n Effect.sync(applying(mounted.gate.setVisible, visible)),\n ),\n Stream.runForEach(reducedMotion, (reduced) => mounted.handle.setAnimating(!reduced)),\n ];\n};\n\n/** The physics engine could not be loaded (Rapier's WebAssembly, say). */\nclass PhysicsUnavailable extends Data.TaggedError('PhysicsUnavailable')<{\n readonly cause: unknown;\n}> {}\n\nconst sceneRuntimeFor =\n (\n environment: Environment,\n element: Element,\n canvas: HTMLCanvasElement,\n overlays: OverlayWriter,\n physics: PhysicsEngine | undefined,\n ) =>\n (scene: SceneDescription) => {\n const frames = createGatedFrames(environment.frames);\n const started = SceneRuntime.make({\n scene,\n renderer: environment.renderer(canvas),\n behaviours: environment.behaviours,\n physics,\n labels: environment.labels,\n placeOverlays: overlays.place,\n viewport: measureViewport(element, environment.host.devicePixelRatio, environment.pixelRatio),\n }).pipe(\n Effect.provideService(FrameSource.FrameSource, FrameSource.fromScheduler(frames)),\n Effect.provideService(ResourceRegistry.ResourceRegistry, { store: environment.store }),\n );\n return Effect.map(started, (handle) => ({ handle, frames }));\n };\n\nfunction* runScene(\n environment: Environment,\n element: Element,\n viewStateChanges: Stream.Stream<ViewState>,\n) {\n const canvas = yield* acquireCanvas(element);\n const updates = yield* acquireSceneUpdates();\n const intercepted = yield* acquireInterception(element, updates);\n const initial = yield* decodeScene(intercepted.initial);\n const overlays = createOverlayWriter(element);\n yield* Effect.sync(containOverlays(element));\n const physics = yield* Effect.tryPromise({\n try: () => environment.physics,\n catch: (cause) => new PhysicsUnavailable({ cause }),\n });\n const { handle, frames } = yield* sceneRuntimeFor(\n environment,\n element,\n canvas,\n overlays,\n physics,\n )(initial);\n const mounted: Mounted = {\n environment,\n element,\n canvas,\n overlays,\n handle,\n frames,\n gate: createFrameGate(frames),\n live: createLatch(true),\n };\n yield* acquirePointer(canvas, mounted);\n yield* acquireXrTarget(mounted);\n yield* Effect.sync(touchActionSync(canvas, handle.graph));\n yield* Effect.sync(reconciledDispatch(element, environment.store)(handle.startupOps));\n const forks = watchers(mounted, updates, viewStateChanges).map((watcher) =>\n Effect.forkScoped(watcher),\n );\n yield* Effect.all(forks, { concurrency: 'unbounded' });\n return SceneLifecycle.StartedScene();\n}\n\nconst failure = (reason: string) => SceneLifecycle.FailedScene({ reason });\n\nconst recoverStart = {\n SchemaError: (error: Schema.SchemaError) =>\n Effect.succeed(failure(`malformed scene: ${error.message}`)),\n InvalidScene: ({ error }: { readonly error: { readonly _tag: string } }) =>\n Effect.succeed(failure(`invalid scene: ${error._tag}`)),\n RendererUnavailable: () => Effect.succeed(failure('renderer unavailable')),\n PhysicsUnavailable: () => Effect.succeed(failure('physics unavailable')),\n};\n\ntype ExecuteInput = {\n readonly element: Element;\n readonly viewStateChanges: Stream.Stream<ViewState>;\n};\n\nconst mountScene =\n (environment: Environment) =>\n ({ element, viewStateChanges }: ExecuteInput) => {\n const scene = Effect.gen(() => runScene(environment, element, viewStateChanges));\n return scene.pipe(Effect.catchTags(recoverStart));\n };\n\n/**\n * Defines the scene Mount for an environment. Call once at the application entry point\n * and pass the result to `view` as `mount`.\n */\nexport const makeSceneMount = (environment: Environment) =>\n Mount.define('EffectThreeScene', {\n messages: [SceneLifecycle.StartedScene, SceneLifecycle.FailedScene],\n execute: mountScene(environment),\n });\n\nexport type SceneMount = ReturnType<typeof makeSceneMount>;\n",
25
+ "/**\n * The canvas a scene draws into, and DOM event dispatch from scene events.\n *\n * @module\n */\nimport type { Op, ResourceStore, SceneEvent } from '@opsydyn/effect-three';\n\nimport { domEventName, type SceneError } from '../element.ts';\nimport type { Latch } from './latch.ts';\nimport { summarise } from './reconciled.ts';\n\n/** Creates a canvas filling `host` and appends it. */\nexport const appendCanvas = (host: Element): HTMLCanvasElement => {\n const canvas = host.ownerDocument.createElement('canvas');\n canvas.style.display = 'block';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n // Pointer gestures go to the scene, not to page scrolling or zooming.\n canvas.style.touchAction = 'none';\n host.append(canvas);\n return canvas;\n};\n\n/** Dispatches a scene event as the element's typed DOM event. */\nexport const dispatchSceneEvent = (element: Element, event: SceneEvent): void => {\n element.dispatchEvent(new CustomEvent(domEventName[event._tag], { detail: event }));\n};\n\n/** Dispatches a rejected scene update as a `scene-error` event. */\nexport const dispatchSceneError = (element: Element, error: SceneError): void => {\n element.dispatchEvent(new CustomEvent('scene-error', { detail: { error } }));\n};\n\n/** Thunk builders, so Effect code can run DOM work with `Effect.sync(thunk)`. */\nexport const canvasIn = (host: Element) => () => appendCanvas(host);\nexport const removal = (node: ChildNode) => () => node.remove();\n/** Dispatches only while `live` is open: events are dropped during time-travel pause. */\nexport const sceneEventDispatch = (element: Element, live: Latch) => (event: SceneEvent) => () => {\n if (live.isOpen()) dispatchSceneEvent(element, event);\n};\nexport const sceneErrorDispatch = (element: Element) => (error: SceneError) => () =>\n dispatchSceneError(element, error);\n\n/**\n * Dispatches a `scene-reconciled` summary when an update changed something. Updates with\n * no operations dispatch nothing, so an app storing the summary in its Model can't loop.\n */\nexport const reconciledDispatch =\n (element: Element, store: ResourceStore) => (ops: ReadonlyArray<Op>) => () => {\n if (ops.length === 0) return;\n element.dispatchEvent(\n new CustomEvent('scene-reconciled', { detail: summarise(ops, store.stats()) }),\n );\n };\n",
26
+ "/**\n * A boolean read synchronously by DOM callbacks and written by Effect code.\n *\n * @module\n */\n\nexport type Latch = {\n readonly isOpen: () => boolean;\n readonly set: (open: boolean) => void;\n};\n\nexport const createLatch = (open: boolean): Latch => {\n let current = open;\n return {\n isOpen: () => current,\n set: (next) => {\n current = next;\n },\n };\n};\n\nconst nothing: ReadonlyArray<never> = [];\n\n/** Calls `route` only while `latch` is open, returning what it routed (nothing when shut). */\nexport const routedWhileOpen =\n <A, B>(latch: Latch, route: (value: A) => ReadonlyArray<B>) =>\n (value: A): ReadonlyArray<B> => {\n if (!latch.isOpen()) return nothing;\n return route(value);\n };\n\n/** A thunk calling `f(value)`, so Effect code can write `Effect.sync(applying(f, value))`. */\nexport const applying =\n <A, B>(f: (value: A) => B, value: A) =>\n (): B =>\n f(value);\n",
27
+ "/**\n * Moves the application's overlay HTML to where the scene placed each overlay, as Drei's\n * `Html` does every frame (`src/web/Html.tsx` at `bf6f4ad`): a translate to the point,\n * the distance scale, centring, the depth's z-index, and hiding when not visible.\n *\n * @module\n */\nimport type { OverlayPlacement } from '@opsydyn/effect-three';\n\n/** The data attribute naming the overlay an element's HTML belongs to. */\nexport const overlayData = {\n key: 'effect-three-overlay',\n attribute: 'data-effect-three-overlay',\n} as const;\n\nconst transformOf = (placement: OverlayPlacement): string =>\n `translate3d(${placement.x}px,${placement.y}px,0) scale(${placement.scale})${\n placement.center ? ' translate(-50%,-50%)' : ''\n }`;\n\n/** Writes one placement, touching only the style values that changed. */\nconst write = (element: HTMLElement, placement: OverlayPlacement): void => {\n const { style } = element;\n const transform = transformOf(placement);\n if (style.transform !== transform) style.transform = transform;\n const zIndex = String(placement.zIndex);\n if (style.zIndex !== zIndex) style.zIndex = zIndex;\n const visibility = placement.visible ? 'visible' : 'hidden';\n if (style.visibility !== visibility) style.visibility = visibility;\n};\n\nexport type OverlayWriter = {\n /** Takes the latest placements and writes them. */\n readonly place: (placements: ReadonlyArray<OverlayPlacement>) => void;\n /** Writes the latest placements again, for overlay elements the view has just made. */\n readonly rewrite: () => void;\n};\n\n/** Creates the writer for overlays rendered inside `host`. */\nexport const createOverlayWriter = (host: Element): OverlayWriter => {\n let latest: ReadonlyArray<OverlayPlacement> = [];\n const rewrite = (): void => {\n for (const placement of latest) {\n const element = host.querySelector(\n `[${overlayData.attribute}=\"${CSS.escape(placement.key)}\"]`,\n );\n if (element instanceof HTMLElement) write(element, placement);\n }\n };\n return {\n place: (placements) => {\n latest = placements;\n rewrite();\n },\n rewrite,\n };\n};\n\n/** Makes the scene element the overlays' containing block, unless it already is one. */\nexport const containOverlays = (host: Element) => (): void => {\n if (!(host instanceof HTMLElement)) return;\n if (getComputedStyle(host).position === 'static') host.style.position = 'relative';\n};\n",
28
+ "/**\n * Intercepts the property Foldkit's CustomElement factory sets on every render, so a\n * Mount can see new values without an update hook (ADR-002).\n *\n * @module\n */\n\nexport type PropertyInterception = {\n /** The value present when interception began (set by the first render). */\n readonly initial: unknown;\n /** Restores a plain data property holding the latest value. */\n readonly restore: () => void;\n};\n\n/** Calls `onSet` for every assignment to `element[key]`. */\nexport const interceptProperty = (\n element: object,\n key: string,\n onSet: (value: unknown) => void,\n): PropertyInterception => {\n const initial: unknown = Reflect.get(element, key);\n let current = initial;\n Object.defineProperty(element, key, {\n configurable: true,\n enumerable: true,\n get: () => current,\n set: (value: unknown) => {\n current = value;\n onSet(value);\n },\n });\n return {\n initial,\n restore: () => {\n Object.defineProperty(element, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: current,\n });\n },\n };\n};\n",
29
+ "/**\n * Scenes that reached the element through the typed `view` helper. TypeScript already\n * checked them against `SceneDescription`, so the Mount can skip the Schema decode (about\n * 0.6 ms per render for 1,000 meshes). Any other value assigned to the element's `scene`\n * property is still decoded.\n *\n * @module\n */\nimport type { SceneDescription } from '@opsydyn/effect-three';\n\nconst typed = new WeakMap<object, SceneDescription>();\n\n/** Records a compile-time-checked scene and returns it unchanged. */\nexport const markTyped = (scene: SceneDescription): SceneDescription => {\n typed.set(scene, scene);\n return scene;\n};\n\n/** The scene, if this exact value came through `markTyped`. */\nexport const typedScene = (value: unknown): SceneDescription | undefined =>\n typeof value === 'object' && value !== null ? typed.get(value) : undefined;\n",
30
+ "/**\n * What follows a scene update in the DOM.\n *\n * @module\n */\n\n/** After an update: report it, then run each follow-up step in order. */\nexport const afterUpdate =\n <A>(report: (value: A) => () => void, steps: ReadonlyArray<() => void>) =>\n (value: A) =>\n (): void => {\n report(value)();\n for (const step of steps) step();\n };\n",
31
+ "/**\n * A mounted scene as an immersive session target: its frames handed to the session while\n * it presents, and the session's start and end dispatched as `scene-xr` events.\n *\n * @module\n */\nimport type { GatedFrames, SceneEvent, Xr, XrInput } from '@opsydyn/effect-three';\nimport type { Object3D } from 'three';\n\nimport type { Latch } from './latch.ts';\nimport type { XrMode, XrTarget } from './xrHub.ts';\nimport type { Follow, LendGeometry } from './xrSpaces.ts';\n\n/**\n * The page's frames for a scene: open while it is visible and no session presents it\n * (a session brings its own frames, as React Three Fiber's loop stands aside).\n */\nexport const createFrameGate = (frames: GatedFrames) => {\n let visible = true;\n let presenting = false;\n const apply = (): void => frames.setOpen(visible && !presenting);\n return {\n setVisible: (next: boolean): void => {\n visible = next;\n apply();\n },\n setPresenting: (next: boolean): void => {\n presenting = next;\n apply();\n },\n };\n};\n\nexport type FrameGate = ReturnType<typeof createFrameGate>;\n\n/** The `scene-xr` event: the mode presenting, or `null` when the session ended. */\nexport const dispatchXrSession = (element: Element, live: Latch, mode: XrMode | null): void => {\n if (live.isOpen()) element.dispatchEvent(new CustomEvent('scene-xr', { detail: { mode } }));\n};\n\n/** A scene as a target for the page's immersive sessions. */\nexport const xrTarget = (scene: {\n readonly element: Element;\n readonly canvas: HTMLCanvasElement;\n readonly live: Latch;\n readonly gate: FrameGate;\n readonly settings: () => Xr | null;\n readonly draw: () => void;\n readonly scene: Object3D;\n readonly follow: Follow;\n readonly lend: LendGeometry;\n readonly input: (input: XrInput) => ReadonlyArray<SceneEvent>;\n}): XrTarget => ({\n canvas: scene.canvas,\n element: scene.element,\n follow: scene.follow,\n lend: scene.lend,\n settings: scene.settings,\n draw: scene.draw,\n scene: scene.scene,\n // Dropped while time travel pauses the scene, as pointer input is.\n input: (input) => {\n if (scene.live.isOpen()) scene.input(input);\n },\n presenting: (mode) => {\n scene.gate.setPresenting(mode !== null);\n // Back on the page's frames: draw once, as React Three Fiber invalidates on session end.\n if (mode === null) scene.draw();\n dispatchXrSession(scene.element, scene.live, mode);\n },\n});\n",
32
+ "/**\n * The scene view: one call from a Foldkit `view` renders a scene and maps its events to\n * the app's typed Messages. The scene is plain data derived from the Model.\n *\n * @module\n */\nimport type { SceneDescription, SceneSchema } from '@opsydyn/effect-three';\nimport { Array as Arr, Option } from 'effect';\nimport { Mount } from 'foldkit';\nimport type { Html, HtmlBuilder } from 'foldkit/html';\n\nimport { markTyped } from './dom/typedScenes.ts';\nimport {\n type ReconciledDetail,\n type SceneError,\n sceneElement,\n type SceneLifecycle,\n type XrSessionDetail,\n} from './element.ts';\nimport type { SceneMount } from './mount.ts';\nimport { overlayLayer, type OverlayView, withOverlays } from './overlayView.ts';\n\n/**\n * Where the pointer met an interactive mesh: key, world-space point, distance from the\n * camera, world-space face normal and texture coordinates.\n */\nexport type HitDetail = typeof SceneSchema.HitDetail.Type;\n\n/** Detail of click, double-click, pointer-down and pointer-up events: the hit and button. */\nexport type ButtonDetail = typeof SceneSchema.ButtonDetail.Type;\n\n/** Detail of wheel events: the hit and the wheel deltas. */\nexport type WheelDetail = typeof SceneSchema.WheelDetail.Type;\n\n/** Detail of a click that hit no interactive mesh. */\nexport type MissDetail = typeof SceneSchema.MissDetail.Type;\n\n/** Detail of drag events: the captured mesh, the button and the pointer's world-space ray. */\nexport type DragDetail = typeof SceneSchema.DragDetail.Type;\n\n/**\n * A drag, wheel or pinch on the canvas, when the scene claims gestures. Pass it to\n * `orbit` to move a camera kept in the Model.\n */\nexport type Gesture = typeof SceneSchema.Gesture.Type;\n\n/** Detail of collision events: the two bodies' keys, and whether they began touching. */\nexport type CollisionDetail = typeof SceneSchema.CollisionDetail.Type;\n\n/** Detail of contact force events: the two bodies, and how hard they pushed. */\nexport type ContactForceDetail = typeof SceneSchema.ContactForceDetail.Type;\n\n/** Detail of measured events: a node's world bounding box. */\nexport type MeasuredDetail = typeof SceneSchema.MeasuredDetail.Type;\n\n/** Detail of auto-rotated events: where a camera turning by itself got to. */\nexport type AutoRotatedDetail = typeof SceneSchema.AutoRotatedDetail.Type;\n\n/** Detail of label measured events: a label's laid-out size in its own units. */\nexport type LabelMeasuredDetail = typeof SceneSchema.LabelMeasuredDetail.Type;\n\n/** Detail of XR stick events: a thumbstick pushed past halfway in a direction, or let back. */\nexport type XrStickDetail = typeof SceneSchema.XrStickDetail.Type;\n\n/** Detail of XR button events: a controller button pressed or released. */\nexport type XrButtonDetail = typeof SceneSchema.XrButtonDetail.Type;\n\n/** Detail of XR moved events: where gliding left the player. */\nexport type XrMovedDetail = typeof SceneSchema.XrMovedDetail.Type;\n\n/** Detail of XR planes events: every plane the session detected, as it is now. */\nexport type XrPlanesDetail = typeof SceneSchema.XrPlanesDetail.Type;\n\n/** Detail of XR meshes events: every mesh the session detected, as it is now. */\nexport type XrMeshesDetail = typeof SceneSchema.XrMeshesDetail.Type;\n\n/** Detail of XR surface events: in AR, where a select met a real surface, and its normal. */\nexport type XrSurfaceDetail = typeof SceneSchema.XrSurfaceDetail.Type;\n\n/** Detail of performance changes: the measured fps and the new factor, 0 to 1. */\nexport type PerformanceDetail = typeof SceneSchema.PerformanceDetail.Type;\n\n/** Detail of pointer-leave events: the key that is no longer under the pointer. */\nexport type KeyDetail = typeof SceneSchema.KeyDetail.Type;\n\nexport type ViewConfig<Message> = {\n /** The scene to show. Derive it from the Model; unchanged scenes cost nothing. */\n readonly scene: SceneDescription;\n /** The Mount from `makeSceneMount`, created once at the entry point. */\n readonly mount: SceneMount;\n /** Maps the mount outcome (started or failed) into the app's Messages. */\n readonly onLifecycle: (message: SceneLifecycle) => Message;\n /** Pressed and released on the same mesh with the same button. */\n readonly onClick?: (detail: ButtonDetail) => Message;\n /** A double-click on the mesh that was last pressed. */\n readonly onDoubleClick?: (detail: ButtonDetail) => Message;\n /** A context menu on the mesh that was last pressed. The browser's menu stays shut. */\n readonly onContextMenu?: (detail: HitDetail) => Message;\n readonly onPointerDown?: (detail: ButtonDetail) => Message;\n readonly onPointerUp?: (detail: ButtonDetail) => Message;\n readonly onPointerEnter?: (detail: HitDetail) => Message;\n /** Every pointer movement over an interactive mesh. Can fire at the pointer's rate. */\n readonly onPointerMove?: (detail: HitDetail) => Message;\n readonly onPointerLeave?: (detail: KeyDetail) => Message;\n /** A click that hit no interactive mesh and moved at most two pixels: clear a selection. */\n readonly onPointerMissed?: (detail: MissDetail) => Message;\n /** The wheel over an interactive mesh. Page scrolling is not blocked. */\n readonly onWheel?: (detail: WheelDetail) => Message;\n /**\n * The pointer moved while pressed on a mesh, anywhere (the press captures it). Turn the\n * ray into a point with `pointOnPlane` to drag along a plane.\n */\n readonly onDrag?: (detail: DragDetail) => Message;\n /** A drag ended: released anywhere, or the pointer was cancelled. */\n readonly onDragEnd?: (detail: DragDetail) => Message;\n /**\n * A drag, wheel or pinch anywhere on the canvas, reported while the scene claims\n * gestures (`scene({ gestures: 'scene' })`). Apply it with `orbit` in `update`:\n * the camera stays in the Model.\n */\n readonly onGesture?: (gesture: Gesture) => Message;\n /**\n * A gesture is about to begin on a camera turning by itself (`autoRotate`): keep where\n * it got to with `autoRotated(model.camera, detail)` (a view's camera when `view` names\n * one), so the gesture goes on from where the camera was shown.\n */\n readonly onAutoRotated?: (detail: AutoRotatedDetail) => Message;\n /**\n * Two bodies began or stopped touching (react-three-rapier's `onCollisionEnter` and\n * `onCollisionExit`, for the whole scene). Needs `physics` and an engine.\n */\n readonly onCollision?: (detail: CollisionDetail) => Message;\n /**\n * Two bodies pushed on each other harder than a body's `contactForces` threshold during\n * a step (react-three-rapier's `onContactForce`). Rapier reports every such step, so\n * set the threshold high.\n */\n readonly onContactForce?: (detail: ContactForceDetail) => Message;\n /**\n * A node listed in the scene's `measure` has a new world bounding box (Drei's `Bounds`\n * measuring, as a Message): fit the camera to it with `fitCamera`.\n */\n readonly onMeasured?: (detail: MeasuredDetail) => Message;\n /**\n * A measured label (`scene({ measure })`) was laid out anew: its block and tight glyph\n * bounds in its own units, before its scale, to size what goes behind it.\n */\n readonly onLabelMeasured?: (detail: LabelMeasuredDetail) => Message;\n /**\n * An immersive session began presenting this scene (`mode`), or ended (`mode: null`),\n * whether the app or the user (through the headset) ended it.\n */\n readonly onXRSession?: (detail: XrSessionDetail) => Message;\n /**\n * In a session, a thumbstick pushed past halfway in a direction, or let back to the\n * centre: snap turn and teleport by changing the scene's `xr({ heading, origin })`, as\n * pmndrs/xr's controller locomotion does.\n */\n readonly onXRStick?: (detail: XrStickDetail) => Message;\n /** In a session, a controller button pressed or released (`xr-standard` mapping). */\n readonly onXRButton?: (detail: XrButtonDetail) => Message;\n /**\n * In AR with `xr({ hitTest: true })`, a select whose ray met a real surface: place\n * things there.\n */\n readonly onXRSurface?: (detail: XrSurfaceDetail) => Message;\n /**\n * Gliding with the sticks (`xr({ glide })`) stopped: keep where the player now stands\n * with `glided(model.xr, detail)`.\n */\n readonly onXRMoved?: (detail: XrMovedDetail) => Message;\n /**\n * With `xr({ planes: true })`, the detected planes changed (found, reshaped, lost, or\n * seen from where the player moved to): every plane, as it is now. Follow one with\n * `group({ follow: planeSpace(id) })`.\n */\n readonly onXRPlanes?: (detail: XrPlanesDetail) => Message;\n /**\n * With `xr({ meshes: true })`, the detected meshes changed: every mesh, as it is now.\n * Draw one as `mesh({ geometry: xrMesh(id), material })` inside a group that follows\n * `meshSpace(id)`: its geometry is lent to the scene, not sent.\n */\n readonly onXRMeshes?: (detail: XrMeshesDetail) => Message;\n /**\n * Frames ran persistently slow or fast, and the performance factor moved (0 to 1).\n * Store it in the Model and lower `render.resolution` with it, as Drei's\n * `PerformanceMonitor` and `AdaptiveDpr` do together.\n */\n readonly onPerformanceChange?: (detail: PerformanceDetail) => Message;\n /** A scene update was rejected; the scene keeps its last good state. */\n readonly onError?: (detail: { readonly error: SceneError }) => Message;\n /**\n * What each scene update did (operations by kind) and the GPU resources held afterwards.\n * Fires at startup and after every update that changed something, never for no-ops.\n */\n readonly onReconciled?: (detail: ReconciledDetail) => Message;\n /**\n * HTML at points in the scene, as Drei's `Html`: each `overlay` says where (a point,\n * perhaps on a node), `content` what. The scene moves the HTML there every frame it\n * draws; the content is ordinary view HTML, rendered from the Model.\n */\n readonly overlays?: ReadonlyArray<OverlayView>;\n readonly className?: string;\n};\n\nconst given = Option.fromNullishOr;\n\n/** Renders a scene element. Only the event handlers you pass are bound. */\nexport const view = <Message>(\n config: ViewConfig<NoInfer<Message>>,\n h: HtmlBuilder<Message>,\n): Html => {\n const element = sceneElement.withMessage(h);\n const optional = Arr.getSomes([\n Option.map(given(config.onClick), element.OnSceneClick),\n Option.map(given(config.onDoubleClick), element.OnSceneDoubleClick),\n Option.map(given(config.onContextMenu), element.OnSceneContextMenu),\n Option.map(given(config.onPointerDown), element.OnScenePointerDown),\n Option.map(given(config.onPointerUp), element.OnScenePointerUp),\n Option.map(given(config.onPointerEnter), element.OnScenePointerEnter),\n Option.map(given(config.onPointerMove), element.OnScenePointerMove),\n Option.map(given(config.onPointerLeave), element.OnScenePointerLeave),\n Option.map(given(config.onPointerMissed), element.OnScenePointerMissed),\n Option.map(given(config.onWheel), element.OnSceneWheel),\n Option.map(given(config.onDrag), element.OnSceneDrag),\n Option.map(given(config.onDragEnd), element.OnSceneDragEnd),\n Option.map(given(config.onCollision), element.OnSceneCollision),\n Option.map(given(config.onContactForce), element.OnSceneContactForce),\n Option.map(given(config.onMeasured), element.OnSceneMeasured),\n Option.map(given(config.onLabelMeasured), element.OnSceneLabelMeasured),\n Option.map(given(config.onXRSession), element.OnSceneXr),\n Option.map(given(config.onXRStick), element.OnSceneXrStick),\n Option.map(given(config.onXRButton), element.OnSceneXrButton),\n Option.map(given(config.onXRSurface), element.OnSceneXrSurface),\n Option.map(given(config.onXRMoved), element.OnSceneXrMoved),\n Option.map(given(config.onXRPlanes), element.OnSceneXrPlanes),\n Option.map(given(config.onXRMeshes), element.OnSceneXrMeshes),\n Option.map(given(config.onAutoRotated), element.OnSceneAutoRotated),\n Option.map(given(config.onGesture), (toMessage) =>\n element.OnSceneGesture((detail) => toMessage(detail.gesture)),\n ),\n Option.map(given(config.onPerformanceChange), element.OnScenePerformance),\n Option.map(given(config.onError), element.OnSceneError),\n Option.map(given(config.onReconciled), element.OnSceneReconciled),\n Option.map(given(config.className), h.Class),\n ]);\n const lifecycle = Mount.mapMessage(config.mount(), config.onLifecycle);\n const overlays = config.overlays ?? [];\n const scene = markTyped(withOverlays(config.scene, overlays));\n return element(\n [element.Scene(scene), h.OnMount(lifecycle), ...optional],\n overlayLayer(h, overlays),\n );\n};\n",
33
+ "/**\n * Overlay HTML in the scene view: the application's content for each overlay, in an\n * element the scene moves to the overlay's point every frame it draws.\n *\n * @module\n */\nimport type { Overlay, SceneDescription } from '@opsydyn/effect-three';\nimport type { Html, HtmlBuilder } from 'foldkit/html';\n\nimport { overlayData } from './dom/overlays.ts';\n\n/** HTML shown at a point in the scene, as Drei's `Html`: where, and what. */\nexport type OverlayView = {\n readonly overlay: Overlay;\n readonly content: Html;\n /**\n * `'auto'` (the default, as Drei): the HTML takes pointer events. `'none'`: they pass\n * through to the canvas, so the scene under a label stays pickable.\n */\n readonly pointerEvents?: 'auto' | 'none';\n};\n\n/** The scene with the overlays' points added, so the scene places them. */\nexport const withOverlays = (\n scene: SceneDescription,\n overlays: ReadonlyArray<OverlayView>,\n): SceneDescription =>\n overlays.length === 0\n ? scene\n : { ...scene, overlays: [...scene.overlays, ...overlays.map((view) => view.overlay)] };\n\n// The layer covers the canvas, lets events through, and keeps Drei's large z-indexes\n// inside the scene element rather than competing with the page.\nconst layerStyle = {\n position: 'absolute',\n inset: '0',\n overflow: 'hidden',\n pointerEvents: 'none',\n isolation: 'isolate',\n};\n\n/** The overlay layer, or nothing when there are no overlays. */\nexport const overlayLayer = <Message>(\n h: HtmlBuilder<Message>,\n overlays: ReadonlyArray<OverlayView>,\n): ReadonlyArray<Html> =>\n overlays.length === 0\n ? []\n : [\n h.div(\n [h.Style(layerStyle)],\n overlays.map(({ overlay, content, pointerEvents = 'auto' }) =>\n h.keyed('div')(\n overlay.key,\n [\n h.DataAttribute(overlayData.key, overlay.key),\n // Hidden until the scene first places it.\n h.Style({\n position: 'absolute',\n top: '0',\n left: '0',\n transformOrigin: '0 0',\n visibility: 'hidden',\n pointerEvents,\n }),\n ],\n [content],\n ),\n ),\n ),\n ];\n"
34
+ ],
35
+ "mappings": "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",
36
+ "debugId": "5EA0611BDE2E2BF164756E2164756E21",
37
+ "names": []
38
+ }
@@ -0,0 +1,14 @@
1
+ import { Mount } from 'foldkit';
2
+ import type { Environment } from './environment.ts';
3
+ /**
4
+ * Defines the scene Mount for an environment. Call once at the application entry point
5
+ * and pass the result to `view` as `mount`.
6
+ */
7
+ export declare const makeSceneMount: (environment: Environment) => Mount.MountDefinitionNoArgs<"EffectThreeScene", {
8
+ readonly _tag: "StartedScene";
9
+ } | {
10
+ readonly _tag: "FailedScene";
11
+ readonly reason: string;
12
+ }>;
13
+ export type SceneMount = ReturnType<typeof makeSceneMount>;
14
+ //# sourceMappingURL=mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAyBhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAyPpD;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAiB,WAAW;;;;;EAInD,CAAC;AAEL,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Overlay HTML in the scene view: the application's content for each overlay, in an
3
+ * element the scene moves to the overlay's point every frame it draws.
4
+ *
5
+ * @module
6
+ */
7
+ import type { Overlay, SceneDescription } from '@opsydyn/effect-three';
8
+ import type { Html, HtmlBuilder } from 'foldkit/html';
9
+ /** HTML shown at a point in the scene, as Drei's `Html`: where, and what. */
10
+ export type OverlayView = {
11
+ readonly overlay: Overlay;
12
+ readonly content: Html;
13
+ /**
14
+ * `'auto'` (the default, as Drei): the HTML takes pointer events. `'none'`: they pass
15
+ * through to the canvas, so the scene under a label stays pickable.
16
+ */
17
+ readonly pointerEvents?: 'auto' | 'none';
18
+ };
19
+ /** The scene with the overlays' points added, so the scene places them. */
20
+ export declare const withOverlays: (scene: SceneDescription, overlays: ReadonlyArray<OverlayView>) => SceneDescription;
21
+ /** The overlay layer, or nothing when there are no overlays. */
22
+ export declare const overlayLayer: <Message>(h: HtmlBuilder<Message>, overlays: ReadonlyArray<OverlayView>) => ReadonlyArray<Html>;
23
+ //# sourceMappingURL=overlayView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlayView.d.ts","sourceRoot":"","sources":["../src/overlayView.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAItD,6EAA6E;AAC7E,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1C,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,YAAY,UAChB,gBAAgB,YACb,aAAa,CAAC,WAAW,CAAC,KACnC,gBAGuF,CAAC;AAY3F,gEAAgE;AAChE,eAAO,MAAM,YAAY,GAAI,OAAO,KAC/B,WAAW,CAAC,OAAO,CAAC,YACb,aAAa,CAAC,WAAW,CAAC,KACnC,aAAa,CAAC,IAAI,CAyBd,CAAC"}