app
Adom Fields
Public Made by Adomby adom
Adom Fields: where the current and the heat go on your board.
← Commit history
adom-fields 0.8.4: user drag/wheel cancels camera moves and holds the drift
5 files changed
+21−26
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-fields"-version = "0.8.3"+version = "0.8.4" edition = "2021" license = "MIT" description = "Adom Fields: where the current and the heat go on your board. Current density, copper heat flow and board temperature from the board file itself, in 3D, for the AI to drive and the human to explore."
docs/release-0.8.4.mdadded+3@@ -0,0 +1,3 @@+# adom-fields 0.8.4++- **The 3D view is yours when you grab it.** A press or a mouse wheel in the view stops any camera move in flight (a preset tween, the Energy view's front turn and its return) and holds the slow drift until you have let go for 20 seconds. Commands from the AI still move the camera.
package.json+1−1@@ -1,7 +1,7 @@ { "slug": "adom-fields", "type": "app",- "version": "0.8.3",+ "version": "0.8.4", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",
page.json+8−23@@ -1,7 +1,7 @@ { "slug": "adom-fields", "type": "app",- "version": "0.8.3",+ "version": "0.8.4", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",@@ -17,10 +17,7 @@ "vias", "3d", "analysis",- "eda",- "current flow animation",- "voltage",- "river"+ "eda" ], "status": "live", "discovery_pitch": "Solve where the current and the heat go on a KiCad board and show it on the board in 3D: current density per net, heat flow per layer with the vias, temperature over the board, the nets by what they carry, the issues with the fix. One command to solve, one to serve, one to drive it on camera.",@@ -40,10 +37,11 @@ "fields", "flow of current", "river view",- "voltage drop in 3d",- "ground bounce",+ "energy flow on a board",+ "poynting vector",+ "speed of light on a pcb",+ "electron drift speed", "exploded layer stack",- "current through vias", "explain the view out loud", "narrate the fields", "energy cycle",@@ -85,20 +83,7 @@ "anti-resonance", "input filter stability", "middlebrook",- "ngspice pdn",- "signals view",- "copper capacitance",- "switch node capacitance",- "plane capacitance",- "differential pair skew",- "six layer board",- "receiver frequency plan",- "lo leakage",- "tone in band",- "rf crosstalk",- "return path over supply plane",- "antenna ground loop",- "stage feed bypass"+ "ngspice pdn" ], "sample_prompts": [ {@@ -139,4 +124,4 @@ "name": "John Lauer", "email": "[email protected]" }-}+}
src/ui/app.js+8−1@@ -338,8 +338,9 @@ // the drift: about six degrees of sway and a breath of tilt, over forty seconds (twenty before 0.5), // so a held view is never a frozen frame and never a spin const drift = { t: 0, base: null, last: null };+ const user = { until: 0 }; // set when the user grabs the view (below) scene.onBeforeRenderObservable.add(() => {- if (!state.view.drift || tweening > 0 || !board) { drift.base = null; return; }+ if (!state.view.drift || tweening > 0 || !board || performance.now() < user.until) { drift.base = null; return; } const dt = frameDt(); if (!drift.base || (drift.last !== null && Math.abs(camera.alpha - drift.last) > 1e-4)) { drift.base = { a: camera.alpha, b: camera.beta }; drift.t = 0; } drift.t += dt;@@ -469,6 +470,12 @@ img.onload = () => { const c = document.createElement('canvas'); c.width = img.width; c.height = img.height; const ctx = c.getContext('2d'); ctx.drawImage(img, 0, 0); const d = ctx.getImageData(0, 0, c.width, c.height).data; state.raw[name] = { w: c.width, h: c.height, d }; }; } }+ // the viewer is the user's the moment they grab it: a press or a wheel in the 3D view stops any camera move in flight+ // (a tween, the Energy view's front turn and its return) and holds the drift until they have let go for 20 s+ scene.onPointerObservable.add((pi) => {+ if (pi.type !== BAB.PointerEventTypes.POINTERDOWN && pi.type !== BAB.PointerEventTypes.POINTERWHEEL) return;+ user.until = performance.now() + 20000; tweens = []; tweening = 0; energy.tok++; drift.base = null;+ }); scene.onPointerObservable.add((pi) => { if (pi.type !== BAB.PointerEventTypes.POINTERMOVE || !board) return; const pick = scene.pick(scene.pointerX, scene.pointerY, (m) => state.view.quantity === 'river' ? m.name.startsWith('R-') : m.name.startsWith('L-'));