molecule
Evan — Adom Molecule LED Nameplate
Public Made by Adomby adom
Evan's name in 66 green 0603 LEDs on a 5x7 dot-matrix grid, USB-C powered off the east edge. A real Adom molecule: four corner machine pins, 96x44 mm absolute, every part from the Adom Basic Parts catalog.
← Commit history
Sandbox rescue: start the render loop, add a fallback light, frame the camera. The wiki CSP leaves all three silently undone.
1 file changed
+74
viewer/index.html+74@@ -1489,6 +1489,80 @@ async function loadCurrentGlb(force) { viewer.frameModel(); setView('isometric'); for (const ms of [50, 200, 600, 1500]) setTimeout(applyGroundTransparency, ms);++ // ── Sandbox rescue ────────────────────────────────────────────────────+ // The wiki serves this page under a CSP that sandboxes it to a null+ // origin (`sandbox allow-scripts ...; default-src 'none'; img-src data:+ // https:; media-src data: https:`). Three things break there, and all+ // three are silent — no console error, the GLB reports "loaded", and you+ // get a blank canvas:+ //+ // 1. NO RENDER LOOP. engine.activeRenderLoops is empty, so scene.render+ // is never called. getFps() still reports 60, which is what makes+ // this so easy to misdiagnose. Measure frames with+ // onAfterRenderObservable instead.+ // 2. NO LIGHTS. environmentSpecular.env fetches fine (200) but Babylon+ // turns it into a blob: URL, which media-src refuses, so+ // scene.environmentTexture stays null and every PBR material renders+ // black. Adom3DViewer.BABYLON exports no light class, so the only+ // way back is Scene.createDefaultLight().+ // 3. NO FRAMING. frameModel() leaves the camera at radius ~2500 on a+ // ~107 mm board, so even once it renders the board is a speck.+ //+ // Each guard is a no-op when the viewer is served normally.+ function sandboxRenderRescue() {+ if (!window.viewer) return;+ let engine, scene, B;+ try {+ engine = viewer.getEngine();+ scene = viewer.getScene();+ B = window.Adom3DViewer.BABYLON;+ } catch (e) { return; }+ if (!engine || !scene || !B) return;++ if (!engine.activeRenderLoops || engine.activeRenderLoops.length === 0) {+ engine.runRenderLoop(() => scene.render());+ }++ if (scene.lights.length === 0 && !scene.environmentTexture && scene.createDefaultLight) {+ scene.createDefaultLight(true);+ const l = scene.lights[0];+ if (l) {+ l.direction = new B.Vector3(-0.3, -0.5, 1);+ l.intensity = 2.2;+ l.diffuse = new B.Color3(1, 1, 1);+ l.groundColor = new B.Color3(0.45, 0.47, 0.5);+ l.specular = new B.Color3(0.6, 0.6, 0.6);+ }+ scene.ambientColor = new B.Color3(0.35, 0.35, 0.35);+ for (const m of scene.materials) {+ if (m.ambientColor) m.ambientColor = new B.Color3(1, 1, 1);+ if (m.environmentIntensity !== undefined) m.environmentIntensity = 0;+ }+ }++ const cam = scene.activeCamera;+ if (!cam || cam.radius === undefined) return;+ let mn = [Infinity, Infinity, Infinity], mx = [-Infinity, -Infinity, -Infinity];+ for (const m of scene.meshes) {+ if (!m.getTotalVertices || !m.getTotalVertices()) continue;+ m.computeWorldMatrix(true);+ const b = m.getBoundingInfo().boundingBox, a = b.minimumWorld, d = b.maximumWorld;+ mn = [Math.min(mn[0], a.x), Math.min(mn[1], a.y), Math.min(mn[2], a.z)];+ mx = [Math.max(mx[0], d.x), Math.max(mx[1], d.y), Math.max(mx[2], d.z)];+ }+ if (!isFinite(mn[0])) return;+ const diag = Math.hypot(mx[0] - mn[0], mx[1] - mn[1], mx[2] - mn[2]);+ if (!(diag > 0) || cam.radius <= diag * 3) return; // already framed+ const ctr = [(mn[0] + mx[0]) / 2, (mn[1] + mx[1]) / 2, (mn[2] + mx[2]) / 2];+ const r = diag * 1.15;+ cam.upperRadiusLimit = Math.max(cam.upperRadiusLimit || 0, r * 4);+ cam.upVector = new B.Vector3(0, 0, 1);+ cam.setPosition(new B.Vector3(ctr[0] + r * 0.55, ctr[1] - r * 0.62, ctr[2] + r * 0.55));+ cam.setTarget(new B.Vector3(ctr[0], ctr[1], ctr[2]));+ }+ for (const ms of [80, 400, 1200, 2500, 5000]) setTimeout(sandboxRenderRescue, ms);+ // BULLETPROOF enforcement — the viewer's goHome()/frameModel()/setView() // re-init the EnvironmentHelper and reset the ground alpha back to 1 // (opaque). The init-time retry loop above can't catch those LATER calls