@oeave/bakery3 0.2.0 → 0.3.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 (46) hide show
  1. package/dist/bake/index.js +3 -3
  2. package/dist/catalog/index.js +1 -1
  3. package/dist/{chunk-KNUAOILG.js → chunk-3T3FJOSD.js} +4 -4
  4. package/dist/{chunk-KNUAOILG.js.map → chunk-3T3FJOSD.js.map} +1 -1
  5. package/dist/{chunk-6FYI6AJM.js → chunk-6FAMQZXB.js} +7 -7
  6. package/dist/{chunk-6FYI6AJM.js.map → chunk-6FAMQZXB.js.map} +1 -1
  7. package/dist/{chunk-QRCT5UGZ.js → chunk-CSSJRP5W.js} +9 -6
  8. package/dist/chunk-CSSJRP5W.js.map +1 -0
  9. package/dist/{chunk-APWUCEEB.js → chunk-EN4ROBYQ.js} +3 -3
  10. package/dist/{chunk-APWUCEEB.js.map → chunk-EN4ROBYQ.js.map} +1 -1
  11. package/dist/{chunk-JFYUDERE.js → chunk-NEK5TBEH.js} +2 -2
  12. package/dist/chunk-NEK5TBEH.js.map +1 -0
  13. package/dist/chunk-OPM2L63B.js +253 -0
  14. package/dist/chunk-OPM2L63B.js.map +1 -0
  15. package/dist/{chunk-UWBP7B54.js → chunk-R5IUPOWI.js} +3 -3
  16. package/dist/{chunk-UWBP7B54.js.map → chunk-R5IUPOWI.js.map} +1 -1
  17. package/dist/{chunk-HNMSWQU7.js → chunk-STRK4SZN.js} +3 -3
  18. package/dist/{chunk-HNMSWQU7.js.map → chunk-STRK4SZN.js.map} +1 -1
  19. package/dist/{chunk-Z7IYVH22.js → chunk-WLEFNUOH.js} +30 -279
  20. package/dist/chunk-WLEFNUOH.js.map +1 -0
  21. package/dist/{chunk-NXBAZGNB.js → chunk-X6GW43EX.js} +3 -3
  22. package/dist/{chunk-NXBAZGNB.js.map → chunk-X6GW43EX.js.map} +1 -1
  23. package/dist/devtools/index.js +7 -6
  24. package/dist/hotspots/index.d.ts +237 -31
  25. package/dist/hotspots/index.js +1013 -118
  26. package/dist/hotspots/index.js.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +7 -6
  29. package/dist/node/index.cjs +1 -1
  30. package/dist/node/index.cjs.map +1 -1
  31. package/dist/node/index.js +2 -2
  32. package/dist/presets/index.js +2 -2
  33. package/dist/r3f/index.js +9 -8
  34. package/dist/r3f/index.js.map +1 -1
  35. package/dist/{room-FS26KAPQ.js → room-BM7Z7NKG.js} +4 -4
  36. package/dist/{room-FS26KAPQ.js.map → room-BM7Z7NKG.js.map} +1 -1
  37. package/dist/session-NPVBESWA.js +9 -0
  38. package/dist/{session-VCIQEO26.js.map → session-NPVBESWA.js.map} +1 -1
  39. package/dist/tsl/index.d.ts +14 -1
  40. package/dist/tsl/index.js +8 -2
  41. package/dist/tsl/index.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunk-JFYUDERE.js.map +0 -1
  44. package/dist/chunk-QRCT5UGZ.js.map +0 -1
  45. package/dist/chunk-Z7IYVH22.js.map +0 -1
  46. package/dist/session-VCIQEO26.js +0 -9
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hotspots/hotspots.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The implementation behind `@oeave/bakery3/hotspots`. `index.ts` lists what\n * is public; the orb's parts and the brand color are here for the SDK's own\n * pointer handling and the monorepo's tools (`internal.ts`).\n */\n\nimport {\n BufferGeometry,\n Color,\n Group,\n Line,\n LineBasicMaterial,\n Mesh,\n MeshBasicMaterial,\n Raycaster,\n SphereGeometry,\n Vector2,\n Vector3,\n type Camera,\n type Object3D,\n type PerspectiveCamera,\n type OrthographicCamera,\n} from 'three';\n\nconst WORLD = new Vector3();\nconst CAMERA = new Vector3();\nconst FORWARD = new Vector3();\n\n/** `[x, y, z]`, in meters: the protocol's own vector shape. */\nexport type Vec3 = [number, number, number];\n\n/** The brand cyan; what an orb is unless told otherwise. */\nexport const HOTSPOT_COLOR = '#33d1ff';\n\n/** The orb's pieces: what the pointer handling raycasts and restyles. */\nexport type HotspotParts = {\n /** The solid core; what `attachHotspots` raycasts against. */\n readonly orb: Mesh<SphereGeometry, MeshBasicMaterial>;\n /** The translucent shell around the core, the part that pulses. */\n readonly halo: Mesh<SphereGeometry, MeshBasicMaterial>;\n /** Holds the orb and halo; `fit()` scales this, never the group. */\n readonly rig: Group;\n /** Present only when anchored: the tether from the surface point to the orb. */\n readonly line: Line<BufferGeometry, LineBasicMaterial> | undefined;\n /** Set by `attachHotspots` as the pointer moves on and off. */\n setHovered(on: boolean): void;\n};\n\nconst PARTS = new WeakMap<Hotspot, HotspotParts>();\n\n/** The parts of a hotspot `createHotspot` made. */\nexport function hotspotParts(hotspot: Hotspot): HotspotParts {\n const parts = PARTS.get(hotspot);\n if (!parts)\n throw new Error(\n '@oeave/bakery3/hotspots: that hotspot was not made by createHotspot().',\n );\n return parts;\n}\n\nexport type HotspotOptions = {\n /** Stable identity: it names the group and travels with `hotspotSpecOf`. */\n id: string;\n /** A caption for the app to show; the orb itself draws no text. */\n label?: string;\n /** Where the orb is, in the parent's space (world space without a parent). */\n position: Vec3 | Vector3;\n /**\n * A surface point on the model, in the same space as `position`. When given\n * the hotspot is anchored: a thin line is drawn from here to the orb.\n */\n anchor?: Vec3 | Vector3;\n /**\n * Attach to this object so the hotspot follows it. Without one the caller\n * adds `hotspot.object` to the scene themselves.\n */\n parent?: Object3D;\n /** CSS color of the orb, halo and line. Default the brand cyan, `#33d1ff`. */\n color?: string;\n /**\n * How the orb is sized. `screen` (default) keeps it the same size on screen\n * wherever it is: `size` is then a fraction of the viewport height, and\n * `attachHotspots` (or `fit()`) re-fits it every frame from the camera.\n * `world` is a fixed radius in meters, which shrinks with distance.\n */\n sizing?: 'screen' | 'world';\n /** Orb radius: a fraction of viewport height (`screen`, default 0.012) or meters (`world`, default 0.03). */\n size?: number;\n /** Whether the halo breathes. Default true. */\n pulse?: boolean;\n};\n\nexport type Hotspot = {\n readonly id: string;\n readonly label: string | undefined;\n /**\n * The group holding everything (the orb, and the tether when anchored),\n * placed at the orb; excluded from capture, named `bakery3-hotspot-<id>`.\n */\n readonly object: Group;\n /** Whether `setSelected(true)` is in effect. */\n readonly selected: boolean;\n /** Whether the cursor is over it; set by `attachHotspots`. */\n readonly hovered: boolean;\n setSelected(on: boolean): void;\n /** Advance the pulse; `seconds` is any monotonic clock. */\n update(seconds: number): void;\n /**\n * Scale the orb so it projects to its `size` for this camera. Called by\n * `attachHotspots.update()`; a host without pointer handling calls it\n * itself once per frame. No-op for `sizing: 'world'`.\n */\n fit(camera: Camera): void;\n /** Detach from its parent and free every geometry and material. */\n dispose(): void;\n};\n\n/** A hotspot as data, in world space: what to keep with a capture. */\nexport type HotspotSpec = {\n id: string;\n label?: string;\n position: Vec3;\n anchor?: Vec3;\n};\n\n// Rest, hovered and selected looks, as the ratios a 0.03 m orb was tuned at.\nconst HALO_SCALE = 1.7;\nconst HALO_PULSE = 0.3;\nconst HALO_OPACITY = 0.28;\nconst LINE_OPACITY = 0.6;\nconst PULSE_HZ = 0.7;\nconst WHITE = new Color('#ffffff');\n\nfunction toVector3(value: Vec3 | Vector3): Vector3 {\n return value instanceof Vector3\n ? value.clone()\n : new Vector3(value[0], value[1], value[2]);\n}\n\nfunction vec3Of(vector: Vector3): Vec3 {\n return [vector.x, vector.y, vector.z];\n}\n\nexport function createHotspot(options: HotspotOptions): Hotspot {\n const {\n id,\n label,\n parent,\n color = HOTSPOT_COLOR,\n sizing = 'screen',\n size = sizing === 'screen' ? 0.012 : 0.03,\n pulse = true,\n } = options;\n // Screen-sized orbs are built at unit radius and scaled by `fit()`; the\n // scale lives on a rig of its own so the tether, which is drawn in the\n // group's space, never scales with it.\n const radius = sizing === 'screen' ? 1 : size;\n const rig = new Group();\n rig.name = 'rig';\n const position = toVector3(options.position);\n const anchor = options.anchor ? toVector3(options.anchor) : undefined;\n\n const object = new Group();\n object.name = `bakery3-hotspot-${id}`;\n // The exclusion the capture honors. It covers the whole subtree, so the\n // line and halo need no mark of their own.\n object.userData.bakery3 = { exclude: true };\n object.position.copy(position);\n\n // Unlit on purpose: an orb that picks up the scene's lighting turns into a\n // gray ball in shadow and a white blob in sun. `toneMapped: false` keeps the\n // brand cyan the brand cyan under ACES too.\n const orb = new Mesh(\n new SphereGeometry(radius, 24, 16),\n new MeshBasicMaterial({ color, toneMapped: false, depthTest: true }),\n );\n orb.name = 'orb';\n rig.add(orb);\n\n const halo = new Mesh(\n new SphereGeometry(radius, 24, 16),\n new MeshBasicMaterial({\n color,\n toneMapped: false,\n transparent: true,\n opacity: HALO_OPACITY,\n depthWrite: false,\n }),\n );\n halo.name = 'halo';\n halo.scale.setScalar(HALO_SCALE);\n // After the opaque core so its translucency composites over it.\n halo.renderOrder = 1;\n rig.add(halo);\n if (sizing === 'screen') rig.scale.setScalar(size); // a sane size before the first fit\n object.add(rig);\n\n let line: Line<BufferGeometry, LineBasicMaterial> | undefined;\n if (anchor) {\n // The group sits at the orb, so the anchor is expressed relative to it.\n // The group is never rotated or scaled by this module, which is what\n // makes a plain subtraction the right transform.\n const geometry = new BufferGeometry().setFromPoints([\n anchor.clone().sub(position),\n new Vector3(0, 0, 0),\n ]);\n line = new Line(\n geometry,\n new LineBasicMaterial({\n color,\n toneMapped: false,\n transparent: true,\n opacity: LINE_OPACITY,\n depthWrite: false,\n }),\n );\n line.name = 'tether';\n object.add(line);\n }\n\n parent?.add(object);\n\n let selected = false;\n let hovered = false;\n let disposed = false;\n\n const applyLook = (): void => {\n // Selected: a brighter, larger core with the halo drawn back, so the orb\n // becomes a filled dot. Hovered: just a touch bigger, the halo stronger.\n const emphasis = selected ? 1.25 : hovered ? 1.1 : 1;\n orb.scale.setScalar(emphasis);\n orb.material.color.set(color);\n if (selected) orb.material.color.lerp(WHITE, 0.5);\n halo.material.opacity = selected\n ? HALO_OPACITY * 0.6\n : hovered\n ? HALO_OPACITY * 1.6\n : HALO_OPACITY;\n if (line) line.material.opacity = selected || hovered ? 1 : LINE_OPACITY;\n };\n\n const hotspot: Hotspot = {\n id,\n label,\n object,\n get selected() {\n return selected;\n },\n get hovered() {\n return hovered;\n },\n setSelected(on) {\n if (selected === on) return;\n selected = on;\n applyLook();\n },\n fit(camera) {\n if (disposed || sizing !== 'screen') return;\n const perspective =\n (camera as PerspectiveCamera).isPerspectiveCamera === true;\n const ortho =\n (camera as OrthographicCamera).isOrthographicCamera === true;\n if (!perspective && !ortho) return;\n object.getWorldPosition(WORLD);\n camera.getWorldPosition(CAMERA);\n let visibleHeight: number;\n if (perspective) {\n const cam = camera as PerspectiveCamera;\n // Depth along the view axis, not the straight-line distance: an orb\n // at the frame's edge is as far \"into\" the picture as one dead center.\n camera.getWorldDirection(FORWARD);\n const depth = Math.max(1e-3, WORLD.sub(CAMERA).dot(FORWARD));\n visibleHeight = 2 * depth * Math.tan((cam.fov * Math.PI) / 360);\n } else {\n const cam = camera as OrthographicCamera;\n visibleHeight = (cam.top - cam.bottom) / cam.zoom;\n }\n rig.scale.setScalar(Math.max(1e-6, size * visibleHeight));\n },\n update(seconds) {\n if (disposed || !pulse) return;\n // A slow breath: never so fast it reads as an alarm.\n const phase = 0.5 + 0.5 * Math.sin(seconds * Math.PI * 2 * PULSE_HZ);\n const rest = selected ? HALO_SCALE * 0.8 : HALO_SCALE;\n halo.scale.setScalar(rest + HALO_PULSE * phase * (selected ? 0.5 : 1));\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n object.removeFromParent();\n orb.geometry.dispose();\n orb.material.dispose();\n halo.geometry.dispose();\n halo.material.dispose();\n line?.geometry.dispose();\n line?.material.dispose();\n },\n };\n PARTS.set(hotspot, {\n orb,\n halo,\n rig,\n line,\n setHovered(on) {\n if (hovered === on) return;\n hovered = on;\n applyLook();\n },\n });\n return hotspot;\n}\n\n/**\n * A hotspot as plain data, in world space, ready for `productState`.\n *\n * Reads through the parents so a hotspot riding on a product that has been\n * moved reports where it actually is, not where it was authored.\n */\nexport function hotspotSpecOf(hotspot: Hotspot): HotspotSpec {\n const { object } = hotspot;\n object.updateWorldMatrix(true, false);\n const spec: HotspotSpec = {\n id: hotspot.id,\n position: vec3Of(object.getWorldPosition(new Vector3())),\n };\n if (hotspot.label !== undefined) spec.label = hotspot.label;\n const { line } = hotspotParts(hotspot);\n if (line) {\n const local = new Vector3().fromBufferAttribute(\n line.geometry.getAttribute('position'),\n 0,\n );\n spec.anchor = vec3Of(object.localToWorld(local));\n }\n return spec;\n}\n\nexport type AttachHotspotsOptions = {\n hotspots: Hotspot[];\n camera: Camera;\n /** The renderer's canvas, or whatever element receives the pointer. */\n domElement: HTMLElement;\n /** Selection changed: the hotspot now selected, or null when cleared. */\n onSelect?(hotspot: Hotspot | null): void;\n /** The pointer moved onto (or off) a hotspot. */\n onHover?(hotspot: Hotspot | null): void;\n};\n\nexport type AttachedHotspots = {\n /** Advance every hotspot's pulse. Call once per frame. */\n update(seconds: number): void;\n /** The hotspot currently selected, if any. */\n readonly selected: Hotspot | null;\n /** Select (or clear) programmatically; fires `onSelect` like a click would. */\n select(hotspot: Hotspot | null): void;\n /** Remove the listeners. Does not dispose the hotspots. */\n dispose(): void;\n};\n\n/** How far a pointer may travel between down and up and still be a click, in\n * CSS pixels: an orbit drag that happens to end on an orb is not a pick. */\nconst CLICK_SLOP_PX = 6;\n\n/**\n * Wire hover and click for a set of hotspots on one canvas.\n *\n * Raycasts the orbs (core and halo, so the target is a little generous) from\n * the pointer through `camera`; sets `cursor: pointer` over one; toggles\n * selection on click, one at a time. Nothing here is a render loop: call\n * `update()` from yours.\n */\nexport function attachHotspots(\n options: AttachHotspotsOptions,\n): AttachedHotspots {\n const { hotspots, camera, domElement, onSelect, onHover } = options;\n const raycaster = new Raycaster();\n const pointer = new Vector2();\n const targets = new Map<Object3D, Hotspot>();\n for (const hotspot of hotspots) {\n const { orb, halo } = hotspotParts(hotspot);\n targets.set(orb, hotspot);\n targets.set(halo, hotspot);\n }\n\n let selected: Hotspot | null = null;\n let hovered: Hotspot | null = null;\n let downAt: { x: number; y: number } | null = null;\n let previousCursor: string | null = null;\n\n const pick = (event: PointerEvent): Hotspot | null => {\n const rect = domElement.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n pointer.set(\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\n -((event.clientY - rect.top) / rect.height) * 2 + 1,\n );\n raycaster.setFromCamera(pointer, camera);\n const hits = raycaster.intersectObjects([...targets.keys()], false);\n for (const hit of hits) {\n const hotspot = targets.get(hit.object);\n if (hotspot && hotspot.object.visible) return hotspot;\n }\n return null;\n };\n\n const setHovered = (next: Hotspot | null): void => {\n if (next === hovered) return;\n if (hovered) hotspotParts(hovered).setHovered(false);\n hovered = next;\n if (hovered) hotspotParts(hovered).setHovered(true);\n if (hovered) {\n if (previousCursor === null) previousCursor = domElement.style.cursor;\n domElement.style.cursor = 'pointer';\n } else if (previousCursor !== null) {\n domElement.style.cursor = previousCursor;\n previousCursor = null;\n }\n onHover?.(hovered);\n };\n\n const select = (next: Hotspot | null): void => {\n if (next === selected) return;\n selected?.setSelected(false);\n selected = next;\n selected?.setSelected(true);\n onSelect?.(selected);\n };\n\n const onPointerMove = (event: PointerEvent): void => setHovered(pick(event));\n const onPointerLeave = (): void => setHovered(null);\n const onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0) return;\n downAt = { x: event.clientX, y: event.clientY };\n };\n const onPointerUp = (event: PointerEvent): void => {\n if (!downAt || event.button !== 0) return;\n const moved = Math.hypot(\n event.clientX - downAt.x,\n event.clientY - downAt.y,\n );\n downAt = null;\n if (moved > CLICK_SLOP_PX) return;\n const hit = pick(event);\n // Clicking the selected orb clears it; clicking empty space clears too.\n select(hit === selected ? null : hit);\n };\n\n // Guarded so a hotspot set can be built where there is no DOM (a test, a\n // server) and simply never receive a pointer.\n const listens = typeof domElement?.addEventListener === 'function';\n if (listens) {\n domElement.addEventListener('pointermove', onPointerMove);\n domElement.addEventListener('pointerleave', onPointerLeave);\n domElement.addEventListener('pointerdown', onPointerDown);\n domElement.addEventListener('pointerup', onPointerUp);\n }\n\n return {\n get selected() {\n return selected;\n },\n select,\n update(seconds) {\n for (const hotspot of hotspots) {\n hotspot.fit(camera);\n hotspot.update(seconds);\n }\n },\n dispose() {\n if (listens) {\n domElement.removeEventListener('pointermove', onPointerMove);\n domElement.removeEventListener('pointerleave', onPointerLeave);\n domElement.removeEventListener('pointerdown', onPointerDown);\n domElement.removeEventListener('pointerup', onPointerUp);\n }\n setHovered(null);\n hovered = null;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/hotspots/label.ts","../../src/hotspots/hotspots.ts"],"names":["step","Color","strength"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * A hotspot's label, drawn by the browser into pixels.\n *\n * The renderer has none of the page's fonts, and shipping a font file, its\n * license and a text engine to match the browser's line metrics would still\n * not be the browser's text. So the label is rasterized here, with whatever\n * font the page has loaded, into an 8-bit texture: the one kind of runtime\n * texture the capture re-encodes to PNG inside the GLB. The renderer traces\n * the very pixels the viewport shows.\n *\n * The pill's rounded shape is geometry, not alpha: the texture is opaque, so\n * an animated `opacity` (the fade) is the only alpha the label has, and the\n * renderer keys exactly that.\n */\n\nimport {\n BufferGeometry,\n Color,\n DataTexture,\n LinearFilter,\n LinearMipmapLinearFilter,\n RGBAFormat,\n SRGBColorSpace,\n Shape,\n ShapeGeometry,\n UnsignedByteType,\n} from 'three';\n\n/** The font a label is set in unless told otherwise: the platform's UI face. */\nexport const LABEL_FONT =\n '600 40px system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif';\n\nexport type LabelLook = {\n text: string;\n /** A CSS font. Its pixel size is the texture's resolution. */\n font: string;\n color: string;\n background: string;\n};\n\nexport type RasterLabel = {\n texture: DataTexture;\n /** Width over height of the pill. */\n aspect: number;\n};\n\ntype Context = OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\nfunction context2d(width: number, height: number): Context | null {\n // Anything short of a real 2D canvas (a server, a test's stub DOM) gets\n // the plain fallback rather than an exception at createHotspot().\n const usable = (ctx: unknown): ctx is Context =>\n !!ctx &&\n typeof (ctx as Context).measureText === 'function' &&\n typeof (ctx as Context).getImageData === 'function';\n try {\n if (typeof OffscreenCanvas !== 'undefined') {\n const ctx = new OffscreenCanvas(width, height).getContext('2d');\n if (usable(ctx)) return ctx;\n }\n if (typeof document !== 'undefined') {\n const canvas = document.createElement('canvas');\n if (typeof canvas?.getContext !== 'function') return null;\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (usable(ctx)) return ctx;\n }\n } catch {\n // Fall through to the fallback.\n }\n return null;\n}\n\nfunction pixelSize(font: string): number {\n const match = /(\\d+(?:\\.\\d+)?)px/.exec(font);\n return match ? Number(match[1]) : 40;\n}\n\nfunction texture(data: Uint8Array, width: number, height: number): DataTexture {\n const map = new DataTexture(\n data,\n width,\n height,\n RGBAFormat,\n UnsignedByteType,\n );\n map.colorSpace = SRGBColorSpace;\n map.magFilter = LinearFilter;\n map.minFilter = LinearMipmapLinearFilter;\n map.generateMipmaps = true;\n map.anisotropy = 4;\n map.needsUpdate = true;\n return map;\n}\n\n/** The background alone, at a typical label's proportions: no canvas to draw on. */\nfunction plain(look: LabelLook): RasterLabel {\n // sRGB bytes, as a canvas would have drawn them; `.r` is linear.\n const hex = new Color(look.background).getHex();\n const rgba = [(hex >> 16) & 255, (hex >> 8) & 255, hex & 255];\n const data = new Uint8Array(12);\n for (let i = 0; i < 3; i++)\n data.set([rgba[0]!, rgba[1]!, rgba[2]!, 255], i * 4);\n return { texture: texture(data, 3, 1), aspect: 3 };\n}\n\n/**\n * The label as a texture. Without a canvas (a test, a server) it is the\n * background alone, at a typical label's proportions.\n */\nexport function rasterizeLabel(look: LabelLook): RasterLabel {\n const size = pixelSize(look.font);\n const height = Math.max(8, Math.round(size * 1.7));\n const pad = Math.round(size * 0.62);\n const probe = context2d(1, 1);\n if (!probe) return plain(look);\n probe.font = look.font;\n const width = Math.max(\n height,\n Math.ceil(probe.measureText(look.text).width + pad * 2),\n );\n const ctx = context2d(width, height);\n if (!ctx) return plain(look);\n ctx.fillStyle = look.background;\n ctx.fillRect(0, 0, width, height);\n ctx.font = look.font;\n ctx.textBaseline = 'middle';\n ctx.fillStyle = look.color;\n // A hair below the middle: 'middle' centres the em box, which sits high\n // for text with no descenders.\n ctx.fillText(look.text, pad, height / 2 + size * 0.04);\n\n // Canvas rows run top down; a texture's first row is v = 0, the bottom.\n const pixels = ctx.getImageData(0, 0, width, height).data;\n const data = new Uint8Array(width * height * 4);\n const row = width * 4;\n for (let y = 0; y < height; y++)\n data.set(\n pixels.subarray((height - 1 - y) * row, (height - y) * row),\n y * row,\n );\n return { texture: texture(data, width, height), aspect: width / height };\n}\n\n/**\n * A pill one unit tall and `aspect` wide, its origin at the middle of its\n * left end, with UVs that lay the label's texture across it.\n */\nexport function pillGeometry(aspect: number): BufferGeometry {\n const width = Math.max(1, aspect);\n const r = 0.5;\n const shape = new Shape();\n shape.moveTo(r, -0.5);\n shape.lineTo(width - r, -0.5);\n shape.absarc(width - r, 0, r, -Math.PI / 2, Math.PI / 2, false);\n shape.lineTo(r, 0.5);\n shape.absarc(r, 0, r, Math.PI / 2, (3 * Math.PI) / 2, false);\n const geometry = new ShapeGeometry(shape, 16);\n const position = geometry.getAttribute('position');\n const uv = geometry.getAttribute('uv');\n for (let i = 0; i < position.count; i++)\n uv.setXY(i, position.getX(i) / width, position.getY(i) + 0.5);\n uv.needsUpdate = true;\n return geometry;\n}\n\n/**\n * Which side of the orb a label goes, given where it is on screen.\n *\n * Right unless that runs off the right edge and the left does not; back to\n * the right once it fits there with room to spare, so a label near the\n * middle of the frame does not flip back and forth. A label too long for\n * either side goes where there is more room. `x` is the orb's\n * centre and `reach` how far the label extends from it, both in normalized\n * device coordinates (-1 to 1 across the frame).\n */\nexport function labelSideFor(\n current: 'left' | 'right',\n x: number,\n reach: number,\n): 'left' | 'right' {\n const margin = 0.04;\n const fitsRight = x + reach < 1 - margin;\n const fitsLeft = x - reach > -1 + margin;\n // Too long for either side: the side with more room, a little past the\n // middle before it changes, and some of it will be cut.\n if (!fitsRight && !fitsLeft)\n return current === 'right'\n ? x > 0.1\n ? 'left'\n : 'right'\n : x < -0.1\n ? 'right'\n : 'left';\n if (current === 'right') return fitsRight ? 'right' : 'left';\n return x + reach < 1 - margin - 0.12 || !fitsLeft ? 'right' : 'left';\n}\n","/**\n * The implementation behind `@oeave/bakery3/hotspots`. `index.ts` lists what\n * is public; the parts, the pose and the brand color are here for the SDK's\n * own pointer handling and the monorepo's tools (`internal.ts`).\n *\n * One function decides how a hotspot looks: `poseOf` turns its state (how far\n * it has appeared, how far it is open, the hover, the label, the pulse) into\n * numbers on its parts. The live hotspot applies them every frame;\n * `animateHotspots` samples them at every frame of a timeline and writes them\n * as tracks, which is how the render plays the same motion the viewport\n * showed. There is no second animation system to drift from the first.\n */\n\nimport {\n Color,\n CylinderGeometry,\n Euler,\n Group,\n Matrix3,\n Matrix4,\n Mesh,\n MeshPhysicalMaterial,\n MeshStandardMaterial,\n PointLight,\n Quaternion,\n Raycaster,\n SphereGeometry,\n TorusGeometry,\n Vector2,\n Vector3,\n type BufferGeometry,\n type Camera,\n type DataTexture,\n type Intersection,\n type Material,\n type Object3D,\n type OrthographicCamera,\n type PerspectiveCamera,\n} from 'three';\nimport { OBJECT_PROPERTIES } from '../timeline/properties.js';\nimport type { Timeline, Track } from '../timeline/timeline.js';\nimport {\n LABEL_FONT,\n labelSideFor,\n pillGeometry,\n rasterizeLabel,\n} from './label.js';\n\nconst WORLD = new Vector3();\nconst CAMERA = new Vector3();\nconst FORWARD = new Vector3();\nconst SCALE = new Vector3();\nconst RIGHT = new Vector3();\nconst EDGE = new Vector3();\nconst ORIENT = new Quaternion();\nconst VIEW = new Quaternion();\nconst EULER = new Euler();\nconst UP = new Vector3(0, 1, 0);\nconst FRONT = new Vector3(0, 0, 1);\n\n/** `[x, y, z]`, in meters: the protocol's own vector shape. */\nexport type Vec3 = [number, number, number];\n\n/** The brand cyan; what a hotspot is unless told otherwise. */\nexport const HOTSPOT_COLOR = '#33d1ff';\n\n/**\n * Where a hotspot is headed. `hidden` is not there at all, `closed` is the\n * resting dot, `open` is the dot as it looks while its panel is showing.\n */\nexport type HotspotState = 'hidden' | 'closed' | 'open';\n\n/** Where a hotspot is now, including the moves between states. */\nexport type HotspotPhase =\n 'hidden' | 'entering' | 'closed' | 'opening' | 'open' | 'closing' | 'leaving';\n\n/**\n * The built-in looks.\n *\n * - `orb`: a glowing core in a soft halo that breathes.\n * - `ring`: a small glowing core inside a ring.\n * - `glass`: a clear glass bead with a glowing core inside.\n * - `solid`: a glossy colored bead that barely glows.\n */\nexport type HotspotPreset = 'orb' | 'ring' | 'glass' | 'solid';\n\n/** The meshes a hotspot can be made of; which exist depends on the preset. */\nexport type HotspotPartName =\n 'core' | 'halo' | 'ring' | 'shell' | 'tether' | 'dot';\n\n/**\n * When the label beside a hotspot shows.\n *\n * - `never` (default): the hotspot draws no text.\n * - `always`: whenever the hotspot is there.\n * - `open`: while it is open.\n * - `hover`: while the pointer is over it, and while it is open. A timeline\n * hovers it with a `hover` event.\n */\nexport type HotspotLabelShow = 'never' | 'always' | 'open' | 'hover';\n\n/** Which side of the orb the label is on. `auto` moves it off a screen edge. */\nexport type HotspotLabelSide = 'auto' | 'left' | 'right';\n\n/**\n * A material of your own for a part, or a function asked once per part that\n * returns one (or `undefined` to keep the preset's). A node material with an\n * `emissiveNode` should multiply it by `bakeryEmissiveIntensity()` from\n * `@oeave/bakery3/tsl`, so the glow the state animates reaches it in the\n * viewport as it does in the render.\n */\nexport type HotspotMaterial =\n | Material\n | ((part: { name: HotspotPartName; color: Color }) => Material | undefined);\n\n/** The parts a hotspot is made of. */\nexport type HotspotParts = {\n /** The glowing center; what `attachHotspots` raycasts against. */\n readonly core: Mesh;\n /** The same mesh as `core`, under its old name. */\n readonly orb: Mesh;\n /** The breathing shell round an `orb`. */\n readonly halo: Mesh | undefined;\n /** The ring of a `ring`. */\n readonly ring: Mesh | undefined;\n /** The glass of a `glass`. */\n readonly shell: Mesh | undefined;\n /** The label, when `showLabel` is not `never`. */\n readonly label: Mesh | undefined;\n /**\n * Holds the head's meshes at their size, turned to face the camera: `fit()`\n * scales and turns this.\n */\n readonly rig: Group;\n /** The moving end: the rig, out along the direction from the anchor. */\n readonly head: Group;\n /** Present only when anchored: a thin tube from the surface to the head. */\n readonly tether: Mesh | undefined;\n /** The same mesh as `tether`, under its old name. */\n readonly line: Mesh | undefined;\n /** Present only when anchored: the small dot on the surface point. */\n readonly dot: Mesh | undefined;\n /** The light that makes the model around the hotspot glow, when `glow` > 0. */\n readonly light: PointLight | undefined;\n /** Set by `attachHotspots` as the pointer moves on and off. */\n setHovered(on: boolean): void;\n};\n\nconst PARTS = new WeakMap<Hotspot, HotspotParts>();\nconst INTERNALS = new WeakMap<Hotspot, Internals>();\n\n/** The parts of a hotspot `createHotspot` made. */\nexport function hotspotParts(hotspot: Hotspot): HotspotParts {\n const parts = PARTS.get(hotspot);\n if (!parts)\n throw new Error(\n '@oeave/bakery3/hotspots: that hotspot was not made by createHotspot().',\n );\n return parts;\n}\n\nexport type HotspotOptions = {\n /** Stable identity: it names the group and travels with `hotspotSpecOf`. */\n id: string;\n /** The hotspot's caption: the text of its label, and yours to show in your app. */\n label?: string;\n /**\n * Where the orb is, in the parent's space (world space without a parent).\n * With an `anchor`, you can give `direction` and `distance` instead.\n */\n position?: Vec3 | Vector3;\n /**\n * A point on the model's surface, in the same space as `position`. When\n * given, the hotspot is tied to it: a thin line runs from a small dot on\n * the surface out to the orb.\n */\n anchor?: Vec3 | Vector3;\n /**\n * Which way the orb stands off the anchor, in the parent's space. Default:\n * toward `position`, or straight up.\n */\n direction?: Vec3 | Vector3;\n /** How far the orb stands off the anchor, in meters. Default: to `position`, or 0.1. */\n distance?: number;\n /**\n * Attach to this object so the hotspot follows it. Without one the caller\n * adds `hotspot.object` to the scene themselves.\n */\n parent?: Object3D;\n /**\n * Whether the hotspot shows up in renders. Default false: a hotspot is\n * viewport UI and the capture walks past it. With true it is part of the\n * scene, its glow lights the model in the render, and `animateHotspots`\n * can play its states in a video.\n */\n render?: boolean;\n /** The look. Default `orb`. */\n style?: HotspotPreset;\n /** Any CSS color. Default the brand cyan, `#33d1ff`. */\n color?: string;\n /** The color it turns while open. Default: it keeps `color`. */\n openColor?: string;\n /**\n * How bright the glowing parts are (emission strength). Default 3 for\n * `orb` and `ring`, 6 for `glass`, 0.2 for `solid`; 1 for a hotspot that\n * does not render, so the color on screen is exactly `color`.\n */\n intensity?: number;\n /**\n * How much the hotspot lights the model around it while open: a point light\n * at the orb, in candela. A closed hotspot gives a third of it. Default 0.\n */\n glow?: number;\n /** Your own material for some or all parts, a TSL node material included. */\n material?: HotspotMaterial;\n /**\n * How the orb is sized. `screen` (default) keeps it the same size on screen\n * wherever it is: `size` is then a fraction of the viewport height, and\n * `attachHotspots` (or `fit()`) re-fits it every frame from the camera.\n * `world` is a fixed radius in meters, which shrinks with distance.\n */\n sizing?: 'screen' | 'world';\n /** Orb radius: a fraction of viewport height (`screen`, default 0.015) or meters (`world`, default 0.03). */\n size?: number;\n /** Whether the closed hotspot breathes, or how fast, in cycles a second. Default true (0.7). */\n pulse?: boolean | number;\n /** Draw the line to the anchor. Default true when anchored. */\n tether?: boolean;\n /** Draw the small dot on the anchor. Default true when anchored. */\n dot?: boolean;\n /** When the label beside the orb shows. Default `never`. */\n showLabel?: HotspotLabelShow;\n /** Which side the label is on. Default `auto`: right, or left near the right edge. */\n labelSide?: HotspotLabelSide;\n /**\n * The label's CSS font. Its pixel size is how sharp the label is, not how\n * big: the label is sized to the orb. Default the platform's UI face at 40px.\n */\n labelFont?: string;\n /** The label's text color. Default white. */\n labelColor?: string;\n /** The label's background color. Default near black. */\n labelBackground?: string;\n /** How opaque the shown label is. Default 0.9. */\n labelOpacity?: number;\n /** The label's height, as a multiple of its default. Default 1. */\n labelSize?: number;\n /** The state it starts in, already there. Default `closed`. */\n state?: HotspotState;\n /** Seconds each move takes. Default 0.8 to appear, 0.45 to open, 0.3 for the label. */\n timing?: { appear?: number; open?: number; label?: number };\n};\n\nexport type Hotspot = {\n readonly id: string;\n readonly label: string | undefined;\n /**\n * The group holding everything, placed at the anchor (at the orb when\n * there is none), named `bakery3-hotspot-<id>`.\n */\n readonly object: Group;\n /** The state it is headed for. */\n readonly state: HotspotState;\n /** Where it is now, moves included. */\n readonly phase: HotspotPhase;\n /** Whether it is open, or opening. */\n readonly selected: boolean;\n /** Whether it is hovered, by the pointer or by `setHovered()`. */\n readonly hovered: boolean;\n /** Meters from the anchor to the orb. */\n readonly distance: number;\n /** The side the label is on, or headed for. */\n readonly labelSide: 'left' | 'right';\n /** True while `animateHotspots` drives it: `update()` then leaves it to the timeline. */\n readonly driven: boolean;\n /** Move to a state, animated unless `instant`. */\n setState(state: HotspotState, options?: { instant?: boolean }): void;\n /** `setState('open')` or `setState('closed')`. */\n setSelected(on: boolean): void;\n /** Hover it, or stop: what `attachHotspots` does as the pointer moves. */\n setHovered(on: boolean): void;\n /** Change the label's text. */\n setLabel(text: string): void;\n /** Stand the orb this far off the anchor, in meters. */\n setDistance(meters: number): void;\n /** Point the orb this way from the anchor (parent space). */\n setDirection(direction: Vec3 | Vector3): void;\n /** Advance the moves and the pulse; `seconds` is any monotonic clock. */\n update(seconds: number): void;\n /**\n * Turn the orb and its label to face this camera, put the label on the\n * side with room, and, for a screen-sized orb, scale it to its `size`.\n * Called by `attachHotspots.update()`; a host without pointer handling\n * calls it itself once per frame, before `update()`.\n */\n fit(camera: Camera): void;\n /** Detach from its parent and free every geometry, material and texture. */\n dispose(): void;\n};\n\n/** A hotspot as data, in world space: what to keep with a capture. */\nexport type HotspotSpec = {\n id: string;\n label?: string;\n position: Vec3;\n anchor?: Vec3;\n};\n\n// ---------------------------------------------------------------------------\n// The look, as ratios of the orb's radius\n// ---------------------------------------------------------------------------\n\nconst HALO_SCALE = 1.7;\nconst HALO_PULSE = 0.3;\nconst HALO_OPACITY = 0.28;\nconst RING_RADIUS = 1.35;\nconst RING_TUBE = 0.11;\nconst GLASS_CORE = 0.42;\nconst RING_CORE = 0.5;\nconst TETHER_RADIUS = 0.09;\nconst DOT_RADIUS = 0.32;\nconst PULSE_HZ = 0.7;\n/** The label's height, and how far it slides as it fades in. */\nconst LABEL_HEIGHT = 2.2;\nconst LABEL_SLIDE = 0.6;\n/**\n * How far the label is lifted toward the camera, as a fraction of the way.\n * It is scaled down by as much, so it lands on exactly the same pixels, but\n * in front of the model rather than behind an armrest that happens to be\n * nearer the camera than the orb.\n */\nconst LABEL_LIFT = 0.4;\n/** How bright the label's pixels are in a render: white reads white through tone mapping. */\nconst LABEL_GLOW = 1.3;\n/** How far out each look reaches, so a label starts clear of it. */\nconst REACH: Record<HotspotPreset, number> = {\n orb: 2.0,\n ring: 2.0,\n glass: 1.15,\n solid: 1.45,\n};\n/** A closed hotspot lights the model this much of its open glow. */\nconst CLOSED_GLOW = 1 / 3;\n/** Never exactly zero: a singular matrix is a transform nobody can decompose. */\nconst FLOOR = 1e-3;\n/** Nor a lamp at zero, which the renderer drops before a channel can drive it. */\nconst LIGHT_FLOOR = 1e-6;\n\nconst INTENSITY: Record<HotspotPreset, number> = {\n orb: 3,\n ring: 3,\n glass: 6,\n solid: 0.2,\n};\n\n/** How far along each move is, 0 to 1, linear in time; `poseOf` shapes it. */\ntype Motion = {\n presence: number;\n open: number;\n hover: number;\n label: number;\n /** 0 with the label on the right, 1 on the left. */\n side: number;\n};\n\n/** Where each move is headed. */\ntype Targets = Motion;\n\ntype Timing = {\n appear: number;\n open: number;\n label: number;\n hover: number;\n side: number;\n};\n\n/** What the parts are at one instant: every number a frame needs. */\nexport type HotspotPose = {\n /** The dot on the surface, as a fraction of its size. */\n dot: number;\n /** How far out the orb has traveled along the tether, 0 to 1. */\n extend: number;\n /** The head's size, as a fraction (it overshoots a little as it pops in). */\n head: number;\n /** How open it looks, 0 to 1, eased. */\n open: number;\n /** Hover emphasis, 0 to 1. */\n hover: number;\n /** How far the label has faded in, 0 to 1, eased. */\n label: number;\n /** Where the label is between the right side (0) and the left (1). */\n side: number;\n /** The breath, 0 to 1. */\n pulse: number;\n};\n\nconst clamp01 = (x: number): number => (x <= 0 ? 0 : x >= 1 ? 1 : x);\nconst smooth = (a: number, b: number, x: number): number => {\n const t = clamp01((x - a) / (b - a));\n return t * t * (3 - 2 * t);\n};\nconst easeOutCubic = (t: number): number => 1 - (1 - clamp01(t)) ** 3;\nconst easeInOutCubic = (t: number): number => {\n const x = clamp01(t);\n return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;\n};\n/** Overshoots by about ten percent and settles: a pop, not a bounce. */\nconst easeOutBack = (t: number): number => {\n const x = clamp01(t);\n const c1 = 1.4;\n const c3 = c1 + 1;\n return 1 + c3 * (x - 1) ** 3 + c1 * (x - 1) ** 2;\n};\n\n/**\n * The shape of every move, from how far along it is.\n *\n * Appearing, an anchored hotspot puts its dot on the surface first, runs the\n * line out, and pops the orb at the end of it; leaving plays the same thing\n * backwards. Opening waits for the orb to be out, and so does the label.\n */\nexport function poseOf(\n motion: Motion,\n seconds: number,\n anchored: boolean,\n pulseHz: number,\n): HotspotPose {\n const p = motion.presence;\n const head = anchored ? easeOutBack((p - 0.45) / 0.55) : easeOutBack(p);\n return {\n dot: anchored ? smooth(0, 0.3, p) : 0,\n extend: anchored ? easeOutCubic((p - 0.15) / 0.6) : 1,\n head: Math.max(0, head),\n open: easeInOutCubic(motion.open) * smooth(0.6, 1, p),\n hover: smooth(0, 1, motion.hover),\n label: easeOutCubic(motion.label) * smooth(0.6, 1, p),\n side: motion.side,\n pulse:\n pulseHz > 0 ? 0.5 + 0.5 * Math.sin(seconds * Math.PI * 2 * pulseHz) : 0,\n };\n}\n\n/** Whether the label is wanted, for this state and hover. */\nfunction labelWanted(\n show: HotspotLabelShow,\n state: HotspotState,\n hovered: boolean,\n): boolean {\n if (state === 'hidden' || show === 'never') return false;\n if (show === 'always') return true;\n if (show === 'open') return state === 'open';\n return hovered || state === 'open';\n}\n\n/** Move a progress toward its target at a constant rate: exact for any dt. */\nfunction approach(\n value: number,\n target: number,\n dt: number,\n seconds: number,\n): number {\n if (seconds <= 0) return target;\n const step = dt / seconds;\n return value < target\n ? Math.min(target, value + step)\n : Math.max(target, value - step);\n}\n\nfunction step(\n motion: Motion,\n target: Targets,\n dt: number,\n timing: Timing,\n): void {\n motion.presence = approach(\n motion.presence,\n target.presence,\n dt,\n timing.appear,\n );\n motion.open = approach(motion.open, target.open, dt, timing.open);\n motion.hover = approach(motion.hover, target.hover, dt, timing.hover);\n motion.label = approach(motion.label, target.label, dt, timing.label);\n motion.side = approach(motion.side, target.side, dt, timing.side);\n}\n\nfunction phaseOf(motion: Motion, state: HotspotState): HotspotPhase {\n if (state === 'hidden') return motion.presence > 0 ? 'leaving' : 'hidden';\n if (motion.presence < 1) return 'entering';\n if (state === 'open') return motion.open < 1 ? 'opening' : 'open';\n return motion.open > 0 ? 'closing' : 'closed';\n}\n\n// ---------------------------------------------------------------------------\n// What a pose writes\n// ---------------------------------------------------------------------------\n\n/** Properties a pose drives, each exactly as the timeline would write it. */\ntype Driven =\n | 'position'\n | 'rotation'\n | 'scale'\n | 'emissiveIntensity'\n | 'opacity'\n | 'emissive'\n | 'color'\n | 'intensity';\n\ntype Write = { object: Object3D; property: Driven; value: number[] };\n\n/** One instant's view of the hotspot: the camera's part in a pose. */\ntype Frame = {\n /** The orb's radius, in meters. */\n radius: number;\n /** The parent's world scale, to turn meters into local units. */\n ws: number;\n /** The rig's local rotation that faces the camera, as an euler. */\n facing: Vec3;\n /**\n * The camera's eye in the rig's own units (a perspective camera's), which\n * is what the label is lifted toward. Null without one.\n */\n eye: Vec3 | null;\n};\n\ntype Internals = {\n writes(pose: HotspotPose, frame: Frame): Write[];\n /** The orb's radius in meters, for the camera at this head position. */\n orbRadius(camera: Camera | undefined, headWorld: Vector3): number;\n /** The rig rotation that faces a camera held at this world rotation. */\n facing(cameraQuaternion: Quaternion): Vec3;\n /** The camera's eye in rig units, for a head here and an orb this big. */\n eye(camera: Camera, headWorld: Vector3, radius: number): Vec3 | null;\n /** Where the label belongs, for this camera, given where it is now. */\n sideFor(\n current: 'left' | 'right',\n camera: Camera,\n headWorld: Vector3,\n radius: number,\n ): 'left' | 'right';\n targets(\n state: HotspotState,\n hovered: boolean,\n side: 'left' | 'right',\n ): Targets;\n headLocal(extend: number, worldScale: number): Vector3;\n worldScale(): number;\n anchored: boolean;\n pulseHz: number;\n timing: Timing;\n labelSide: HotspotLabelSide;\n driven: Timeline | null;\n render: boolean;\n};\n\nfunction vector(value: Vec3 | Vector3): Vector3 {\n return value instanceof Vector3\n ? value.clone()\n : new Vector3(value[0], value[1], value[2]);\n}\n\nfunction vec3Of(v: Vector3): Vec3 {\n return [v.x, v.y, v.z];\n}\n\ntype Emissive = Material & {\n emissive?: Color;\n emissiveIntensity?: number;\n color?: Color;\n opacity: number;\n};\n\nexport function createHotspot(options: HotspotOptions): Hotspot {\n const {\n id,\n parent,\n render = false,\n style = 'orb',\n color = HOTSPOT_COLOR,\n openColor,\n glow = 0,\n sizing = 'screen',\n size = sizing === 'screen' ? 0.015 : 0.03,\n showLabel = 'never',\n labelOpacity = 0.9,\n labelSize = 1,\n } = options;\n let label = options.label;\n const intensity = options.intensity ?? (render ? INTENSITY[style] : 1);\n const pulseHz =\n options.pulse === false\n ? 0\n : typeof options.pulse === 'number'\n ? Math.max(0, options.pulse)\n : PULSE_HZ;\n const timing: Timing = {\n appear: options.timing?.appear ?? 0.8,\n open: options.timing?.open ?? 0.45,\n label: options.timing?.label ?? 0.3,\n hover: 0.15,\n side: 0.35,\n };\n const labelSide = options.labelSide ?? 'auto';\n\n // Where things are. The group sits at the anchor and is never rotated or\n // scaled by this module, so a direction in the parent's space is a\n // direction in the group's.\n const anchor = options.anchor ? vector(options.anchor) : undefined;\n const anchored = anchor !== undefined;\n const given = options.position ? vector(options.position) : undefined;\n const direction = new Vector3();\n if (options.direction) direction.copy(vector(options.direction));\n else if (anchor && given) direction.copy(given).sub(anchor);\n else direction.copy(anchored ? UP : FRONT);\n if (direction.lengthSq() < 1e-12) direction.copy(anchored ? UP : FRONT);\n direction.normalize();\n let distance =\n options.distance ??\n (anchor && given ? given.distanceTo(anchor) : anchored ? 0.1 : 0);\n\n const object = new Group();\n object.name = `bakery3-hotspot-${id}`;\n // The exclusion the capture honors covers the whole subtree. A hotspot that\n // renders carries the opposite mark for nothing: it is simply in the scene.\n if (!render) object.userData.bakery3 = { exclude: true };\n object.position.copy(anchor ?? given ?? new Vector3());\n\n const base = new Color(color);\n const opened = openColor ? new Color(openColor) : undefined;\n const custom = options.material;\n const materials: Material[] = [];\n const geometries: BufferGeometry[] = [];\n const meshes: Mesh[] = [];\n\n /** The preset's material for a part, unless the developer has one. */\n const materialFor = (name: HotspotPartName, preset: () => Material) => {\n let material: Material | undefined;\n if (typeof custom === 'function')\n material = custom({ name, color: base.clone() });\n else if (custom && name === 'core') material = custom;\n material ??= preset();\n // A hotspot that never renders keeps the exact color on screen; one that\n // renders goes through tone mapping like the trace it has to match.\n if (!render) material.toneMapped = false;\n materials.push(material);\n return material;\n };\n\n const part = (mesh: Mesh, name: string): Mesh => {\n mesh.name = name;\n // The viewport draws no hotspot shadows (nothing here casts one), so\n // the render must not either: a label's plane or a halo would otherwise\n // throw a shadow on the product that the browser never showed.\n if (render) mesh.userData.bakery3 = { castsShadow: false };\n meshes.push(mesh);\n return mesh;\n };\n\n const glowing = (\n strength: number,\n extra: Partial<MeshStandardMaterial> = {},\n ) =>\n new MeshStandardMaterial({\n // A dark base under the emission: the part reads as light, not as a lit thing.\n color: base.clone().multiplyScalar(0.12),\n emissive: base.clone(),\n emissiveIntensity: strength,\n roughness: 0.45,\n metalness: 0,\n ...extra,\n });\n\n const sphere = () => {\n const geometry = new SphereGeometry(1, 32, 20);\n geometries.push(geometry);\n return geometry;\n };\n\n // The head travels out along the direction; the rig inside it turns to\n // face the camera, so a ring and a label are always seen face on.\n const rig = new Group();\n rig.name = 'rig';\n const head = new Group();\n head.name = 'head';\n head.add(rig);\n object.add(head);\n\n const coreRadius =\n style === 'glass' ? GLASS_CORE : style === 'ring' ? RING_CORE : 1;\n const core = part(\n new Mesh(\n sphere(),\n materialFor('core', () =>\n style === 'solid'\n ? new MeshStandardMaterial({\n color: base.clone(),\n emissive: base.clone(),\n emissiveIntensity: intensity,\n roughness: 0.22,\n metalness: 0,\n })\n : glowing(intensity),\n ),\n ),\n 'core',\n );\n rig.add(core);\n\n let halo: Mesh | undefined;\n if (style === 'orb') {\n halo = part(\n new Mesh(\n sphere(),\n materialFor('halo', () =>\n glowing(intensity * 0.5, {\n color: new Color(0, 0, 0),\n transparent: true,\n opacity: HALO_OPACITY,\n depthWrite: false,\n roughness: 1,\n }),\n ),\n ),\n 'halo',\n );\n // After the opaque core so its translucency composites over it.\n halo.renderOrder = 1;\n rig.add(halo);\n }\n\n let ring: Mesh | undefined;\n if (style === 'ring') {\n // A torus lies in its XY plane, which is the plane facing the camera.\n const geometry = new TorusGeometry(1, RING_TUBE / RING_RADIUS, 12, 64);\n geometries.push(geometry);\n ring = part(\n new Mesh(\n geometry,\n materialFor('ring', () =>\n glowing(intensity, { transparent: true, opacity: 0.9 }),\n ),\n ),\n 'ring',\n );\n rig.add(ring);\n }\n\n let shell: Mesh | undefined;\n if (style === 'glass') {\n shell = part(\n new Mesh(\n sphere(),\n materialFor(\n 'shell',\n () =>\n new MeshPhysicalMaterial({\n color: '#ffffff',\n transmission: 1,\n roughness: 0.04,\n ior: 1.5,\n thickness: 0.02,\n metalness: 0,\n specularIntensity: 1,\n }),\n ),\n ),\n 'shell',\n );\n rig.add(shell);\n }\n\n let tether: Mesh | undefined;\n if (anchored && options.tether !== false) {\n // A unit tube standing on its base, so scale y is its length.\n const geometry = new CylinderGeometry(1, 1, 1, 10, 1, true);\n geometry.translate(0, 0.5, 0);\n geometries.push(geometry);\n tether = part(\n new Mesh(\n geometry,\n materialFor('tether', () => glowing(intensity * 0.6)),\n ),\n 'tether',\n );\n tether.quaternion.setFromUnitVectors(UP, direction);\n object.add(tether);\n }\n\n let dot: Mesh | undefined;\n if (anchored && options.dot !== false) {\n dot = part(\n new Mesh(\n sphere(),\n materialFor('dot', () => glowing(intensity)),\n ),\n 'dot',\n );\n object.add(dot);\n }\n\n // The label: the browser's own text, as pixels on a pill that faces the\n // camera with the rest of the rig. It fades in by opacity alone, which is\n // the one alpha it has: the pill's shape is geometry, its texture opaque.\n let labelMesh: Mesh | undefined;\n let labelMaterial: MeshPhysicalMaterial | undefined;\n let labelMap: DataTexture | undefined;\n let labelAspect = 3;\n const labelLook = () => ({\n text: label ?? id,\n font: options.labelFont ?? LABEL_FONT,\n color: options.labelColor ?? '#ffffff',\n background: options.labelBackground ?? '#0b0c12',\n });\n const drawLabel = (): void => {\n if (!labelMesh || !labelMaterial) return;\n const raster = rasterizeLabel(labelLook());\n labelMap?.dispose();\n labelMap = raster.texture;\n labelAspect = raster.aspect;\n labelMaterial.emissiveMap = labelMap;\n labelMaterial.needsUpdate = true;\n const old = labelMesh.geometry;\n labelMesh.geometry = pillGeometry(labelAspect);\n old.dispose();\n };\n if (showLabel !== 'never') {\n labelMaterial = new MeshPhysicalMaterial({\n color: 0x000000,\n emissive: 0xffffff,\n emissiveIntensity: render ? LABEL_GLOW : 1,\n roughness: 1,\n metalness: 0,\n // No sheen of the studio across the text.\n specularIntensity: 0,\n transparent: true,\n opacity: 0,\n depthWrite: false,\n });\n if (!render) labelMaterial.toneMapped = false;\n materials.push(labelMaterial);\n labelMesh = part(\n new Mesh(pillGeometry(labelAspect), labelMaterial),\n 'label',\n );\n labelMesh.renderOrder = 2;\n const height = LABEL_HEIGHT * labelSize;\n labelMesh.scale.set(height, height, 1);\n rig.add(labelMesh);\n drawLabel();\n // A web font the page has not finished loading draws as the fallback;\n // draw again once it is in.\n const fonts = typeof document !== 'undefined' ? document.fonts : undefined;\n const font = labelLook().font;\n if (fonts && !fonts.check(font))\n void fonts.load(font).then(\n () => !disposed && drawLabel(),\n () => undefined,\n );\n }\n\n // The light stands where the orb ends up and never moves: the renderer's\n // lamps have no parent, so a lamp riding the head out would be a lamp the\n // render leaves at the capture's position. Only its strength is animated.\n let light: PointLight | undefined;\n if (glow > 0) {\n light = new PointLight((opened ?? base).clone(), glow * CLOSED_GLOW, 0, 2);\n light.name = 'glow';\n light.castShadow = false;\n object.add(light);\n }\n\n parent?.add(object);\n\n let state: HotspotState = options.state ?? 'closed';\n let hovered = false;\n let side: 'left' | 'right' = labelSide === 'left' ? 'left' : 'right';\n let sided = labelSide !== 'auto';\n // The orb's radius in meters; `fit()` sets it for a screen-sized orb.\n let fitted = size;\n let facing: Vec3 = [0, 0, 0];\n let eye: Vec3 | null = null;\n let clock: number | undefined;\n let disposed = false;\n\n const targets = (\n next: HotspotState,\n hover: boolean,\n labelOn: 'left' | 'right',\n ): Targets => ({\n presence: next === 'hidden' ? 0 : 1,\n open: next === 'open' ? 1 : 0,\n hover: hover ? 1 : 0,\n label: labelWanted(showLabel, next, hover) ? 1 : 0,\n side: labelOn === 'left' ? 1 : 0,\n });\n const motion: Motion = targets(state, false, side);\n\n const worldScale = (): number => {\n object.updateWorldMatrix(true, false);\n object.getWorldScale(SCALE);\n return Math.max(1e-9, (SCALE.x + SCALE.y + SCALE.z) / 3);\n };\n\n const headLocal = (extend: number, ws: number): Vector3 =>\n direction.clone().multiplyScalar((distance * extend) / ws);\n\n const orbRadius = (\n camera: Camera | undefined,\n headWorld: Vector3,\n ): number => {\n if (sizing === 'world' || !camera)\n return sizing === 'world' ? size : fitted;\n const perspective =\n (camera as PerspectiveCamera).isPerspectiveCamera === true;\n const ortho = (camera as OrthographicCamera).isOrthographicCamera === true;\n if (!perspective && !ortho) return fitted;\n let visibleHeight: number;\n if (perspective) {\n const cam = camera as PerspectiveCamera;\n camera.updateMatrixWorld();\n camera.getWorldPosition(CAMERA);\n // Depth along the view axis, not the straight-line distance: an orb\n // at the frame's edge is as far \"into\" the picture as one dead center.\n camera.getWorldDirection(FORWARD);\n const depth = Math.max(\n 1e-3,\n WORLD.copy(headWorld).sub(CAMERA).dot(FORWARD),\n );\n visibleHeight = 2 * depth * Math.tan((cam.fov * Math.PI) / 360);\n } else {\n const cam = camera as OrthographicCamera;\n visibleHeight = (cam.top - cam.bottom) / cam.zoom;\n }\n return Math.max(1e-6, size * visibleHeight);\n };\n\n /**\n * The rig's rotation that matches the camera's: a sprite's billboard, so\n * the label reads level with the frame rather than leaning toward its\n * vanishing point.\n */\n const facingFor = (cameraQuaternion: Quaternion): Vec3 => {\n head.updateWorldMatrix(true, false);\n head.getWorldQuaternion(ORIENT);\n VIEW.copy(ORIENT).invert().multiply(cameraQuaternion);\n EULER.setFromQuaternion(VIEW, rig.rotation.order);\n return [EULER.x, EULER.y, EULER.z];\n };\n\n /** Where the eye is from the head, in the rig's units: camera space over the radius. */\n const eyeFor = (\n camera: Camera,\n headWorld: Vector3,\n radius: number,\n ): Vec3 | null => {\n if ((camera as PerspectiveCamera).isPerspectiveCamera !== true) return null;\n camera.updateMatrixWorld();\n camera.getWorldPosition(CAMERA);\n camera.getWorldQuaternion(VIEW);\n const local = CAMERA.sub(headWorld)\n .applyQuaternion(VIEW.invert())\n .divideScalar(Math.max(radius, 1e-9));\n return [local.x, local.y, local.z];\n };\n\n const labelGap = REACH[style] + 0.35;\n const sideFor = (\n current: 'left' | 'right',\n camera: Camera,\n headWorld: Vector3,\n radius: number,\n ): 'left' | 'right' => {\n if (labelSide !== 'auto' || !labelMesh) return current;\n camera.updateMatrixWorld();\n camera.getWorldQuaternion(VIEW);\n RIGHT.set(1, 0, 0).applyQuaternion(VIEW);\n const reach = (labelGap + LABEL_HEIGHT * labelSize * labelAspect) * radius;\n const x = WORLD.copy(headWorld).project(camera).x;\n const edge = EDGE.copy(headWorld)\n .addScaledVector(RIGHT, reach)\n .project(camera).x;\n if (!Number.isFinite(x) || !Number.isFinite(edge)) return current;\n return labelSideFor(current, x, Math.abs(edge - x));\n };\n\n const mixColor = (open: number): Color =>\n opened ? base.clone().lerp(opened, open) : base;\n\n /** Everything a pose sets, part by part. */\n const writes = (pose: HotspotPose, frame: Frame): Write[] => {\n const { radius, ws } = frame;\n const out: Write[] = [];\n const emissive = (\n mesh: Mesh | undefined,\n strength: number,\n darken = 0.12,\n ) => {\n if (!mesh) return;\n const material = mesh.material as Emissive;\n if (typeof material.emissiveIntensity === 'number')\n out.push({\n object: mesh,\n property: 'emissiveIntensity',\n value: [strength],\n });\n // A node material that computes its own emission or color keeps it:\n // the renderer would unhook the graph to key a flat color instead.\n const nodes = material as { emissiveNode?: unknown; colorNode?: unknown };\n if (opened && material.emissive?.isColor && !nodes.emissiveNode) {\n const c = mixColor(pose.open);\n out.push({\n object: mesh,\n property: 'emissive',\n value: [c.r, c.g, c.b],\n });\n if (material.color?.isColor && darken > 0 && !nodes.colorNode)\n out.push({\n object: mesh,\n property: 'color',\n value: [c.r * darken, c.g * darken, c.b * darken],\n });\n }\n };\n const uniform = (mesh: Mesh | undefined, s: number) => {\n if (!mesh) return;\n const k = Math.max(s, FLOOR);\n out.push({ object: mesh, property: 'scale', value: [k, k, k] });\n };\n\n const rigScale = radius / ws;\n out.push({\n object: rig,\n property: 'scale',\n value: [rigScale, rigScale, rigScale],\n });\n out.push({ object: rig, property: 'rotation', value: [...frame.facing] });\n out.push({\n object: head,\n property: 'position',\n value: vec3Of(headLocal(pose.extend, ws)),\n });\n\n const h = pose.head;\n const open = pose.open;\n const hover = pose.hover;\n const breath = pose.pulse * (1 - open);\n const emphasis = 1 + 0.35 * open + 0.1 * hover;\n const strength = intensity * (1 + 1.2 * open + 0.3 * hover);\n\n uniform(\n core,\n h * coreRadius * (style === 'glass' ? 1 + 0.35 * open : emphasis),\n );\n emissive(core, strength, style === 'solid' ? 1 : 0.12);\n\n if (halo) {\n uniform(halo, h * (HALO_SCALE + HALO_PULSE * breath + 0.5 * open));\n out.push({\n object: halo,\n property: 'opacity',\n value: [HALO_OPACITY * (1 + 0.6 * hover) * (1 - 0.25 * open)],\n });\n emissive(halo, strength * 0.5, 0);\n }\n if (ring) {\n uniform(\n ring,\n h * RING_RADIUS * (1 + 0.45 * open + 0.12 * breath + 0.08 * hover),\n );\n out.push({\n object: ring,\n property: 'opacity',\n value: [0.9 - 0.35 * breath],\n });\n emissive(ring, strength);\n }\n if (shell) uniform(shell, h * (1 + 0.05 * hover));\n\n if (labelMesh) {\n // It slides out from the orb as it fades in. Changing sides, it fades\n // out on one side and back in on the other.\n const width = LABEL_HEIGHT * labelSize * labelAspect;\n const slide = (1 - pose.label) * LABEL_SLIDE;\n const left = pose.side >= 0.5;\n const swap = Math.abs(2 * pose.side - 1);\n const x = left ? -(labelGap + slide) - width : labelGap + slide;\n const height = LABEL_HEIGHT * labelSize;\n // Lifted toward the eye and shrunk by as much: the same pixels, in\n // front of whatever stands between the orb and the camera.\n const k = frame.eye ? LABEL_LIFT : 0;\n const [ex, ey, ez] = frame.eye ?? [0, 0, 0];\n out.push({\n object: labelMesh,\n property: 'position',\n value: [x * (1 - k) + k * ex, k * ey, k * ez],\n });\n out.push({\n object: labelMesh,\n property: 'scale',\n value: [height * (1 - k), height * (1 - k), 1],\n });\n out.push({\n object: labelMesh,\n property: 'opacity',\n value: [labelOpacity * pose.label * swap],\n });\n }\n\n if (tether) {\n const thickness = Math.max((radius * TETHER_RADIUS) / ws, 1e-9);\n const length = Math.max(\n (distance * pose.extend) / ws,\n (FLOOR * radius) / ws,\n );\n const visible = pose.extend > 0 ? 1 : FLOOR;\n out.push({\n object: tether,\n property: 'scale',\n value: [thickness * visible, length, thickness * visible],\n });\n emissive(tether, intensity * 0.6 * (1 + 0.6 * open));\n }\n if (dot) {\n uniform(dot, (pose.dot * radius * DOT_RADIUS) / ws);\n emissive(dot, intensity * (1 + 0.6 * open));\n }\n if (light) {\n const presence = Math.min(1, h);\n out.push({\n object: light,\n property: 'intensity',\n value: [\n Math.max(\n LIGHT_FLOOR,\n glow * presence * (CLOSED_GLOW + (1 - CLOSED_GLOW) * open),\n ),\n ],\n });\n // The color stays put: the glow is mostly seen open, so it is the\n // open color from the start. Workers before the lamp-color fix in\n // `apply_animation` refuse a lamp color channel outright.\n }\n return out;\n };\n\n const apply = (seconds: number): void => {\n const ws = worldScale();\n const pose = poseOf(motion, seconds, anchored, pulseHz);\n const frame = {\n radius: sizing === 'world' ? size : fitted,\n ws,\n facing,\n eye,\n };\n for (const write of writes(pose, frame))\n OBJECT_PROPERTIES[write.property]!.write(write.object, write.value);\n };\n\n const placeLight = (): void => {\n if (light) light.position.copy(headLocal(1, worldScale()));\n };\n placeLight();\n\n const internals: Internals = {\n writes,\n orbRadius,\n facing: facingFor,\n eye: eyeFor,\n sideFor,\n targets,\n headLocal,\n worldScale,\n anchored,\n pulseHz,\n timing,\n labelSide,\n driven: null,\n render,\n };\n\n const hotspot: Hotspot = {\n id,\n get label() {\n return label;\n },\n object,\n get state() {\n return state;\n },\n get phase() {\n return phaseOf(motion, state);\n },\n get selected() {\n return state === 'open';\n },\n get hovered() {\n return hovered;\n },\n get distance() {\n return distance;\n },\n get labelSide() {\n return side;\n },\n get driven() {\n return internals.driven !== null;\n },\n setState(next, opts = {}) {\n state = next;\n if (opts.instant) {\n Object.assign(motion, targets(next, hovered, side));\n if (!internals.driven) apply(clock ?? 0);\n }\n },\n setSelected(on) {\n hotspot.setState(on ? 'open' : 'closed');\n },\n setHovered(on) {\n hovered = on;\n },\n setLabel(text) {\n label = text;\n drawLabel();\n },\n setDistance(meters) {\n distance = Math.max(0, meters);\n placeLight();\n if (!internals.driven) apply(clock ?? 0);\n },\n setDirection(next) {\n const v = vector(next);\n if (v.lengthSq() < 1e-12) return;\n direction.copy(v.normalize());\n tether?.quaternion.setFromUnitVectors(UP, direction);\n placeLight();\n if (!internals.driven) apply(clock ?? 0);\n },\n fit(camera) {\n if (disposed || internals.driven) return;\n const ws = worldScale();\n object.updateWorldMatrix(true, false);\n const headWorld = headLocal(1, ws).applyMatrix4(object.matrixWorld);\n if (sizing === 'screen') fitted = orbRadius(camera, headWorld);\n // Facing and the label's side need a real camera's matrices.\n if (typeof camera.updateMatrixWorld !== 'function') return;\n camera.updateMatrixWorld();\n facing = facingFor(camera.getWorldQuaternion(new Quaternion()));\n const radius = sizing === 'world' ? size : fitted;\n eye = eyeFor(camera, headWorld, radius);\n side = sideFor(side, camera, headWorld, radius);\n // The first look at a camera settles the side without a move.\n if (!sided) {\n sided = true;\n motion.side = side === 'left' ? 1 : 0;\n }\n },\n update(seconds) {\n if (disposed || internals.driven) return;\n const dt = clock === undefined ? 0 : Math.max(0, seconds - clock);\n clock = seconds;\n step(motion, targets(state, hovered, side), dt, timing);\n apply(seconds);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n object.removeFromParent();\n for (const geometry of geometries) geometry.dispose();\n labelMesh?.geometry.dispose();\n for (const material of materials) material.dispose();\n labelMap?.dispose();\n light?.dispose();\n },\n };\n\n PARTS.set(hotspot, {\n core,\n orb: core,\n halo,\n ring,\n shell,\n label: labelMesh,\n rig,\n head,\n tether,\n line: tether,\n dot,\n light,\n setHovered: (on) => hotspot.setHovered(on),\n });\n INTERNALS.set(hotspot, internals);\n apply(0);\n return hotspot;\n}\n\n/**\n * Where to put a hotspot for a click on a model: the surface point, and the\n * way out of the surface there.\n *\n * `along: 'normal'` (default) stands the orb off the face that was hit;\n * `'center'` stands it away from `center` (the model's middle) through the\n * point, which keeps orbs on a curved or noisy surface from pointing every\n * which way. Both are returned in `space`'s coordinates (world without one),\n * ready to pass as `anchor` and `direction` with `parent: space`.\n */\nexport function hotspotFromHit(\n hit: Intersection,\n options: {\n along?: 'normal' | 'center';\n center?: Vector3;\n space?: Object3D;\n } = {},\n): { anchor: Vector3; direction: Vector3 } {\n const { along = 'normal', center, space } = options;\n const point = hit.point.clone();\n const out = new Vector3();\n if (along === 'center' && center) {\n out.copy(point).sub(center);\n } else if (hit.face) {\n // The normal matrix, not the world matrix: a model scaled unevenly\n // would otherwise tilt every orb toward its long axis.\n out\n .copy(hit.face.normal)\n .applyMatrix3(new Matrix3().getNormalMatrix(hit.object.matrixWorld));\n }\n if (along === 'normal' && !hit.face && center) out.copy(point).sub(center);\n if (out.lengthSq() < 1e-12) out.copy(UP);\n out.normalize();\n if (space) {\n space.updateWorldMatrix(true, false);\n const inverse = new Matrix4().copy(space.matrixWorld).invert();\n const anchor = point.clone().applyMatrix4(inverse);\n const tip = hit.point.clone().add(out).applyMatrix4(inverse);\n return { anchor, direction: tip.sub(anchor).normalize() };\n }\n return { anchor: point, direction: out };\n}\n\n/**\n * A hotspot as plain data, in world space, ready for `productState`.\n *\n * Reads through the parents so a hotspot riding on a product that has been\n * moved reports where it actually is, not where it was authored. The\n * position is where the orb stands once it is out, whatever it is doing.\n */\nexport function hotspotSpecOf(hotspot: Hotspot): HotspotSpec {\n const internals = INTERNALS.get(hotspot);\n if (!internals)\n throw new Error(\n '@oeave/bakery3/hotspots: that hotspot was not made by createHotspot().',\n );\n const { object } = hotspot;\n object.updateWorldMatrix(true, false);\n const tip = internals\n .headLocal(1, internals.worldScale())\n .applyMatrix4(object.matrixWorld);\n const spec: HotspotSpec = { id: hotspot.id, position: vec3Of(tip) };\n if (hotspot.label !== undefined) spec.label = hotspot.label;\n if (internals.anchored)\n spec.anchor = vec3Of(object.getWorldPosition(new Vector3()));\n return spec;\n}\n\n// ---------------------------------------------------------------------------\n// On a timeline\n// ---------------------------------------------------------------------------\n\n/** One change, at a time on the timeline: a state, a hover, or both. */\nexport type HotspotEvent = {\n /** The hotspot, or its id. */\n hotspot: Hotspot | string;\n /** Seconds from the start of the timeline. */\n at: number;\n state?: HotspotState;\n /**\n * The pointer moves onto it (true) or off (false): the hover look, and the\n * label of a hotspot that shows it on hover.\n */\n hover?: boolean;\n};\n\nexport type AnimateHotspotsOptions = {\n /** The changes, in any order. */\n events?: HotspotEvent[];\n /**\n * Where each hotspot is at time zero, already there: one state for all, or\n * one per id. Default `hidden`, so a clip opens on the model alone.\n */\n initial?: HotspotState | Record<string, HotspotState>;\n /**\n * Round each pulse to whole breaths over the timeline, so a clip that loops\n * does not hitch at the seam. Default true.\n */\n loop?: boolean;\n};\n\nexport type AnimatedHotspots = {\n /** How many tracks were written. */\n readonly tracks: number;\n /** Remove the tracks and hand the hotspots back to their own `update()`. */\n release(): void;\n};\n\nconst OWNED = new WeakMap<Timeline, { tracks: Track[]; hotspots: Hotspot[] }>();\n\nconst TRANSFORMS = ['position', 'rotation', 'scale'];\n\nconst idOfEvent = (event: HotspotEvent): string =>\n typeof event.hotspot === 'string' ? event.hotspot : event.hotspot.id;\n\n/**\n * Play hotspot states on a timeline, so a video renders them.\n *\n * Every frame of the timeline is posed by the same function the live hotspot\n * uses, and written as ordinary tracks (position, rotation, scale, emission,\n * opacity, the glow light's intensity), so `seek()` previews exactly what the\n * render traces. The camera at each frame decides what a live camera would:\n * the size of a screen-sized orb, which way the rig faces, and which side the\n * label is on. Author the camera first. Calling it again on the same timeline\n * replaces what it wrote. Hotspots must be made with `render: true`.\n *\n * While animated, a hotspot's `update()` and `fit()` stand aside.\n */\nexport function animateHotspots(\n timeline: Timeline,\n hotspots: Hotspot[],\n options: AnimateHotspotsOptions = {},\n): AnimatedHotspots {\n releaseHotspots(timeline);\n const { events = [], initial = 'hidden', loop = true } = options;\n const byId = new Map(hotspots.map((hotspot) => [hotspot.id, hotspot]));\n for (const event of events) {\n const id = idOfEvent(event);\n if (!byId.has(id))\n throw new Error(\n `@oeave/bakery3/hotspots: an event names \"${id}\", which is not one of the hotspots passed to animateHotspots().`,\n );\n if (event.state === undefined && event.hover === undefined)\n throw new Error(\n `@oeave/bakery3/hotspots: the event for \"${id}\" at ${event.at} s changes nothing. Give it a state, a hover, or both.`,\n );\n }\n\n const fps = timeline.fps;\n const duration = timeline.duration;\n const frames = Math.max(1, Math.round(duration * fps));\n const camera = timeline.camera;\n const fovTrack = timeline.tracks.find(\n (track) => track.target === 'camera' && track.property === 'fov',\n );\n const owned: Track[] = [];\n\n // The camera at each frame, posed once for every hotspot.\n const views: Array<Camera | undefined> = [];\n for (let frame = 0; frame < frames; frame++) {\n const time = frame / fps;\n if (!camera) {\n views.push(undefined);\n continue;\n }\n const cameraPose = timeline.cameraPoseAt(time);\n if (!cameraPose && !fovTrack) {\n views.push(camera);\n continue;\n }\n const view = camera.clone() as Camera;\n if (cameraPose) {\n view.position.set(...cameraPose.position);\n view.quaternion.set(...cameraPose.quaternion);\n }\n const fov = fovTrack ? timeline.valueAt(fovTrack, time) : undefined;\n if (fov && (view as PerspectiveCamera).isPerspectiveCamera) {\n (view as PerspectiveCamera).fov = fov[0]!;\n (view as PerspectiveCamera).updateProjectionMatrix();\n }\n view.updateMatrixWorld(true);\n views.push(view);\n }\n\n for (const hotspot of hotspots) {\n const internals = INTERNALS.get(hotspot);\n if (!internals)\n throw new Error(\n '@oeave/bakery3/hotspots: that hotspot was not made by createHotspot().',\n );\n if (!internals.render)\n throw new Error(\n `@oeave/bakery3/hotspots: hotspot \"${hotspot.id}\" does not render. Create it with { render: true } to play it in a video.`,\n );\n\n const mine = events\n .filter((event) => idOfEvent(event) === hotspot.id)\n .sort((a, b) => a.at - b.at);\n let state =\n typeof initial === 'string' ? initial : (initial[hotspot.id] ?? 'hidden');\n let hovered = false;\n let side: 'left' | 'right' =\n internals.labelSide === 'left' ? 'left' : 'right';\n let motion: Motion | undefined;\n let now = 0;\n let next = 0;\n const pulseHz =\n loop && internals.pulseHz > 0 && duration > 0\n ? Math.max(1, Math.round(internals.pulseHz * duration)) / duration\n : internals.pulseHz;\n\n const ws = internals.worldScale();\n hotspot.object.updateWorldMatrix(true, false);\n const matrix = hotspot.object.matrixWorld.clone();\n const ownTracks: Track[] = [];\n const samples = new Map<\n string,\n { object: Object3D; property: Driven; values: number[][] }\n >();\n\n for (let frame = 0; frame < frames; frame++) {\n const time = frame / fps;\n const view = views[frame];\n // Fitted at the orb's resting place, as the live hotspot is.\n const restWorld = internals.headLocal(1, ws).applyMatrix4(matrix);\n const restRadius = internals.orbRadius(view, restWorld);\n if (view) side = internals.sideFor(side, view, restWorld, restRadius);\n if (!motion) motion = internals.targets(state, hovered, side);\n\n const advance = (to: number) => {\n const dt = to - now;\n if (dt <= 0) return;\n step(\n motion!,\n internals.targets(state, hovered, side),\n dt,\n internals.timing,\n );\n now = to;\n };\n while (next < mine.length && mine[next]!.at <= time) {\n const event = mine[next]!;\n advance(Math.max(0, event.at));\n if (event.state !== undefined) state = event.state;\n if (event.hover !== undefined) hovered = event.hover;\n next++;\n }\n advance(time);\n\n const pose = poseOf(motion, time, internals.anchored, pulseHz);\n const headWorld = internals\n .headLocal(pose.extend, ws)\n .applyMatrix4(matrix);\n const radius = internals.orbRadius(view, headWorld);\n const facing: Vec3 = view\n ? internals.facing(view.getWorldQuaternion(new Quaternion()))\n : [0, 0, 0];\n const eye = view ? internals.eye(view, headWorld, radius) : null;\n\n for (const write of internals.writes(pose, { radius, ws, facing, eye })) {\n const key = `${write.object.uuid}:${write.property}`;\n let entry = samples.get(key);\n if (!entry) {\n entry = {\n object: write.object,\n property: write.property,\n values: [],\n };\n samples.set(key, entry);\n }\n entry.values.push(write.value);\n }\n }\n\n for (const { object, property, values } of samples.values()) {\n const first = values[0]!;\n const constant = values.every((value) =>\n value.every((n, i) => Math.abs(n - first[i]!) < 1e-7),\n );\n if (constant) {\n // Nothing to animate: leave the value on the object, where the\n // capture will read it.\n OBJECT_PROPERTIES[property]!.write(object, first);\n continue;\n }\n if (property === 'rotation') unwrapEulers(values);\n const track = timeline.track(object, property);\n track.keyframes.length = 0;\n values.forEach((value, frame) =>\n track.keyframes.push({\n time: frame / fps,\n value: value.map(short),\n easing: 'linear',\n }),\n );\n track.label = `${hotspot.id} · ${object.name} ${property}`;\n owned.push(track);\n ownTracks.push(track);\n }\n\n // A node under a moving node is keyed in full (position, rotation and\n // scale), held where it stands where it does not move. Workers released\n // before the fix in `apply_animation` read the parts of a child nobody\n // keyed against a parent they had already keyed, so a core under a rig\n // that turns to the camera came out turned. A node whose parents never\n // move (the head, the line, the dot hang off the hotspot's own group)\n // reads right as it is, and gets nothing: these are a clip's largest\n // channels, a sample at every frame.\n const moving = new Set(\n ownTracks\n .filter((track) => TRANSFORMS.includes(track.property))\n .map((track) => track.target as Object3D),\n );\n const underMoving = (node: Object3D): boolean => {\n for (let up = node.parent; up && up !== hotspot.object; up = up.parent)\n if (moving.has(up)) return true;\n return false;\n };\n const parts = hotspotParts(hotspot);\n const nodes = (\n [\n parts.head,\n parts.rig,\n parts.core,\n parts.halo,\n parts.ring,\n parts.shell,\n parts.label,\n parts.tether,\n parts.dot,\n ] as Array<Object3D | undefined>\n ).filter(\n (node): node is Object3D => node !== undefined && underMoving(node),\n );\n for (const node of nodes)\n for (const property of TRANSFORMS) {\n if (ownTracks.some((t) => t.target === node && t.property === property))\n continue;\n const value = OBJECT_PROPERTIES[property]!.read(node)!.map(short);\n const track = timeline.track(node, property);\n track.keyframes.length = 0;\n track.keyframes.push(\n { time: 0, value: [...value], easing: 'linear' },\n { time: duration, value: [...value], easing: 'linear' },\n );\n track.label = `${hotspot.id} · ${node.name} ${property}`;\n owned.push(track);\n ownTracks.push(track);\n }\n internals.driven = timeline;\n }\n\n OWNED.set(timeline, { tracks: owned, hotspots });\n // The panel listens for structural changes; the tracks were filled in\n // place, so tell it once, then pose the scene at the playhead.\n timeline.duration = timeline.duration;\n timeline.seek(timeline.time);\n return {\n tracks: owned.length,\n release: () => releaseHotspots(timeline),\n };\n}\n\n/**\n * Six significant figures: ten microns on a position, a millionth of a\n * radian on a turn. A track is sampled at every frame of a video, and the\n * renderer is handed every sample, so the digits past these are most of a\n * clip's manifest and nothing anybody could see.\n */\nconst short = (n: number): number => Number(n.toPrecision(6));\n\n/**\n * Keep each angle within half a turn of the frame before it, so a scrub\n * between two frames does not spin the long way round. The render samples\n * the frames themselves and never sees the difference.\n */\nfunction unwrapEulers(values: number[][]): void {\n for (let i = 1; i < values.length; i++) {\n const previous = values[i - 1]!;\n const current = values[i]!;\n for (let axis = 0; axis < 3; axis++) {\n let angle = current[axis]!;\n while (angle - previous[axis]! > Math.PI) angle -= Math.PI * 2;\n while (angle - previous[axis]! < -Math.PI) angle += Math.PI * 2;\n current[axis] = angle;\n }\n }\n}\n\n/** Undo `animateHotspots` on a timeline: its tracks go, the hotspots are live again. */\nexport function releaseHotspots(timeline: Timeline): void {\n const owned = OWNED.get(timeline);\n if (!owned) return;\n OWNED.delete(timeline);\n for (const track of owned.tracks) {\n if (timeline.tracks.includes(track)) timeline.removeTrack(track.id);\n }\n for (const hotspot of owned.hotspots) {\n const internals = INTERNALS.get(hotspot);\n if (internals?.driven === timeline) internals.driven = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pointer handling\n// ---------------------------------------------------------------------------\n\nexport type AttachHotspotsOptions = {\n hotspots: Hotspot[];\n camera: Camera;\n /** The renderer's canvas, or whatever element receives the pointer. */\n domElement: HTMLElement;\n /** Selection changed: the hotspot now open, or null when cleared. */\n onSelect?(hotspot: Hotspot | null): void;\n /** The pointer moved onto (or off) a hotspot. */\n onHover?(hotspot: Hotspot | null): void;\n};\n\nexport type AttachedHotspots = {\n /** Fit and advance every hotspot. Call once per frame. */\n update(seconds: number): void;\n /** The hotspot currently open, if any. */\n readonly selected: Hotspot | null;\n /** Open one (or close all) programmatically; fires `onSelect` like a click would. */\n select(hotspot: Hotspot | null): void;\n /** Remove the listeners. Does not dispose the hotspots. */\n dispose(): void;\n};\n\n/** How far a pointer may travel between down and up and still be a click, in\n * CSS pixels: an orbit drag that happens to end on an orb is not a pick. */\nconst CLICK_SLOP_PX = 6;\n\n/**\n * Wire hover and click for a set of hotspots on one canvas.\n *\n * Raycasts the heads (core and halo, ring or glass, and the label, so the\n * target is a little generous) from the pointer through `camera`; sets\n * `cursor: pointer` over one; opens it on click and closes the one that was\n * open. Nothing here is a render loop: call `update()` from yours.\n */\nexport function attachHotspots(\n options: AttachHotspotsOptions,\n): AttachedHotspots {\n const { hotspots, camera, domElement, onSelect, onHover } = options;\n const raycaster = new Raycaster();\n const pointer = new Vector2();\n const targets = new Map<Object3D, Hotspot>();\n for (const hotspot of hotspots) {\n const { core, halo, ring, shell, label } = hotspotParts(hotspot);\n for (const mesh of [core, halo, ring, shell, label])\n if (mesh) targets.set(mesh, hotspot);\n }\n\n let selected: Hotspot | null =\n hotspots.find((hotspot) => hotspot.state === 'open') ?? null;\n let hovered: Hotspot | null = null;\n let downAt: { x: number; y: number } | null = null;\n let previousCursor: string | null = null;\n\n const pick = (event: PointerEvent): Hotspot | null => {\n const rect = domElement.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n pointer.set(\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\n -((event.clientY - rect.top) / rect.height) * 2 + 1,\n );\n raycaster.setFromCamera(pointer, camera);\n const hits = raycaster.intersectObjects([...targets.keys()], false);\n for (const hit of hits) {\n const hotspot = targets.get(hit.object);\n // A label only counts while it is showing.\n if (\n hit.object === hotspotParts(hotspot!).label &&\n ((hit.object as Mesh).material as Material).opacity < 0.05\n )\n continue;\n if (hotspot && hotspot.object.visible && hotspot.state !== 'hidden')\n return hotspot;\n }\n return null;\n };\n\n const setHovered = (next: Hotspot | null): void => {\n if (next === hovered) return;\n hovered?.setHovered(false);\n hovered = next;\n hovered?.setHovered(true);\n if (hovered) {\n if (previousCursor === null) previousCursor = domElement.style.cursor;\n domElement.style.cursor = 'pointer';\n } else if (previousCursor !== null) {\n domElement.style.cursor = previousCursor;\n previousCursor = null;\n }\n onHover?.(hovered);\n };\n\n const select = (next: Hotspot | null): void => {\n if (next === selected) return;\n selected?.setSelected(false);\n selected = next;\n selected?.setSelected(true);\n onSelect?.(selected);\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n // A finger has no hover: a tap is a click, and a label shows on open.\n if (event.pointerType === 'touch') return;\n setHovered(pick(event));\n };\n const onPointerLeave = (): void => setHovered(null);\n const onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0) return;\n downAt = { x: event.clientX, y: event.clientY };\n };\n const onPointerUp = (event: PointerEvent): void => {\n if (!downAt || event.button !== 0) return;\n const moved = Math.hypot(\n event.clientX - downAt.x,\n event.clientY - downAt.y,\n );\n downAt = null;\n if (moved > CLICK_SLOP_PX) return;\n const hit = pick(event);\n // Clicking the open orb closes it; clicking empty space closes too.\n select(hit === selected ? null : hit);\n };\n\n // Guarded so a hotspot set can be built where there is no DOM (a test, a\n // server) and simply never receive a pointer.\n const listens = typeof domElement?.addEventListener === 'function';\n if (listens) {\n domElement.addEventListener('pointermove', onPointerMove);\n domElement.addEventListener('pointerleave', onPointerLeave);\n domElement.addEventListener('pointerdown', onPointerDown);\n domElement.addEventListener('pointerup', onPointerUp);\n }\n\n return {\n get selected() {\n return selected;\n },\n select,\n update(seconds) {\n for (const hotspot of hotspots) {\n hotspot.fit(camera);\n hotspot.update(seconds);\n }\n },\n dispose() {\n if (listens) {\n domElement.removeEventListener('pointermove', onPointerMove);\n domElement.removeEventListener('pointerleave', onPointerLeave);\n domElement.removeEventListener('pointerdown', onPointerDown);\n domElement.removeEventListener('pointerup', onPointerUp);\n }\n setHovered(null);\n hovered = null;\n },\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -485,7 +485,7 @@ declare class BakeJob extends PolledJob<BakeRecord, BakeOutput, BakeJobEvents> {
485
485
  }
