@particle-academy/fancy-3d-babylon 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.
- package/README.md +64 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/engine.cjs +59 -0
- package/dist/engine.cjs.map +1 -0
- package/dist/engine.d.cts +19 -0
- package/dist/engine.d.ts +19 -0
- package/dist/engine.js +52 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.cjs +861 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +323 -0
- package/dist/index.d.ts +323 -0
- package/dist/index.js +836 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +315 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +60 -0
- package/dist/react.d.ts +60 -0
- package/dist/react.js +311 -0
- package/dist/react.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/painters.ts","../src/primitives.ts","../src/layouts.ts","../src/index.ts"],"names":["box","Vector3","DynamicTexture","StandardMaterial","Color3","MeshBuilder"],"mappings":"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","file":"index.js","sourcesContent":["import type { WidgetSpec } from \"@particle-academy/fancy-3d\";\n\nexport const TEX_SCALE = 2; // retina-ish texture sharpness\n\n/** Scale factor against the painters' design-time canvas (240px tall). All\n * widget painters multiply their padding / font sizes by this so the layout\n * looks the same at any pixel resolution. */\nfunction unitOf(_w: number, h: number): number {\n return h / 240;\n}\n\nfunction paintCardBg(ctx: CanvasRenderingContext2D, w: number, h: number, selected: boolean) {\n const u = unitOf(w, h);\n ctx.fillStyle = \"#0f172a\";\n roundRect(ctx, 0, 0, w, h, 14 * u);\n ctx.fill();\n ctx.strokeStyle = selected ? \"#6366f1\" : \"#1e293b\";\n ctx.lineWidth = (selected ? 4 : 2) * u;\n ctx.stroke();\n}\n\nfunction roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.arcTo(x + w, y, x + w, y + h, r);\n ctx.arcTo(x + w, y + h, x, y + h, r);\n ctx.arcTo(x, y + h, x, y, r);\n ctx.arcTo(x, y, x + w, y, r);\n ctx.closePath();\n}\n\nfunction paintLabel(ctx: CanvasRenderingContext2D, text: string, x: number, y: number) {\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.textBaseline = \"top\";\n ctx.fillText(text.toUpperCase(), x, y);\n}\n\nfunction paintSparkline(ctx: CanvasRenderingContext2D, values: number[], x: number, y: number, w: number, h: number, variant: \"line\" | \"bar\" | \"area\", color: string) {\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = max - min || 1;\n const step = w / Math.max(values.length - 1, 1);\n\n if (variant === \"bar\") {\n const bw = w / values.length - 4;\n ctx.fillStyle = color;\n values.forEach((v, i) => {\n const bh = ((v - min) / range) * h;\n ctx.fillRect(x + i * (bw + 4), y + h - bh, bw, Math.max(bh, 1));\n });\n return;\n }\n\n ctx.beginPath();\n values.forEach((v, i) => {\n const px = x + i * step;\n const py = y + h - ((v - min) / range) * h;\n if (i === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n });\n\n if (variant === \"area\") {\n ctx.lineTo(x + w, y + h);\n ctx.lineTo(x, y + h);\n ctx.closePath();\n ctx.fillStyle = color + \"44\";\n ctx.fill();\n ctx.beginPath();\n values.forEach((v, i) => {\n const px = x + i * step;\n const py = y + h - ((v - min) / range) * h;\n if (i === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n });\n }\n\n ctx.strokeStyle = color;\n ctx.lineWidth = 3;\n ctx.stroke();\n}\nexport function paintWidget(ctx: CanvasRenderingContext2D, spec: WidgetSpec, w: number, h: number, selected: boolean) {\n paintCardBg(ctx, w, h, selected);\n const pad = 20;\n\n switch (spec.kind) {\n case \"kpi\": {\n paintLabel(ctx, spec.label, pad, pad);\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"700 56px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.value, pad, pad + 32);\n if (spec.delta) {\n ctx.fillStyle = spec.trend === \"up\" ? \"#10b981\" : spec.trend === \"down\" ? \"#f43f5e\" : \"#94a3b8\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.delta, pad, pad + 92);\n }\n break;\n }\n case \"chart\": {\n paintLabel(ctx, spec.title, pad, pad);\n paintSparkline(ctx, spec.series, pad, pad + 36, w - pad * 2, h - pad * 2 - 36, spec.variant, spec.color ?? \"#6366f1\");\n break;\n }\n case \"kanban\": {\n const colW = (w - pad * 2 - (spec.columns.length - 1) * 10) / spec.columns.length;\n spec.columns.forEach((col, i) => {\n const cx = pad + i * (colW + 10);\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, cx, pad, colW, h - pad * 2, 8);\n ctx.fill();\n paintLabel(ctx, col.title, cx + 8, pad + 10);\n col.cards.forEach((c, j) => {\n ctx.fillStyle = \"#0f172a\";\n roundRect(ctx, cx + 8, pad + 44 + j * 38, colW - 16, 30, 6);\n ctx.fill();\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"500 20px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(c, cx + 16, pad + 50 + j * 38);\n });\n });\n break;\n }\n case \"table\": {\n paintLabel(ctx, spec.title, pad, pad);\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"600 18px ui-sans-serif, system-ui, sans-serif\";\n const colW = (w - pad * 2) / spec.columns.length;\n spec.columns.forEach((c, i) => ctx.fillText(c, pad + i * colW, pad + 38));\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n spec.rows.forEach((row, ri) => {\n row.forEach((cell, ci) => ctx.fillText(String(cell), pad + ci * colW, pad + 70 + ri * 28));\n });\n break;\n }\n case \"profile\": {\n ctx.fillStyle = \"#6366f1\";\n ctx.beginPath();\n ctx.arc(pad + 30, pad + 30, 28, 0, Math.PI * 2);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.font = \"700 24px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(spec.initials, pad + 30, pad + 22);\n ctx.textAlign = \"left\";\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"600 24px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.name, pad + 76, pad + 12);\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"400 20px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.role, pad + 76, pad + 40);\n if (spec.status) {\n ctx.fillStyle = spec.status === \"online\" ? \"#10b981\" : spec.status === \"away\" ? \"#f59e0b\" : \"#64748b\";\n ctx.beginPath();\n ctx.arc(pad + 50, pad + 50, 6, 0, Math.PI * 2);\n ctx.fill();\n }\n break;\n }\n case \"callout\": {\n const tone = spec.tone === \"danger\" ? \"#f43f5e\" : spec.tone === \"warning\" ? \"#f59e0b\" : spec.tone === \"success\" ? \"#10b981\" : \"#3b82f6\";\n ctx.fillStyle = tone + \"22\";\n roundRect(ctx, 4, 4, w - 8, h - 8, 12);\n ctx.fill();\n ctx.fillStyle = tone;\n ctx.fillRect(12, 12, 4, h - 24);\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.title, 28, pad);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n wrapText(ctx, spec.body, 28, pad + 32, w - 40, 22);\n break;\n }\n case \"form\": {\n paintLabel(ctx, spec.title, pad, pad);\n spec.fields.forEach((f, i) => {\n const y = pad + 40 + i * 44;\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"500 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(f.label, pad, y);\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, w - pad - 100, y - 4, 100, 28, 6);\n ctx.fill();\n if (f.type === \"switch\") {\n ctx.fillStyle = \"#6366f1\";\n roundRect(ctx, w - pad - 60, y - 4, 60, 28, 14);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.beginPath();\n ctx.arc(w - pad - 18, y + 10, 10, 0, Math.PI * 2);\n ctx.fill();\n }\n });\n break;\n }\n case \"action\": {\n paintLabel(ctx, spec.title, pad, pad);\n let bx = pad;\n const by = pad + 40;\n spec.buttons.forEach((b) => {\n const tw = ctx.measureText(b.label).width + 24;\n ctx.fillStyle = b.variant === \"primary\" ? \"#6366f1\" : b.variant === \"ghost\" ? \"transparent\" : \"#1e293b\";\n if (b.variant !== \"ghost\") {\n roundRect(ctx, bx, by, tw, 36, 8);\n ctx.fill();\n }\n ctx.fillStyle = b.variant === \"primary\" ? \"#fff\" : \"#cbd5e1\";\n ctx.font = \"600 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(b.label, bx + 12, by + 9);\n bx += tw + 8;\n });\n break;\n }\n case \"timeline\": {\n paintLabel(ctx, spec.title, pad, pad);\n spec.events.forEach((e, i) => {\n const y = pad + 40 + i * 32;\n ctx.fillStyle = \"#6366f1\";\n ctx.beginPath();\n ctx.arc(pad + 4, y + 10, 4, 0, Math.PI * 2);\n ctx.fill();\n ctx.strokeStyle = \"#1e293b\";\n if (i < spec.events.length - 1) {\n ctx.beginPath();\n ctx.moveTo(pad + 4, y + 14);\n ctx.lineTo(pad + 4, y + 32);\n ctx.stroke();\n }\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"500 14px ui-monospace, monospace\";\n ctx.fillText(e.at, pad + 16, y);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(e.label, pad + 60, y);\n });\n break;\n }\n case \"code\": {\n paintLabel(ctx, spec.title, pad, pad);\n ctx.fillStyle = \"#020617\";\n roundRect(ctx, pad, pad + 36, w - pad * 2, h - pad * 2 - 36, 8);\n ctx.fill();\n ctx.fillStyle = \"#a5b4fc\";\n ctx.font = \"400 16px ui-monospace, monospace\";\n const lines = spec.code.split(\"\\n\");\n lines.forEach((ln, i) => ctx.fillText(ln, pad + 14, pad + 56 + i * 22));\n break;\n }\n case \"image\": {\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, pad, pad, w - pad * 2, h - pad * 2, 8);\n ctx.fill();\n ctx.fillStyle = \"#64748b\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(spec.alt, w / 2, h / 2);\n ctx.textAlign = \"left\";\n break;\n }\n case \"text\": {\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"700 26px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.heading, pad, pad);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n wrapText(ctx, spec.body, pad, pad + 38, w - pad * 2, 22);\n break;\n }\n case \"screen\": {\n const bezel = spec.bezel ?? \"#0b0f17\";\n const t = spec.bezelThickness ?? 14;\n const on = spec.on ?? true;\n const brightness = spec.brightness ?? (on ? 1 : 0.06);\n const bg = spec.background ?? \"#020617\";\n\n // Outer bezel\n ctx.fillStyle = bezel;\n roundRect(ctx, 0, 0, w, h, 18);\n ctx.fill();\n // Inner screen area\n const sx = t;\n const sy = t;\n const sw = w - t * 2;\n const sh = h - t * 2;\n ctx.save();\n ctx.fillStyle = bg;\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.fill();\n ctx.beginPath();\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.clip();\n ctx.translate(sx, sy);\n // Apply brightness as global alpha multiplier\n ctx.globalAlpha = brightness;\n const c = spec.content;\n if (c.type === \"label\") {\n ctx.fillStyle = \"#e2e8f0\";\n ctx.font = \"700 32px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(c.title, sw / 2, sh / 2 - (c.subtitle ? 16 : 0));\n if (c.subtitle) {\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(c.subtitle, sw / 2, sh / 2 + 18);\n }\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n } else if (c.type === \"paint\") {\n c.paint(ctx, sw, sh);\n } else if (c.type === \"image\") {\n // Image content is best painted by the consumer via \"paint\" — labels\n // serve as a fallback so the screen still has identifiable content.\n ctx.fillStyle = \"#475569\";\n ctx.font = \"500 16px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(c.alt ?? \"image\", sw / 2, sh / 2);\n ctx.textAlign = \"left\";\n }\n ctx.globalAlpha = 1;\n ctx.restore();\n // Power LED\n ctx.fillStyle = on ? \"#10b981\" : \"#475569\";\n ctx.beginPath();\n ctx.arc(w - t - 6, h - t - 6, 4, 0, Math.PI * 2);\n ctx.fill();\n // Subtle glass reflection\n const grad = ctx.createLinearGradient(sx, sy, sx, sy + sh);\n grad.addColorStop(0, \"rgba(255,255,255,0.08)\");\n grad.addColorStop(0.4, \"rgba(255,255,255,0)\");\n ctx.fillStyle = grad;\n ctx.beginPath();\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.fill();\n break;\n }\n case \"demoPage\": {\n const u = unitOf(w, h);\n const padX = w * 0.06;\n const headerH = h * 0.22;\n const titleY = headerH + h * 0.12;\n const titleSize = h * 0.16;\n const descY = titleY + titleSize * 0.6;\n const descSize = h * 0.072;\n const descLine = descSize * 1.4;\n const chipSize = h * 0.052;\n const pathSize = h * 0.052;\n const ctaSize = h * 0.075;\n const ctaH = ctaSize * 2;\n\n // Accent header bar — slightly overlaps card top to visually anchor\n ctx.fillStyle = spec.accent;\n roundRect(ctx, 0, 0, w, headerH, 14 * u);\n ctx.fill();\n // Squared bottom on the accent bar (cancel rounded bottom corners)\n ctx.fillRect(0, headerH - 14 * u, w, 14 * u);\n\n // Category chip\n ctx.fillStyle = \"rgba(255,255,255,0.22)\";\n const chipText = spec.category.toUpperCase();\n ctx.font = `700 ${chipSize}px ui-sans-serif, system-ui, sans-serif`;\n ctx.textBaseline = \"top\";\n const chipPad = chipSize * 0.7;\n const chipW = ctx.measureText(chipText).width + chipPad * 2;\n const chipH = chipSize * 1.85;\n const chipY = (headerH - chipH) / 2;\n roundRect(ctx, padX, chipY, chipW, chipH, chipH / 2);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.fillText(chipText, padX + chipPad, chipY + (chipH - chipSize) / 2);\n\n // Path on right\n ctx.fillStyle = \"rgba(255,255,255,0.9)\";\n ctx.font = `500 ${pathSize}px ui-monospace, monospace`;\n const pathW = ctx.measureText(spec.path).width;\n ctx.fillText(spec.path, w - padX - pathW, chipY + (chipH - chipSize) / 2);\n\n // Title\n ctx.fillStyle = \"#f8fafc\";\n ctx.font = `800 ${titleSize}px ui-sans-serif, system-ui, sans-serif`;\n ctx.fillText(spec.name, padX, titleY);\n\n // Description (wrapped, clipped before reaching the CTA)\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = `400 ${descSize}px ui-sans-serif, system-ui, sans-serif`;\n const ctaY = h - padX - ctaH;\n wrapText(ctx, spec.description, padX, descY, w - padX * 2, descLine, ctaY - descLine);\n\n // CTA at bottom\n ctx.fillStyle = spec.accent;\n const ctaText = \"Open demo →\";\n ctx.font = `600 ${ctaSize}px ui-sans-serif, system-ui, sans-serif`;\n const ctaTextPad = ctaSize * 0.9;\n const ctaW = ctx.measureText(ctaText).width + ctaTextPad * 2;\n roundRect(ctx, padX, ctaY, ctaW, ctaH, ctaH * 0.25);\n ctx.fill();\n ctx.fillStyle = \"#0f172a\";\n ctx.fillText(ctaText, padX + ctaTextPad, ctaY + (ctaH - ctaSize) / 2);\n ctx.textBaseline = \"alphabetic\";\n break;\n }\n }\n}\n\nfunction wrapText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n maxW: number,\n lineH: number,\n maxY?: number\n) {\n const words = text.split(\" \");\n let line = \"\";\n let yy = y;\n for (const word of words) {\n const test = line ? `${line} ${word}` : word;\n if (ctx.measureText(test).width > maxW && line) {\n if (maxY !== undefined && yy > maxY) return;\n ctx.fillText(line, x, yy);\n line = word;\n yy += lineH;\n } else {\n line = test;\n }\n }\n if (line && (maxY === undefined || yy <= maxY)) ctx.fillText(line, x, yy);\n}\n","/**\n * 3D shape primitives for `@particle-academy/fancy-3d`.\n *\n * A primitive is a Babylon mesh that can host UI content on its surface —\n * either a flat color, a freeform 2D paint callback, or a `WidgetSpec`\n * rendered through the same painters as the Babylon adapter.\n *\n * Every primitive returns a `Mesh`, ready to position in your scene.\n */\nimport {\n Color3,\n DynamicTexture,\n Mesh,\n MeshBuilder,\n StandardMaterial,\n Vector3,\n Vector4,\n type Scene,\n} from \"@babylonjs/core\";\nimport type { WidgetSpec } from \"@particle-academy/fancy-3d\";\nimport { TEX_SCALE, paintWidget } from \"./painters\";\n\nexport type PaintFn = (ctx: CanvasRenderingContext2D, width: number, height: number) => void;\n\nexport type SurfaceContent =\n | { type: \"color\"; color: string }\n | { type: \"paint\"; paint: PaintFn; pixelWidth?: number; pixelHeight?: number; transparent?: boolean }\n | { type: \"widget\"; widget: WidgetSpec; pixelWidth?: number; pixelHeight?: number; selected?: boolean };\n\n/** Default pixel density when a primitive auto-sizes a widget surface from\n * world-space dimensions (1 world unit ≈ 1 meter). Higher values produce\n * sharper textures at the cost of GPU memory. */\nconst DEFAULT_DENSITY = 120;\nconst MAX_TEXTURE_AXIS = 1024;\n\nfunction autoPixelSize(worldWidth: number, worldHeight: number, density = DEFAULT_DENSITY) {\n let w = Math.max(96, Math.round(worldWidth * density));\n let h = Math.max(96, Math.round(worldHeight * density));\n const scale = Math.min(1, MAX_TEXTURE_AXIS / Math.max(w, h));\n if (scale < 1) {\n w = Math.round(w * scale);\n h = Math.round(h * scale);\n }\n return { w, h };\n}\n\ninterface SurfaceTexture {\n material: StandardMaterial;\n texture: DynamicTexture | null;\n}\n\nfunction buildSurface(\n scene: Scene,\n name: string,\n surface: SurfaceContent,\n autoSize?: { worldWidth: number; worldHeight: number }\n): SurfaceTexture {\n const mat = new StandardMaterial(`${name}-mat`, scene);\n mat.specularColor = new Color3(0.05, 0.05, 0.05);\n\n if (surface.type === \"color\") {\n mat.diffuseColor = Color3.FromHexString(surface.color);\n mat.emissiveColor = Color3.FromHexString(surface.color).scale(0.15);\n return { material: mat, texture: null };\n }\n\n let w = surface.pixelWidth;\n let h = surface.pixelHeight;\n if ((w == null || h == null) && autoSize) {\n const auto = autoPixelSize(autoSize.worldWidth, autoSize.worldHeight);\n w = w ?? auto.w;\n h = h ?? auto.h;\n }\n w = w ?? 512;\n h = h ?? 512;\n const tex = new DynamicTexture(`${name}-tex`, { width: w * TEX_SCALE, height: h * TEX_SCALE }, scene, true);\n // Babylon plane UVs run V=0 at the bottom; canvas Y runs top-to-bottom.\n tex.vScale = -1;\n tex.vOffset = 1;\n if (surface.type === \"paint\" && surface.transparent) {\n tex.hasAlpha = true;\n }\n if (surface.type === \"widget\") {\n tex.hasAlpha = true;\n }\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n if (surface.type === \"paint\") {\n surface.paint(ctx, w, h);\n } else {\n paintWidget(ctx, surface.widget, w, h, surface.selected ?? false);\n }\n tex.update(false);\n\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(0.6, 0.6, 0.6);\n if (tex.hasAlpha) mat.useAlphaFromDiffuseTexture = true;\n\n return { material: mat, texture: tex };\n}\n\n/* ------------------------------------------------------------------ */\n/* Panel — flat 2D plane with one surface */\n/* ------------------------------------------------------------------ */\n\nexport interface PanelOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n surface: SurfaceContent;\n /** Babylon sideOrientation. Use `Mesh.DOUBLESIDE` for panels you want visible\n * from both directions (e.g. self-luminous screens). Default is FRONTSIDE. */\n sideOrientation?: number;\n}\n\nexport function createPanel(opts: PanelOpts): Mesh {\n const name = opts.name ?? \"panel\";\n const m = MeshBuilder.CreatePlane(name, { width: opts.width, height: opts.height, sideOrientation: opts.sideOrientation }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Billboard — panel that can be set to always face the camera */\n/* ------------------------------------------------------------------ */\n\nexport interface BillboardOpts extends PanelOpts {\n /** When true, mesh.billboardMode = ALL — always faces the camera. */\n faceCamera?: boolean;\n}\n\nexport function createBillboard(opts: BillboardOpts): Mesh {\n const m = createPanel({ ...opts, name: opts.name ?? \"billboard\" });\n if (opts.faceCamera) {\n m.billboardMode = Mesh.BILLBOARDMODE_ALL;\n }\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Building — rectangular box with optional facade texture */\n/* ------------------------------------------------------------------ */\n\nexport interface BuildingOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n depth: number;\n /** Surface applied to all 6 faces (cheap path). */\n surface?: SurfaceContent;\n /** Per-face surfaces; missing faces use `surface` or a default grey. */\n faces?: Partial<Record<BoxFace, SurfaceContent>>;\n}\n\n/** Babylon box face indices (CreateBox): 0=front (-Z), 1=back (+Z), 2=right (+X), 3=left (-X), 4=top (+Y), 5=bottom (-Y). */\nexport type BoxFace = \"front\" | \"back\" | \"right\" | \"left\" | \"top\" | \"bottom\";\n\nconst BOX_FACE_ORDER: BoxFace[] = [\"front\", \"back\", \"right\", \"left\", \"top\", \"bottom\"];\n\nexport function createBuilding(opts: BuildingOpts): Mesh {\n const name = opts.name ?? \"building\";\n // If only a single uniform surface is given, take the cheap path.\n if (opts.surface && !opts.faces) {\n const box = MeshBuilder.CreateBox(name, { width: opts.width, height: opts.height, depth: opts.depth }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n box.material = material;\n return box;\n }\n\n // Per-face surfaces — Babylon's CreateBox supports `faceUV` to map sub-rects\n // of a single texture onto each face. We composite 6 sub-textures into one.\n const faceW = 256;\n const faceH = 256;\n const atlasW = faceW * 3;\n const atlasH = faceH * 2;\n const tex = new DynamicTexture(`${name}-atlas`, { width: atlasW * TEX_SCALE, height: atlasH * TEX_SCALE }, opts.scene, true);\n tex.vScale = -1;\n tex.vOffset = 1;\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n\n const faceUV: Vector4[] = [];\n BOX_FACE_ORDER.forEach((face, i) => {\n const col = i % 3;\n const row = Math.floor(i / 3);\n const fx = col * faceW;\n const fy = row * faceH;\n const surface = opts.faces?.[face] ?? opts.surface ?? { type: \"color\", color: \"#475569\" };\n ctx.save();\n ctx.translate(fx, fy);\n if (surface.type === \"color\") {\n ctx.fillStyle = surface.color;\n ctx.fillRect(0, 0, faceW, faceH);\n } else if (surface.type === \"paint\") {\n surface.paint(ctx, faceW, faceH);\n } else {\n paintWidget(ctx, surface.widget, faceW, faceH, surface.selected ?? false);\n }\n ctx.restore();\n\n // UV rect for this face within the atlas.\n faceUV.push(new Vector4(fx / atlasW, 1 - (fy + faceH) / atlasH, (fx + faceW) / atlasW, 1 - fy / atlasH));\n });\n tex.update(false);\n\n const mat = new StandardMaterial(`${name}-mat`, opts.scene);\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(0.4, 0.4, 0.4);\n mat.specularColor = new Color3(0.05, 0.05, 0.05);\n\n const box = MeshBuilder.CreateBox(name, {\n width: opts.width,\n height: opts.height,\n depth: opts.depth,\n faceUV,\n wrap: true,\n }, opts.scene);\n box.material = mat;\n return box;\n}\n\n/* ------------------------------------------------------------------ */\n/* Pillar — alias for a tall narrow building */\n/* ------------------------------------------------------------------ */\n\nexport interface PillarOpts {\n scene: Scene;\n name?: string;\n thickness: number;\n height: number;\n surface?: SurfaceContent;\n}\n\nexport function createPillar(opts: PillarOpts): Mesh {\n return createBuilding({\n scene: opts.scene,\n name: opts.name ?? \"pillar\",\n width: opts.thickness,\n depth: opts.thickness,\n height: opts.height,\n surface: opts.surface,\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Cylinder — tube with content wrapping the side */\n/* ------------------------------------------------------------------ */\n\nexport interface CylinderOpts {\n scene: Scene;\n name?: string;\n radius: number;\n height: number;\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createCylinder(opts: CylinderOpts): Mesh {\n const name = opts.name ?? \"cylinder\";\n const m = MeshBuilder.CreateCylinder(name, {\n diameter: opts.radius * 2,\n height: opts.height,\n tessellation: opts.tessellation ?? 48,\n }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.radius * 2 * Math.PI,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* CurvedPanel — a partial cylindrical sheet (like a wraparound ad) */\n/* ------------------------------------------------------------------ */\n\nexport interface CurvedPanelOpts {\n scene: Scene;\n name?: string;\n width: number; // arc length\n height: number;\n arc: number; // radians spanned\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createCurvedPanel(opts: CurvedPanelOpts): Mesh {\n const name = opts.name ?? \"curved-panel\";\n const radius = opts.width / opts.arc;\n // Build by creating a partial cylinder (arc fraction) with no caps.\n const tess = opts.tessellation ?? 48;\n const fullCircleSegments = Math.max(8, Math.ceil((tess * (Math.PI * 2)) / opts.arc));\n const m = MeshBuilder.CreateCylinder(name, {\n diameter: radius * 2,\n height: opts.height,\n tessellation: fullCircleSegments,\n arc: opts.arc / (Math.PI * 2),\n cap: Mesh.NO_CAP,\n sideOrientation: Mesh.DOUBLESIDE,\n }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Sphere — full sphere with equirectangular surface */\n/* ------------------------------------------------------------------ */\n\nexport interface SphereOpts {\n scene: Scene;\n name?: string;\n diameter: number;\n surface: SurfaceContent;\n segments?: number;\n}\n\nexport function createSphere(opts: SphereOpts): Mesh {\n const name = opts.name ?? \"sphere\";\n const m = MeshBuilder.CreateSphere(name, { diameter: opts.diameter, segments: opts.segments ?? 32 }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.diameter * Math.PI,\n worldHeight: opts.diameter * Math.PI / 2,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Disc — flat disc/circle */\n/* ------------------------------------------------------------------ */\n\nexport interface DiscOpts {\n scene: Scene;\n name?: string;\n radius: number;\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createDisc(opts: DiscOpts): Mesh {\n const name = opts.name ?? \"disc\";\n const m = MeshBuilder.CreateDisc(name, { radius: opts.radius, tessellation: opts.tessellation ?? 64 }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.radius * 2,\n worldHeight: opts.radius * 2,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Card3D — an extruded panel (gives panels physical depth) */\n/* ------------------------------------------------------------------ */\n\nexport interface Card3DOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n /** Extrusion depth. Defaults to a thin 0.06 — like real foam-board signage. */\n depth?: number;\n /** Surface for the front face (the visible UI). */\n front: SurfaceContent;\n /** Surface for the side and back faces. Defaults to a dark color. */\n edge?: SurfaceContent;\n}\n\nexport function createCard3D(opts: Card3DOpts): Mesh {\n const name = opts.name ?? \"card3d\";\n const depth = opts.depth ?? 0.06;\n const edge = opts.edge ?? { type: \"color\" as const, color: \"#0b0f17\" };\n return createBuilding({\n scene: opts.scene,\n name,\n width: opts.width,\n height: opts.height,\n depth,\n faces: {\n front: opts.front,\n back: edge,\n top: edge,\n bottom: edge,\n left: edge,\n right: edge,\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Sign — a panel mounted on a post */\n/* ------------------------------------------------------------------ */\n\nexport interface SignOpts {\n scene: Scene;\n name?: string;\n /** Panel dimensions. */\n width: number;\n height: number;\n /** How tall the post is (from ground to bottom of panel). */\n postHeight?: number;\n /** Post thickness (square cross-section). */\n postThickness?: number;\n /** Panel surface (color, paint, or widget). */\n surface: SurfaceContent;\n /** Post color. */\n postColor?: string;\n}\n\nexport interface SignResult {\n /** Group containing the panel + post, parented at ground level. */\n root: Mesh;\n panel: Mesh;\n post: Mesh;\n}\n\nexport function createSign(opts: SignOpts): SignResult {\n const name = opts.name ?? \"sign\";\n const postHeight = opts.postHeight ?? 1.4;\n const postThickness = opts.postThickness ?? 0.12;\n const postColor = opts.postColor ?? \"#1f2937\";\n\n const root = new Mesh(`${name}-root`, opts.scene);\n\n const panel = createBillboard({\n scene: opts.scene,\n name: `${name}-panel`,\n width: opts.width,\n height: opts.height,\n surface: opts.surface,\n });\n panel.position = new Vector3(0, postHeight + opts.height / 2, 0);\n panel.parent = root;\n\n const post = MeshBuilder.CreateBox(`${name}-post`, {\n width: postThickness,\n height: postHeight,\n depth: postThickness,\n }, opts.scene);\n post.position = new Vector3(0, postHeight / 2, 0);\n const postMat = new StandardMaterial(`${name}-post-mat`, opts.scene);\n postMat.diffuseColor = Color3.FromHexString(postColor);\n post.material = postMat;\n post.parent = root;\n\n return { root, panel, post };\n}\n\n/* ------------------------------------------------------------------ */\n/* Monitor — a 3D display: extruded bezel + recessed screen face */\n/* ------------------------------------------------------------------ */\n\nexport interface MonitorOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n /** Front-to-back depth of the display chassis. Defaults to 0.18. */\n depth?: number;\n /** Bezel color. Defaults to near-black. */\n bezel?: string;\n /** Screen surface — color, paint, or widget. */\n screen: SurfaceContent;\n /** Optional kickstand height — when set, the monitor sits on a base. */\n standHeight?: number;\n}\n\nexport interface MonitorResult {\n root: Mesh;\n body: Mesh;\n screen: Mesh;\n stand?: Mesh;\n}\n\nexport function createMonitor(opts: MonitorOpts): MonitorResult {\n const name = opts.name ?? \"monitor\";\n const depth = opts.depth ?? 0.18;\n const bezelColor = opts.bezel ?? \"#0b0f17\";\n\n const root = new Mesh(`${name}-root`, opts.scene);\n\n // Body — extruded bezel\n const body = MeshBuilder.CreateBox(`${name}-body`, {\n width: opts.width,\n height: opts.height,\n depth,\n }, opts.scene);\n const bodyMat = new StandardMaterial(`${name}-body-mat`, opts.scene);\n bodyMat.diffuseColor = Color3.FromHexString(bezelColor);\n bodyMat.specularColor = new Color3(0.08, 0.08, 0.08);\n body.material = bodyMat;\n body.parent = root;\n\n // Screen face — sits flush at the front (+Z) face of the bezel.\n // Babylon's default plane has its visible face on -Z (per the docs:\n // \"default plane faces the negative Z direction\"). The default\n // ArcRotateCamera sits at +Z, so we need the screen's visible face to\n // point +Z. `BACKSIDE` orientation flips visibility from -Z to +Z without\n // rotating the plane (which would also mirror the texture). The screen\n // sits 0.001 in front of the body's +Z face so it's not occluded.\n const screenInset = 0.04;\n const screenW = opts.width - screenInset * 2;\n const screenH = opts.height - screenInset * 2;\n // Use a very thin extruded card for the screen face. This delegates to\n // createBuilding's per-face Box atlas, which handles UV orientation\n // correctly out of the box (a flat Plane's UVs render mirrored from the\n // default camera angle without orientation gymnastics).\n const screen = createCard3D({\n scene: opts.scene,\n name: `${name}-screen`,\n width: screenW,\n height: screenH,\n depth: 0.01,\n front: opts.screen,\n edge: { type: \"color\", color: bezelColor },\n });\n screen.position = new Vector3(0, 0, depth / 2 + 0.005);\n screen.parent = root;\n\n let stand: Mesh | undefined;\n if (opts.standHeight && opts.standHeight > 0) {\n stand = MeshBuilder.CreateBox(`${name}-stand`, {\n width: opts.width * 0.3,\n height: opts.standHeight,\n depth: depth * 1.5,\n }, opts.scene);\n stand.position = new Vector3(0, -opts.height / 2 - opts.standHeight / 2, 0);\n stand.material = bodyMat;\n stand.parent = root;\n }\n\n return { root, body, screen, stand };\n}\n\n/* ------------------------------------------------------------------ */\n/* Decal — project a 2D pattern onto another mesh's surface */\n/* ------------------------------------------------------------------ */\n\nexport interface DecalOpts {\n scene: Scene;\n name?: string;\n /** The mesh to project the decal onto. */\n target: Mesh;\n /** World-space position the projector sits at. */\n position: Vector3;\n /** Direction the projector points. Defaults to -Z. */\n normal?: Vector3;\n /** Size of the decal box. */\n size: { width: number; height: number; depth?: number };\n /** Rotation around the projection axis (radians). */\n angle?: number;\n /** Surface to project. */\n surface: SurfaceContent;\n}\n\n/**\n * Projects a SurfaceContent onto `target`'s geometry. The decal conforms to\n * the underlying surface — useful for signage on curved walls, logos on\n * irregular terrain, graffiti on cylindrical surfaces, etc.\n */\nexport function createDecal(opts: DecalOpts): Mesh {\n const name = opts.name ?? \"decal\";\n const normal = opts.normal ?? new Vector3(0, 0, -1);\n const size = new Vector3(opts.size.width, opts.size.height, opts.size.depth ?? 1);\n\n const decal = MeshBuilder.CreateDecal(name, opts.target, {\n position: opts.position,\n normal,\n size,\n angle: opts.angle,\n });\n\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.size.width,\n worldHeight: opts.size.height,\n });\n // Decals need transparency to show the underlying mesh through their borders.\n if (\"hasAlpha\" in (material as StandardMaterial)) {\n (material as StandardMaterial).useAlphaFromDiffuseTexture = true;\n }\n decal.material = material;\n return decal;\n}\n\n/* ------------------------------------------------------------------ */\n/* Helper: paint a widget onto a fresh DynamicTexture (escape hatch) */\n/* ------------------------------------------------------------------ */\n\nexport function createWidgetTexture(\n scene: Scene,\n name: string,\n widget: WidgetSpec,\n pixelWidth: number,\n pixelHeight: number,\n selected = false\n): DynamicTexture {\n const tex = new DynamicTexture(name, { width: pixelWidth * TEX_SCALE, height: pixelHeight * TEX_SCALE }, scene, true);\n tex.vScale = -1;\n tex.vOffset = 1;\n tex.hasAlpha = true;\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n paintWidget(ctx, widget, pixelWidth, pixelHeight, selected);\n tex.update(false);\n return tex;\n}\n","/**\n * Layout helpers — map 2D scene-node positions onto 3D arrangements.\n *\n * All layout functions take the same shape: a SceneNode, the Mesh that was\n * built for it, the scene's bounds, and layout-specific options. They mutate\n * `mesh.position` (and sometimes `mesh.rotation`) in place.\n *\n * Pair with `sceneBounds(scene)` from `./babylon` to compute the bounds.\n */\nimport { Vector3, type Mesh } from \"@babylonjs/core\";\nimport type { SceneNode } from \"@particle-academy/fancy-3d\";\n\ninterface Bounds {\n minX: number;\n maxX: number;\n minY: number;\n maxY: number;\n}\n\nfunction sizeOf(node: SceneNode): { w: number; h: number } {\n return { w: node.size?.w ?? 200, h: node.size?.h ?? 120 };\n}\n\nfunction normalizedCenter(node: SceneNode, bounds: Bounds) {\n const { w, h } = sizeOf(node);\n const cx = (node.position.x + w / 2 - bounds.minX) / Math.max(1, bounds.maxX - bounds.minX);\n const cy = (node.position.y + h / 2 - bounds.minY) / Math.max(1, bounds.maxY - bounds.minY);\n return { cx, cy };\n}\n\n/* ------------------------------------------------------------------ */\n/* Grid — flat XY grid in front of the camera */\n/* ------------------------------------------------------------------ */\n\nexport interface GridLayoutOpts {\n /** Pixel-to-world unit ratio. Defaults to 1/120. */\n scale?: number;\n /** World-space center of the grid. Defaults to (0, 0, 0). */\n origin?: Vector3;\n}\n\n/**\n * Direct 2D-to-3D mapping. DOM (x, y) becomes world (x, -y, 0) — the most\n * literal layout. Useful when you want the scene to look identical to its\n * DOM rendering, just rendered as floating panels.\n */\nexport function placeOnGrid(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: GridLayoutOpts = {}) {\n const scale = opts.scale ?? 1 / 120;\n const origin = opts.origin ?? new Vector3(0, 0, 0);\n const { w, h } = sizeOf(node);\n const cx = node.position.x + w / 2 - (bounds.minX + bounds.maxX) / 2;\n const cy = node.position.y + h / 2 - (bounds.minY + bounds.maxY) / 2;\n mesh.position = new Vector3(origin.x + cx * scale, origin.y - cy * scale, origin.z);\n}\n\n/* ------------------------------------------------------------------ */\n/* Wall — gallery layout against a vertical plane */\n/* ------------------------------------------------------------------ */\n\nexport interface WallLayoutOpts {\n /** Distance from origin along the wall's normal. Defaults to 0. */\n z?: number;\n /** Spread along world X. Defaults to 10 world units. */\n spreadX?: number;\n /** Spread along world Y. Defaults to 4 world units. */\n spreadY?: number;\n /** Wall vertical center. Defaults to 1.5 world units. */\n centerY?: number;\n}\n\n/**\n * Hangs panels on a flat virtual wall, centered on the world origin and\n * facing +Z.\n */\nexport function placeOnWall(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: WallLayoutOpts = {}) {\n const spreadX = opts.spreadX ?? 10;\n const spreadY = opts.spreadY ?? 4;\n const centerY = opts.centerY ?? 1.5;\n const z = opts.z ?? 0;\n const { cx, cy } = normalizedCenter(node, bounds);\n mesh.position = new Vector3((cx - 0.5) * spreadX, centerY + (0.5 - cy) * spreadY, z);\n mesh.rotation.y = 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Arc — partial cylinder (alias of placeOnCylinder with friendlier name) */\n/* ------------------------------------------------------------------ */\n\nexport interface ArcLayoutOpts {\n /** Cylinder radius. Defaults to 6. */\n radius?: number;\n /** Total arc spanned in radians. Defaults to π * 0.9 (~160°). */\n arc?: number;\n /** Vertical extent. Defaults to 6. */\n height?: number;\n /** Base Y of the arc. Defaults to 0. */\n baseY?: number;\n}\n\n/**\n * Wraps DOM x onto an angle around a vertical axis; DOM y becomes height.\n * Same math as `placeOnCylinder` from `./babylon`, exposed here with a\n * clearer name and consistent options shape.\n */\nexport function placeOnArc(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: ArcLayoutOpts = {}) {\n const radius = opts.radius ?? 6;\n const arc = opts.arc ?? Math.PI * 0.9;\n const height = opts.height ?? 6;\n const baseY = opts.baseY ?? 0;\n const { cx, cy } = normalizedCenter(node, bounds);\n const angle = (cx - 0.5) * arc;\n mesh.position = new Vector3(Math.sin(angle) * radius, baseY + (0.5 - cy) * height, Math.cos(angle) * radius);\n mesh.rotation.y = angle;\n}\n\n/* ------------------------------------------------------------------ */\n/* Path — distribute along a sequence of waypoints */\n/* ------------------------------------------------------------------ */\n\nexport interface PathLayoutOpts {\n /** Waypoints along the path. */\n waypoints: Vector3[];\n /** Should each mesh face the next waypoint? Defaults to true. */\n faceForward?: boolean;\n /** Distribute by node index (0..n-1) instead of normalized x. Defaults to false. */\n byIndex?: boolean;\n /** Total node count when using `byIndex`. Defaults to inferred from bounds. */\n nodeCount?: number;\n}\n\nfunction lerpPath(waypoints: Vector3[], t: number): { pos: Vector3; tangent: Vector3 } {\n if (waypoints.length === 0) return { pos: new Vector3(0, 0, 0), tangent: new Vector3(0, 0, 1) };\n if (waypoints.length === 1) return { pos: waypoints[0].clone(), tangent: new Vector3(0, 0, 1) };\n const segments = waypoints.length - 1;\n const scaled = Math.max(0, Math.min(1, t)) * segments;\n const i = Math.min(segments - 1, Math.floor(scaled));\n const local = scaled - i;\n const a = waypoints[i];\n const b = waypoints[i + 1];\n const pos = Vector3.Lerp(a, b, local);\n const tangent = b.subtract(a).normalize();\n return { pos, tangent };\n}\n\n/**\n * Distributes nodes along a polyline. Each mesh sits on the path; if\n * `faceForward` is true, each mesh's +Y rotation aligns with the path\n * tangent.\n */\nexport function placeOnPath(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: PathLayoutOpts) {\n const faceForward = opts.faceForward ?? true;\n let t: number;\n if (opts.byIndex) {\n const total = opts.nodeCount ?? Math.max(1, bounds.maxX - bounds.minX);\n const idx = node.position.x;\n t = total > 1 ? idx / (total - 1) : 0.5;\n } else {\n const { cx } = normalizedCenter(node, bounds);\n t = cx;\n }\n const { pos, tangent } = lerpPath(opts.waypoints, t);\n mesh.position = pos;\n if (faceForward) {\n mesh.rotation.y = Math.atan2(tangent.x, tangent.z);\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Sphere — wrap nodes onto a sphere surface */\n/* ------------------------------------------------------------------ */\n\nexport interface SphereLayoutOpts {\n /** Sphere radius. Defaults to 5. */\n radius?: number;\n /** World-space center. Defaults to (0, 0, 0). */\n center?: Vector3;\n /** Latitude span in radians (0..π). Defaults to π * 0.7 (avoids poles). */\n latSpan?: number;\n /** Longitude span in radians (0..2π). Defaults to 2π. */\n lonSpan?: number;\n}\n\n/**\n * DOM x → longitude, DOM y → latitude. Useful for \"globe of widgets\" or\n * any kind of spherical immersive layout.\n */\nexport function placeOnSphere(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: SphereLayoutOpts = {}) {\n const radius = opts.radius ?? 5;\n const center = opts.center ?? new Vector3(0, 0, 0);\n const latSpan = opts.latSpan ?? Math.PI * 0.7;\n const lonSpan = opts.lonSpan ?? Math.PI * 2;\n const { cx, cy } = normalizedCenter(node, bounds);\n const lon = (cx - 0.5) * lonSpan;\n const lat = (0.5 - cy) * latSpan;\n const r = radius;\n const x = r * Math.cos(lat) * Math.sin(lon);\n const y = r * Math.sin(lat);\n const z = r * Math.cos(lat) * Math.cos(lon);\n mesh.position = new Vector3(center.x + x, center.y + y, center.z + z);\n mesh.rotation.y = lon;\n}\n","/**\n * BabylonJS adapter for `@particle-academy/fancy-3d`.\n *\n * Each widget kind paints onto a 2D HTMLCanvasElement that is uploaded to a\n * Babylon `DynamicTexture`, which is then applied to a plane mesh sized to\n * the widget's pixel rect. Edges become line meshes between node centers.\n *\n * `@babylonjs/core` is an OPTIONAL peer dependency — only consumers building\n * 3D scenes need to install it.\n */\nimport {\n Color3,\n DynamicTexture,\n MeshBuilder,\n StandardMaterial,\n Vector3,\n type Mesh,\n type Scene as BJScene,\n} from \"@babylonjs/core\";\nimport type {\n AdapterContext,\n Scene,\n SceneNode,\n WidgetAdapter,\n WidgetSpec,\n} from \"@particle-academy/fancy-3d\";\n\nimport { TEX_SCALE, paintWidget } from \"./painters\";\nexport { TEX_SCALE, paintWidget } from \"./painters\";\n\nconst WORLD_SCALE = 1 / 180; // pixels → world units\n\n\n/* ------------------------------------------------------------------ */\n/* Adapter */\n/* ------------------------------------------------------------------ */\n\nexport interface BabylonAdapterDeps {\n scene3D: BJScene;\n /** Pixel size for the widget (the scene node's `size` field). */\n sizeFor(spec: WidgetSpec): { w: number; h: number };\n}\n\nexport function createBabylonAdapter(deps: BabylonAdapterDeps): WidgetAdapter<Mesh> {\n return {\n render(spec: WidgetSpec, ctx: AdapterContext): Mesh {\n const { w, h } = deps.sizeFor(spec);\n const tex = new DynamicTexture(`tex-${ctx.nodeId}`, { width: w * TEX_SCALE, height: h * TEX_SCALE }, deps.scene3D, true);\n tex.hasAlpha = true;\n // Babylon plane UVs run V=0 at the bottom; canvas Y runs top-to-bottom.\n // Without this flip, painted content appears upside down on the mesh.\n tex.vScale = -1;\n tex.vOffset = 1;\n const c = tex.getContext() as CanvasRenderingContext2D;\n c.scale(TEX_SCALE, TEX_SCALE);\n paintWidget(c, spec, w, h, ctx.selected);\n tex.update(false);\n\n const mat = new StandardMaterial(`mat-${ctx.nodeId}`, deps.scene3D);\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(1, 1, 1);\n mat.disableLighting = false;\n mat.useAlphaFromDiffuseTexture = true;\n\n const plane = MeshBuilder.CreatePlane(`node-${ctx.nodeId}`, { width: w * WORLD_SCALE, height: h * WORLD_SCALE }, deps.scene3D);\n plane.material = mat;\n plane.metadata = { nodeId: ctx.nodeId, kind: spec.kind };\n return plane;\n },\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Layout helpers */\n/* ------------------------------------------------------------------ */\n\n/**\n * \"3D Desktop\" layout — wraps the scene's 2D positions onto a partial\n * cylinder facing the camera. DOM `x` becomes angle around the cylinder,\n * DOM `y` becomes height.\n */\nexport function placeOnCylinder(node: SceneNode, mesh: Mesh, bounds: { minX: number; maxX: number; minY: number; maxY: number }, opts: { radius?: number; arc?: number } = {}) {\n const radius = opts.radius ?? 6;\n const arc = opts.arc ?? Math.PI * 0.9; // ~160°\n const rangeX = bounds.maxX - bounds.minX || 1;\n const rangeY = bounds.maxY - bounds.minY || 1;\n const cx = (node.position.x + (node.size?.w ?? 200) / 2 - bounds.minX) / rangeX;\n const cy = (node.position.y + (node.size?.h ?? 120) / 2 - bounds.minY) / rangeY;\n const angle = (cx - 0.5) * arc;\n const height = (0.5 - cy) * 6;\n mesh.position = new Vector3(Math.sin(angle) * radius, height, Math.cos(angle) * radius);\n // Rotate the plane around Y so its FRONT face (default plane normal: +Z)\n // points outward — toward the orbiting camera. Babylon's `lookAt` aimed\n // the back of the plane at the target, which read as mirrored text.\n mesh.rotation = new Vector3(0, angle, 0);\n}\n\nexport function sceneBounds(scene: Scene) {\n const xs = scene.nodes.map((n) => n.position.x);\n const ys = scene.nodes.map((n) => n.position.y);\n const xe = scene.nodes.map((n) => n.position.x + (n.size?.w ?? 200));\n const ye = scene.nodes.map((n) => n.position.y + (n.size?.h ?? 120));\n return {\n minX: Math.min(...xs),\n maxX: Math.max(...xe),\n minY: Math.min(...ys),\n maxY: Math.max(...ye),\n };\n}\n\n\nexport * from \"./primitives\";\n\nexport * from \"./layouts\";\n"]}
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@babylonjs/core');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/react.tsx
|
|
8
|
+
function adj3(m) {
|
|
9
|
+
return [
|
|
10
|
+
m[4] * m[8] - m[5] * m[7],
|
|
11
|
+
m[2] * m[7] - m[1] * m[8],
|
|
12
|
+
m[1] * m[5] - m[2] * m[4],
|
|
13
|
+
m[5] * m[6] - m[3] * m[8],
|
|
14
|
+
m[0] * m[8] - m[2] * m[6],
|
|
15
|
+
m[2] * m[3] - m[0] * m[5],
|
|
16
|
+
m[3] * m[7] - m[4] * m[6],
|
|
17
|
+
m[1] * m[6] - m[0] * m[7],
|
|
18
|
+
m[0] * m[4] - m[1] * m[3]
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function multmm(a, b) {
|
|
22
|
+
const c = new Array(9);
|
|
23
|
+
for (let i = 0; i < 3; i++) {
|
|
24
|
+
for (let j = 0; j < 3; j++) {
|
|
25
|
+
let cij = 0;
|
|
26
|
+
for (let k = 0; k < 3; k++) cij += a[3 * i + k] * b[3 * k + j];
|
|
27
|
+
c[3 * i + j] = cij;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return c;
|
|
31
|
+
}
|
|
32
|
+
function multmv(m, v) {
|
|
33
|
+
return [
|
|
34
|
+
m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
|
|
35
|
+
m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
|
|
36
|
+
m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
function basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
40
|
+
const m = [x1, x2, x3, y1, y2, y3, 1, 1, 1];
|
|
41
|
+
const v = multmv(adj3(m), [x4, y4, 1]);
|
|
42
|
+
return multmm(m, [v[0], 0, 0, 0, v[1], 0, 0, 0, v[2]]);
|
|
43
|
+
}
|
|
44
|
+
function quadToQuad(w, h, x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
45
|
+
const s = basisToPoints(0, 0, w, 0, w, h, 0, h);
|
|
46
|
+
const d = basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4);
|
|
47
|
+
const t = multmm(d, adj3(s));
|
|
48
|
+
const n = t[8];
|
|
49
|
+
for (let i = 0; i < 9; i++) t[i] /= n;
|
|
50
|
+
return t;
|
|
51
|
+
}
|
|
52
|
+
function matrix3dString(t) {
|
|
53
|
+
return `matrix3d(${t[0]}, ${t[3]}, 0, ${t[6]}, ${t[1]}, ${t[4]}, 0, ${t[7]}, 0, 0, 1, 0, ${t[2]}, ${t[5]}, 0, ${t[8]})`;
|
|
54
|
+
}
|
|
55
|
+
var StageContext = react.createContext(null);
|
|
56
|
+
function useStage() {
|
|
57
|
+
const ctx = react.useContext(StageContext);
|
|
58
|
+
if (!ctx) throw new Error("useStage() must be called inside <Stage>");
|
|
59
|
+
return ctx;
|
|
60
|
+
}
|
|
61
|
+
function Stage({
|
|
62
|
+
children,
|
|
63
|
+
cameraRadius = 10,
|
|
64
|
+
cameraTarget = [0, 1.5, 0],
|
|
65
|
+
cameraAlpha = Math.PI / 2,
|
|
66
|
+
cameraBeta = Math.PI / 2.4,
|
|
67
|
+
clearColor = "#06080f",
|
|
68
|
+
bare = false,
|
|
69
|
+
onReady,
|
|
70
|
+
className,
|
|
71
|
+
style
|
|
72
|
+
}) {
|
|
73
|
+
const containerRef = react.useRef(null);
|
|
74
|
+
const canvasRef = react.useRef(null);
|
|
75
|
+
const overlayRef = react.useRef(null);
|
|
76
|
+
const [stage, setStage] = react.useState(null);
|
|
77
|
+
react.useEffect(() => {
|
|
78
|
+
const canvas = canvasRef.current;
|
|
79
|
+
const overlay = overlayRef.current;
|
|
80
|
+
if (!canvas || !overlay) return;
|
|
81
|
+
const engine = new core.Engine(canvas, true, { stencil: true, preserveDrawingBuffer: true });
|
|
82
|
+
const scene = new core.Scene(engine);
|
|
83
|
+
const c = core.Color4.FromHexString(clearColor);
|
|
84
|
+
scene.clearColor = new core.Color4(c.r, c.g, c.b, 1);
|
|
85
|
+
if (!bare) {
|
|
86
|
+
const cam = new core.ArcRotateCamera(
|
|
87
|
+
"fancy3d-cam",
|
|
88
|
+
cameraAlpha,
|
|
89
|
+
cameraBeta,
|
|
90
|
+
cameraRadius,
|
|
91
|
+
new core.Vector3(...cameraTarget),
|
|
92
|
+
scene
|
|
93
|
+
);
|
|
94
|
+
cam.attachControl(canvas, true);
|
|
95
|
+
cam.lowerRadiusLimit = 1;
|
|
96
|
+
cam.upperRadiusLimit = 80;
|
|
97
|
+
cam.wheelDeltaPercentage = 0.01;
|
|
98
|
+
cam.upperBetaLimit = Math.PI / 2 - 0.05;
|
|
99
|
+
const hemi = new core.HemisphericLight("fancy3d-hemi", new core.Vector3(0, 1, 0), scene);
|
|
100
|
+
hemi.intensity = 0.7;
|
|
101
|
+
hemi.diffuse = new core.Color3(0.7, 0.78, 1);
|
|
102
|
+
hemi.groundColor = new core.Color3(0.1, 0.1, 0.18);
|
|
103
|
+
const dir = new core.DirectionalLight("fancy3d-dir", new core.Vector3(-0.4, -1, -0.6), scene);
|
|
104
|
+
dir.intensity = 0.6;
|
|
105
|
+
}
|
|
106
|
+
onReady?.(scene);
|
|
107
|
+
const frameSubs = /* @__PURE__ */ new Set();
|
|
108
|
+
scene.onBeforeRenderObservable.add(() => {
|
|
109
|
+
frameSubs.forEach((cb) => cb());
|
|
110
|
+
});
|
|
111
|
+
engine.runRenderLoop(() => scene.render());
|
|
112
|
+
const handleResize = () => engine.resize();
|
|
113
|
+
window.addEventListener("resize", handleResize);
|
|
114
|
+
setStage({
|
|
115
|
+
engine,
|
|
116
|
+
scene,
|
|
117
|
+
canvas,
|
|
118
|
+
overlayRoot: overlay,
|
|
119
|
+
onFrame(cb) {
|
|
120
|
+
frameSubs.add(cb);
|
|
121
|
+
return () => frameSubs.delete(cb);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return () => {
|
|
125
|
+
window.removeEventListener("resize", handleResize);
|
|
126
|
+
engine.dispose();
|
|
127
|
+
setStage(null);
|
|
128
|
+
};
|
|
129
|
+
}, []);
|
|
130
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
ref: containerRef,
|
|
134
|
+
className,
|
|
135
|
+
style: { position: "relative", overflow: "hidden", ...style },
|
|
136
|
+
"data-fancy-3d-stage": "",
|
|
137
|
+
children: [
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
139
|
+
"canvas",
|
|
140
|
+
{
|
|
141
|
+
ref: canvasRef,
|
|
142
|
+
style: { display: "block", width: "100%", height: "100%", outline: "none" },
|
|
143
|
+
tabIndex: 0
|
|
144
|
+
}
|
|
145
|
+
),
|
|
146
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
ref: overlayRef,
|
|
150
|
+
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
151
|
+
"data-fancy-3d-overlay-root": ""
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
stage && /* @__PURE__ */ jsxRuntime.jsx(StageContext.Provider, { value: stage, children })
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
function Monitor({
|
|
160
|
+
children,
|
|
161
|
+
position,
|
|
162
|
+
width,
|
|
163
|
+
height,
|
|
164
|
+
rotationY = 0,
|
|
165
|
+
bezel = "#0b0f17",
|
|
166
|
+
bezelThickness = 0.06,
|
|
167
|
+
background = "#0b1220",
|
|
168
|
+
pixelWidth,
|
|
169
|
+
pixelHeight,
|
|
170
|
+
name = "screen"
|
|
171
|
+
}) {
|
|
172
|
+
const stage = useStage();
|
|
173
|
+
const meshRef = react.useRef(null);
|
|
174
|
+
const overlayRef = react.useRef(null);
|
|
175
|
+
const innerSize = react.useRef({
|
|
176
|
+
w: pixelWidth ?? Math.max(120, Math.round(width * 360)),
|
|
177
|
+
h: pixelHeight ?? Math.max(80, Math.round(height * 360))
|
|
178
|
+
});
|
|
179
|
+
react.useEffect(() => {
|
|
180
|
+
const { scene } = stage;
|
|
181
|
+
const bezelMesh = core.MeshBuilder.CreateBox(`${name}-bezel`, {
|
|
182
|
+
width: width + bezelThickness * 2,
|
|
183
|
+
height: height + bezelThickness * 2,
|
|
184
|
+
depth: bezelThickness
|
|
185
|
+
}, scene);
|
|
186
|
+
bezelMesh.position = new core.Vector3(position[0], position[1], position[2]);
|
|
187
|
+
bezelMesh.rotation.y = rotationY;
|
|
188
|
+
const bezelMat = new core.StandardMaterial(`${name}-bezel-mat`, scene);
|
|
189
|
+
bezelMat.diffuseColor = core.Color3.FromHexString(bezel);
|
|
190
|
+
bezelMat.specularColor = new core.Color3(0.05, 0.05, 0.05);
|
|
191
|
+
bezelMesh.material = bezelMat;
|
|
192
|
+
const pane = core.MeshBuilder.CreatePlane(`${name}-pane`, { width, height, sideOrientation: core.Mesh.DOUBLESIDE }, scene);
|
|
193
|
+
pane.position = new core.Vector3(position[0], position[1], position[2]);
|
|
194
|
+
pane.rotation.y = rotationY;
|
|
195
|
+
const forward = new core.Vector3(0, 0, 1);
|
|
196
|
+
const rot = core.Matrix.RotationY(rotationY);
|
|
197
|
+
const offset = core.Vector3.TransformNormal(forward.scale(bezelThickness / 2 + 1e-3), rot);
|
|
198
|
+
pane.position.addInPlace(offset);
|
|
199
|
+
const paneMat = new core.StandardMaterial(`${name}-pane-mat`, scene);
|
|
200
|
+
paneMat.diffuseColor = core.Color3.FromHexString(background);
|
|
201
|
+
paneMat.emissiveColor = core.Color3.FromHexString(background).scale(0.4);
|
|
202
|
+
pane.material = paneMat;
|
|
203
|
+
pane.metadata = { fancy3d: "screen", screenName: name };
|
|
204
|
+
meshRef.current = pane;
|
|
205
|
+
return () => {
|
|
206
|
+
pane.dispose();
|
|
207
|
+
bezelMesh.dispose();
|
|
208
|
+
meshRef.current = null;
|
|
209
|
+
};
|
|
210
|
+
}, [stage, name, width, height, bezel, bezelThickness, background, position, rotationY]);
|
|
211
|
+
react.useEffect(() => {
|
|
212
|
+
const unsub = stage.onFrame(() => {
|
|
213
|
+
const mesh = meshRef.current;
|
|
214
|
+
const overlay = overlayRef.current;
|
|
215
|
+
if (!mesh || !overlay) return;
|
|
216
|
+
const cam = stage.scene.activeCamera;
|
|
217
|
+
if (!cam) return;
|
|
218
|
+
const engine = stage.engine;
|
|
219
|
+
const renderW = engine.getRenderWidth();
|
|
220
|
+
const renderH = engine.getRenderHeight();
|
|
221
|
+
const viewport = cam.viewport.toGlobal(renderW, renderH);
|
|
222
|
+
const tm = stage.scene.getTransformMatrix();
|
|
223
|
+
const identity = core.Matrix.Identity();
|
|
224
|
+
const wm = mesh.getWorldMatrix();
|
|
225
|
+
const halfW = width / 2;
|
|
226
|
+
const halfH = height / 2;
|
|
227
|
+
const localCorners = [
|
|
228
|
+
new core.Vector3(-halfW, halfH, 0),
|
|
229
|
+
// top-left
|
|
230
|
+
new core.Vector3(halfW, halfH, 0),
|
|
231
|
+
// top-right
|
|
232
|
+
new core.Vector3(halfW, -halfH, 0),
|
|
233
|
+
// bottom-right
|
|
234
|
+
new core.Vector3(-halfW, -halfH, 0)
|
|
235
|
+
// bottom-left
|
|
236
|
+
];
|
|
237
|
+
const worldCorners = localCorners.map((v) => core.Vector3.TransformCoordinates(v, wm));
|
|
238
|
+
const camPos = cam.globalPosition;
|
|
239
|
+
const right = worldCorners[1].subtract(worldCorners[0]);
|
|
240
|
+
const up = worldCorners[0].subtract(worldCorners[3]);
|
|
241
|
+
const normal = core.Vector3.Cross(up, right).normalize();
|
|
242
|
+
const center = worldCorners[0].add(worldCorners[2]).scale(0.5);
|
|
243
|
+
const toCam = camPos.subtract(center).normalize();
|
|
244
|
+
const facing = Math.abs(core.Vector3.Dot(normal, toCam));
|
|
245
|
+
const projected = worldCorners.map((c) => core.Vector3.Project(c, identity, tm, viewport));
|
|
246
|
+
const inFrustum = projected.every((p) => p.z >= 0 && p.z <= 1);
|
|
247
|
+
const visible = inFrustum && facing > 0.05;
|
|
248
|
+
if (!visible) {
|
|
249
|
+
if (overlay.style.display !== "none") overlay.style.display = "none";
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const avgZ = (projected[0].z + projected[1].z + projected[2].z + projected[3].z) / 4;
|
|
253
|
+
const depthZIndex = Math.round(Math.max(0, Math.min(1, 1 - avgZ)) * 1e5);
|
|
254
|
+
const zStr = String(depthZIndex);
|
|
255
|
+
if (overlay.style.zIndex !== zStr) overlay.style.zIndex = zStr;
|
|
256
|
+
const dpr = window.devicePixelRatio || 1;
|
|
257
|
+
const w0 = innerSize.current.w;
|
|
258
|
+
const h0 = innerSize.current.h;
|
|
259
|
+
const t = quadToQuad(
|
|
260
|
+
w0,
|
|
261
|
+
h0,
|
|
262
|
+
projected[0].x / dpr,
|
|
263
|
+
projected[0].y / dpr,
|
|
264
|
+
projected[1].x / dpr,
|
|
265
|
+
projected[1].y / dpr,
|
|
266
|
+
projected[2].x / dpr,
|
|
267
|
+
projected[2].y / dpr,
|
|
268
|
+
projected[3].x / dpr,
|
|
269
|
+
projected[3].y / dpr
|
|
270
|
+
);
|
|
271
|
+
if (overlay.style.display !== "block") overlay.style.display = "block";
|
|
272
|
+
overlay.style.transform = matrix3dString(t);
|
|
273
|
+
});
|
|
274
|
+
return unsub;
|
|
275
|
+
}, [stage, width, height]);
|
|
276
|
+
react.useLayoutEffect(() => {
|
|
277
|
+
const el = overlayRef.current;
|
|
278
|
+
if (!el) return;
|
|
279
|
+
if (el.parentElement !== stage.overlayRoot) {
|
|
280
|
+
stage.overlayRoot.appendChild(el);
|
|
281
|
+
}
|
|
282
|
+
return () => {
|
|
283
|
+
if (el.parentElement === stage.overlayRoot) {
|
|
284
|
+
stage.overlayRoot.removeChild(el);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
}, [stage]);
|
|
288
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
289
|
+
"div",
|
|
290
|
+
{
|
|
291
|
+
ref: overlayRef,
|
|
292
|
+
"data-fancy-3d-screen": name,
|
|
293
|
+
style: {
|
|
294
|
+
position: "absolute",
|
|
295
|
+
left: 0,
|
|
296
|
+
top: 0,
|
|
297
|
+
width: innerSize.current.w,
|
|
298
|
+
height: innerSize.current.h,
|
|
299
|
+
transformOrigin: "0 0",
|
|
300
|
+
pointerEvents: "auto",
|
|
301
|
+
overflow: "hidden",
|
|
302
|
+
background,
|
|
303
|
+
borderRadius: 4,
|
|
304
|
+
display: "none"
|
|
305
|
+
},
|
|
306
|
+
children
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
exports.Monitor = Monitor;
|
|
312
|
+
exports.Stage = Stage;
|
|
313
|
+
exports.useStage = useStage;
|
|
314
|
+
//# sourceMappingURL=react.cjs.map
|
|
315
|
+
//# sourceMappingURL=react.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx"],"names":["createContext","useContext","useRef","useState","useEffect","Engine","BJScene","Color4","ArcRotateCamera","Vector3","HemisphericLight","Color3","DirectionalLight","jsxs","jsx","MeshBuilder","StandardMaterial","Mesh","Matrix","useLayoutEffect"],"mappings":"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","file":"react.cjs","sourcesContent":["/**\n * `<Stage>` and `<Monitor>` — declarative React API for fancy-3d.\n *\n * <Stage>\n * <Monitor position={[0, 2, 0]} width={4} height={2.5}>\n * <Card>...real react-fancy components...</Card>\n * </Monitor>\n * </Stage>\n *\n * `<Stage>` owns the Babylon engine + scene + render loop and exposes them\n * via context. `<Monitor>` builds a bezel mesh, projects its world-space\n * corners to screen space each frame, and renders its children into a\n * positioned DOM overlay. Children are real React: full interactivity,\n * accessibility, and styling — no canvas-rasterized snapshot.\n\n * Renamed from `<Screen>` in v0.3.0 to free the name for\n * `@particle-academy/fancy-screens`'s `<Screen>` (containerized application\n * surface). The behavior here is unchanged.\n *\n * Tradeoffs of mount mode (vs. painted texture):\n * - Pro: live, interactive, perfect text rendering.\n * - Con: HTML overlay always renders on top of the WebGL canvas; depth\n * sorting against other 3D objects is approximate (we hide the overlay\n * when the mesh is behind the camera or fully occluded by frustum).\n */\nimport {\n ArcRotateCamera,\n Color3,\n Color4,\n DirectionalLight,\n Engine,\n HemisphericLight,\n Matrix,\n Mesh,\n MeshBuilder,\n Scene as BJScene,\n StandardMaterial,\n Vector3,\n type Camera,\n} from \"@babylonjs/core\";\nimport {\n createContext,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\n\n/* ------------------------------------------------------------------ */\n/* 2D perspective transform — maps a unit rectangle to a 4-point quad */\n/* via a 3x3 homography, packed into a CSS matrix3d for transform. */\n/* ------------------------------------------------------------------ */\n\ntype Mat3 = [number, number, number, number, number, number, number, number, number];\n\nfunction adj3(m: Mat3): Mat3 {\n return [\n m[4] * m[8] - m[5] * m[7], m[2] * m[7] - m[1] * m[8], m[1] * m[5] - m[2] * m[4],\n m[5] * m[6] - m[3] * m[8], m[0] * m[8] - m[2] * m[6], m[2] * m[3] - m[0] * m[5],\n m[3] * m[7] - m[4] * m[6], m[1] * m[6] - m[0] * m[7], m[0] * m[4] - m[1] * m[3],\n ];\n}\n\nfunction multmm(a: Mat3, b: Mat3): Mat3 {\n const c: number[] = new Array(9);\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n let cij = 0;\n for (let k = 0; k < 3; k++) cij += a[3 * i + k] * b[3 * k + j];\n c[3 * i + j] = cij;\n }\n }\n return c as Mat3;\n}\n\nfunction multmv(m: Mat3, v: [number, number, number]): [number, number, number] {\n return [\n m[0] * v[0] + m[1] * v[1] + m[2] * v[2],\n m[3] * v[0] + m[4] * v[1] + m[5] * v[2],\n m[6] * v[0] + m[7] * v[1] + m[8] * v[2],\n ];\n}\n\nfunction basisToPoints(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): Mat3 {\n const m: Mat3 = [x1, x2, x3, y1, y2, y3, 1, 1, 1];\n const v = multmv(adj3(m), [x4, y4, 1]);\n return multmm(m, [v[0], 0, 0, 0, v[1], 0, 0, 0, v[2]]);\n}\n\n/** Compute a homography that maps (0,0)→p1, (w,0)→p2, (w,h)→p3, (0,h)→p4. */\nfunction quadToQuad(\n w: number, h: number,\n x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number\n): Mat3 {\n const s = basisToPoints(0, 0, w, 0, w, h, 0, h);\n const d = basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4);\n const t = multmm(d, adj3(s));\n // Normalize so t[8] is 1\n const n = t[8];\n for (let i = 0; i < 9; i++) t[i] /= n;\n return t;\n}\n\n/** Pack a 3x3 homography into a CSS matrix3d() string. */\nfunction matrix3dString(t: Mat3): string {\n return `matrix3d(${t[0]}, ${t[3]}, 0, ${t[6]}, ${t[1]}, ${t[4]}, 0, ${t[7]}, 0, 0, 1, 0, ${t[2]}, ${t[5]}, 0, ${t[8]})`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Stage context */\n/* ------------------------------------------------------------------ */\n\ninterface StageContextValue {\n engine: Engine;\n scene: BJScene;\n /** The HTML <canvas> the engine renders into — its bounding rect anchors overlays. */\n canvas: HTMLCanvasElement;\n /** Subscribe to per-frame ticks. Returns an unsubscribe fn. */\n onFrame(cb: () => void): () => void;\n /** The DOM container that screen overlays mount into. */\n overlayRoot: HTMLDivElement;\n}\n\nconst StageContext = createContext<StageContextValue | null>(null);\n\nexport function useStage(): StageContextValue {\n const ctx = useContext(StageContext);\n if (!ctx) throw new Error(\"useStage() must be called inside <Stage>\");\n return ctx;\n}\n\n/* ------------------------------------------------------------------ */\n/* Stage */\n/* ------------------------------------------------------------------ */\n\nexport interface StageProps {\n children?: ReactNode;\n /** Initial camera radius. Defaults to 10. */\n cameraRadius?: number;\n /** Initial camera target. Defaults to (0, 1.5, 0). */\n cameraTarget?: [number, number, number];\n /** Initial camera alpha (horizontal angle). Defaults to π/2. */\n cameraAlpha?: number;\n /** Initial camera beta (vertical angle). Defaults to π/2.4. */\n cameraBeta?: number;\n /** Background clear color. Defaults to a near-black. */\n clearColor?: string;\n /** Disable the default lights / camera if you want to set your own. */\n bare?: boolean;\n /** Callback after the scene is created — set up custom cameras, lights, meshes. */\n onReady?: (scene: BJScene) => void;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function Stage({\n children,\n cameraRadius = 10,\n cameraTarget = [0, 1.5, 0],\n cameraAlpha = Math.PI / 2,\n cameraBeta = Math.PI / 2.4,\n clearColor = \"#06080f\",\n bare = false,\n onReady,\n className,\n style,\n}: StageProps) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const [stage, setStage] = useState<StageContextValue | null>(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const overlay = overlayRef.current;\n if (!canvas || !overlay) return;\n\n const engine = new Engine(canvas, true, { stencil: true, preserveDrawingBuffer: true });\n const scene = new BJScene(engine);\n const c = Color4.FromHexString(clearColor);\n scene.clearColor = new Color4(c.r, c.g, c.b, 1);\n\n if (!bare) {\n const cam = new ArcRotateCamera(\n \"fancy3d-cam\",\n cameraAlpha,\n cameraBeta,\n cameraRadius,\n new Vector3(...cameraTarget),\n scene\n );\n cam.attachControl(canvas, true);\n cam.lowerRadiusLimit = 1;\n cam.upperRadiusLimit = 80;\n cam.wheelDeltaPercentage = 0.01;\n cam.upperBetaLimit = Math.PI / 2 - 0.05;\n\n const hemi = new HemisphericLight(\"fancy3d-hemi\", new Vector3(0, 1, 0), scene);\n hemi.intensity = 0.7;\n hemi.diffuse = new Color3(0.7, 0.78, 1);\n hemi.groundColor = new Color3(0.1, 0.1, 0.18);\n\n const dir = new DirectionalLight(\"fancy3d-dir\", new Vector3(-0.4, -1, -0.6), scene);\n dir.intensity = 0.6;\n }\n\n onReady?.(scene);\n\n const frameSubs = new Set<() => void>();\n scene.onBeforeRenderObservable.add(() => {\n frameSubs.forEach((cb) => cb());\n });\n\n engine.runRenderLoop(() => scene.render());\n const handleResize = () => engine.resize();\n window.addEventListener(\"resize\", handleResize);\n\n setStage({\n engine,\n scene,\n canvas,\n overlayRoot: overlay,\n onFrame(cb) {\n frameSubs.add(cb);\n return () => frameSubs.delete(cb);\n },\n });\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n engine.dispose();\n setStage(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ position: \"relative\", overflow: \"hidden\", ...style }}\n data-fancy-3d-stage=\"\"\n >\n <canvas\n ref={canvasRef}\n style={{ display: \"block\", width: \"100%\", height: \"100%\", outline: \"none\" }}\n tabIndex={0}\n />\n <div\n ref={overlayRef}\n style={{ position: \"absolute\", inset: 0, pointerEvents: \"none\" }}\n data-fancy-3d-overlay-root=\"\"\n />\n {stage && <StageContext.Provider value={stage}>{children}</StageContext.Provider>}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Monitor — interactive mount point on a 3D mesh */\n/* ------------------------------------------------------------------ */\n\nexport interface MonitorProps {\n children?: ReactNode;\n /** World-space center of the screen. */\n position: [number, number, number];\n /** Mesh dimensions in world units. */\n width: number;\n height: number;\n /** Y-axis rotation in radians. */\n rotationY?: number;\n /** Bezel color. Defaults to a near-black frame. */\n bezel?: string;\n /** Bezel thickness in world units. Defaults to 0.06. */\n bezelThickness?: number;\n /** Background color visible behind the React content. */\n background?: string;\n /** Design-time pixel width for the children. Defaults to `width * 360`. */\n pixelWidth?: number;\n /** Design-time pixel height for the children. Defaults to `height * 360`. */\n pixelHeight?: number;\n /** Optional name on the Babylon mesh. */\n name?: string;\n}\n\nexport function Monitor({\n children,\n position,\n width,\n height,\n rotationY = 0,\n bezel = \"#0b0f17\",\n bezelThickness = 0.06,\n background = \"#0b1220\",\n pixelWidth,\n pixelHeight,\n name = \"screen\",\n}: MonitorProps) {\n const stage = useStage();\n const meshRef = useRef<Mesh | null>(null);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n // Design-time pixel size for the children. The matrix3d transform maps\n // this unit rectangle onto the projected mesh quad each frame.\n const innerSize = useRef({\n w: pixelWidth ?? Math.max(120, Math.round(width * 360)),\n h: pixelHeight ?? Math.max(80, Math.round(height * 360)),\n });\n\n // Build the bezel + invisible projection-target plane.\n useEffect(() => {\n const { scene } = stage;\n const bezelMesh = MeshBuilder.CreateBox(`${name}-bezel`, {\n width: width + bezelThickness * 2,\n height: height + bezelThickness * 2,\n depth: bezelThickness,\n }, scene);\n bezelMesh.position = new Vector3(position[0], position[1], position[2]);\n bezelMesh.rotation.y = rotationY;\n const bezelMat = new StandardMaterial(`${name}-bezel-mat`, scene);\n bezelMat.diffuseColor = Color3.FromHexString(bezel);\n bezelMat.specularColor = new Color3(0.05, 0.05, 0.05);\n bezelMesh.material = bezelMat;\n\n // Inner pane the overlay tracks. Its background fills behind the React\n // overlay (in case the overlay is briefly mispositioned); the React\n // children are stamped on top.\n const pane = MeshBuilder.CreatePlane(`${name}-pane`, { width, height, sideOrientation: Mesh.DOUBLESIDE }, scene);\n pane.position = new Vector3(position[0], position[1], position[2]);\n pane.rotation.y = rotationY;\n // The bezel's \"front\" face is on +Z (default camera sits on +Z). Offset\n // the pane forward of that face so the React HTML overlay lines up with\n // the visible front of the bezel rather than its hidden back.\n const forward = new Vector3(0, 0, 1);\n const rot = Matrix.RotationY(rotationY);\n const offset = Vector3.TransformNormal(forward.scale(bezelThickness / 2 + 0.001), rot);\n pane.position.addInPlace(offset);\n const paneMat = new StandardMaterial(`${name}-pane-mat`, scene);\n paneMat.diffuseColor = Color3.FromHexString(background);\n paneMat.emissiveColor = Color3.FromHexString(background).scale(0.4);\n pane.material = paneMat;\n pane.metadata = { fancy3d: \"screen\", screenName: name };\n meshRef.current = pane;\n\n return () => {\n pane.dispose();\n bezelMesh.dispose();\n meshRef.current = null;\n };\n }, [stage, name, width, height, bezel, bezelThickness, background, position, rotationY]);\n\n // Each frame: project the four mesh corners and apply the matrix3d\n // transform that maps the inner div's local pixel space to the projected\n // quad. Imperative — no React re-render per frame.\n useEffect(() => {\n const unsub = stage.onFrame(() => {\n const mesh = meshRef.current;\n const overlay = overlayRef.current;\n if (!mesh || !overlay) return;\n const cam = stage.scene.activeCamera;\n if (!cam) return;\n const engine = stage.engine;\n const renderW = engine.getRenderWidth();\n const renderH = engine.getRenderHeight();\n const viewport = cam.viewport.toGlobal(renderW, renderH);\n const tm = stage.scene.getTransformMatrix();\n const identity = Matrix.Identity();\n const wm = mesh.getWorldMatrix();\n\n const halfW = width / 2;\n const halfH = height / 2;\n // Mesh-local corners ordered: top-left, top-right, bottom-right, bottom-left.\n // Babylon's plane: +Y is up in world (when not rotated around X), so\n // mesh-local +Y = top.\n const localCorners = [\n new Vector3(-halfW, halfH, 0), // top-left\n new Vector3(halfW, halfH, 0), // top-right\n new Vector3(halfW, -halfH, 0), // bottom-right\n new Vector3(-halfW, -halfH, 0), // bottom-left\n ];\n const worldCorners = localCorners.map((v) => Vector3.TransformCoordinates(v, wm));\n\n // Edge-on cull only — hide overlay when the panel is nearly perpendicular\n // to the camera ray (where the projected quad collapses and matrix3d\n // becomes singular). The matrix3d transform handles both front and\n // back side rendering naturally, so we don't strictly cull by side.\n const camPos = cam.globalPosition;\n const right = worldCorners[1].subtract(worldCorners[0]);\n const up = worldCorners[0].subtract(worldCorners[3]);\n const normal = Vector3.Cross(up, right).normalize();\n const center = worldCorners[0].add(worldCorners[2]).scale(0.5);\n const toCam = camPos.subtract(center).normalize();\n const facing = Math.abs(Vector3.Dot(normal, toCam));\n\n const projected = worldCorners.map((c) => Vector3.Project(c, identity, tm, viewport));\n const inFrustum = projected.every((p) => p.z >= 0 && p.z <= 1);\n const visible = inFrustum && facing > 0.05;\n\n if (!visible) {\n if (overlay.style.display !== \"none\") overlay.style.display = \"none\";\n return;\n }\n\n // Depth-sort overlays: nearer-to-camera panels stack above farther ones.\n // Without this, DOM document order decides stacking and side screens\n // can render on top of the center screen even when 3D depth says\n // otherwise. NDC z is 0 at the near plane and 1 at the far plane, so\n // closer-to-camera = smaller z = higher z-index.\n const avgZ = (projected[0].z + projected[1].z + projected[2].z + projected[3].z) / 4;\n const depthZIndex = Math.round(Math.max(0, Math.min(1, 1 - avgZ)) * 100000);\n const zStr = String(depthZIndex);\n if (overlay.style.zIndex !== zStr) overlay.style.zIndex = zStr;\n\n const dpr = window.devicePixelRatio || 1;\n const w0 = innerSize.current.w;\n const h0 = innerSize.current.h;\n const t = quadToQuad(\n w0, h0,\n projected[0].x / dpr, projected[0].y / dpr,\n projected[1].x / dpr, projected[1].y / dpr,\n projected[2].x / dpr, projected[2].y / dpr,\n projected[3].x / dpr, projected[3].y / dpr\n );\n\n if (overlay.style.display !== \"block\") overlay.style.display = \"block\";\n overlay.style.transform = matrix3dString(t);\n });\n return unsub;\n }, [stage, width, height]);\n\n // Mount the overlay into the stage's overlay root.\n useLayoutEffect(() => {\n const el = overlayRef.current;\n if (!el) return;\n if (el.parentElement !== stage.overlayRoot) {\n stage.overlayRoot.appendChild(el);\n }\n return () => {\n if (el.parentElement === stage.overlayRoot) {\n stage.overlayRoot.removeChild(el);\n }\n };\n }, [stage]);\n\n return (\n <div\n ref={overlayRef}\n data-fancy-3d-screen={name}\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n width: innerSize.current.w,\n height: innerSize.current.h,\n transformOrigin: \"0 0\",\n pointerEvents: \"auto\",\n overflow: \"hidden\",\n background,\n borderRadius: 4,\n display: \"none\",\n }}\n >\n {children}\n </div>\n );\n}\n"]}
|