486
486
 
487
487
  /** The published version. Must equal the version in package.json. */
488
- declare const SDK_VERSION = "0.2.0";
488
+ declare const SDK_VERSION = "0.3.0";
489
489
 
490
490
  /**
491
491
  * TSL to a renderer-neutral shader graph.
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
- export { BakeJob, RenderJob, createBakery3 } from './chunk-6FYI6AJM.js';
1
+ export { BakeJob, RenderJob, createBakery3 } from './chunk-6FAMQZXB.js';
2
2
  import './chunk-XK35ANPJ.js';
3
- export { Batch } from './chunk-NXBAZGNB.js';
3
+ export { Batch } from './chunk-X6GW43EX.js';
4
4
  export { RenderSet, RenderSetRefused } from './chunk-ZEBVAIJJ.js';
5
- export { Timeline, analyzeScene, createTimeline, extractMaterialShader, isNodeMaterial, timelineFromGsap, timelineFromTheatre } from './chunk-Z7IYVH22.js';
5
+ export { Timeline, analyzeScene, createTimeline, extractMaterialShader, isNodeMaterial, timelineFromGsap, timelineFromTheatre } from './chunk-WLEFNUOH.js';
6
6
  import './chunk-62M6XXNX.js';
7
- export { SDK_VERSION } from './chunk-UWBP7B54.js';
7
+ export { SDK_VERSION } from './chunk-R5IUPOWI.js';
8
8
  import './chunk-S4AJTLLN.js';
9
9
  export { rememberEnvironmentSource } from './chunk-KZLVTSBI.js';
10
- export { shouldExclude } from './chunk-JFYUDERE.js';
11
- import './chunk-APWUCEEB.js';
10
+ export { shouldExclude } from './chunk-NEK5TBEH.js';
11
+ import './chunk-EN4ROBYQ.js';
12
12
  import './chunk-LAKXC4WR.js';
13
13
  export { Bakery3Error, BatchPageRefused, RenderBudgetExceeded } from './chunk-3G5QL4F4.js';
14
+ import './chunk-OPM2L63B.js';
14
15
  //# sourceMappingURL=index.js.map
15
16
  //# sourceMappingURL=index.js.map
@@ -240,7 +240,7 @@ var BatchPageRefused = class extends Bakery3Error {
240
240
  };
241
241
 
242
242
  // src/version.ts
243
- var SDK_VERSION = "0.2.0";
243
+ var SDK_VERSION = "0.3.0";
244
244
 
245
245
  // src/warn.ts
246
246
  var warned = /* @__PURE__ */ new Set();