← Commit history

native viewer rig: unquantized groups (true bounds -> bundle framing/spot/shadows/viewcube), real FR4 sublayers with drill holes, no render-loop override

John Lauer ·2db5617279 ·3mo ago ·parent f7a82c6
7 files changed +40−45
grp-board.glb.pngadded
⋯ 1 unchanged line ⋯
grp-components.glb.png
⋯ 1 unchanged line ⋯
grp-cu1.glb.png
⋯ 1 unchanged line ⋯
grp-cu16.glb.png
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -2,7 +2,7 @@   "slug": "bq25792-charger",   "title": "BQ25792 Charger",   "type": "component",-  "version": "0.1.27",+  "version": "0.1.28",   "description": "BQ25792 Charger - buck-boost 1S-4S battery charger board by Adonis, with real 3D copper traces and measured stackup.",   "tags": [     "hardware"
page.json+10−3
@@ -4,9 +4,16 @@   "slug": "bq25792-charger",   "title": "BQ25792 Charger",   "brief": "Buck-boost 1S-4S battery charger board (TI BQ25792) with 14 Adom machine pins, by Adonis",-  "version": "0.1.27",+  "version": "0.1.28",   "tags": [-    "hardware"+    "adom",+    "adom-modular",+    "component",+    "charger",+    "battery",+    "bq25792",+    "power",+    "usb-c"   ],   "license": "proprietary",   "component": {@@ -49,7 +56,7 @@     "email": "[email protected]"   },   "visibility": "public",-  "description": "BQ25792 Charger - buck-boost 1S-4S battery charger board by Adonis, with real 3D copper traces and measured stackup.",+  "description": "BQ25792 Charger - a buck-boost 1S-4S battery charger board (Texas Instruments BQ25792) designed by Adonis in Fusion 360, with 14 Adom machine pins for the modular stack. Interactive colored 3D model, schematic and layout views.",   "dependencies": {},   "files": [     "README.md",
readme.html+29−41
@@ -179,8 +179,6 @@ exported bodies + design rules.</p>     viewer.frameModel();     try{ if(viewer.toggleAxes) viewer.toggleAxes("world",false); }catch(e){}     const compMeshes=sc.meshes.slice(pre);-    // ensure a live render loop (bundle starts it in loadModel, keep ours as belt+suspenders)-    eng.stopRenderLoop(); eng.runRenderLoop(function(){ sc.render(); });      // 2) outer copper groups appended into the same scene     for (const g of [["grp-cu1.glb.png", 18*mm-1.5335*mm, "cu1"],["grp-cu16.glb.png", -18*mm+0.0185*mm, "cu16"]]){@@ -192,20 +190,29 @@ exported bodies + design rules.</p>     }     reg(compMeshes, 36*mm-1.582*mm); -    // 3) FR4 slabs (prepreg/core/prepreg) as translucent boxes at exact thickness-    const fr4mat=new (B().StandardMaterial)("fr4",sc);-    fr4mat.diffuseColor=new (B().Color3)(0.45,0.42,0.28); fr4mat.alpha=0.72; fr4mat.backFaceCulling=false;-    function slab(name, zc, th, delta){-      const bx=B().MeshBuilder.CreateBox(name,{width:50.4*mm,depth:26.4*mm,height:th},sc);-      bx.position=new (B().Vector3)(25.2*mm,13.2*mm,zc); bx.rotation.x=Math.PI/2;  // zUp scene: check axis below-      bx.material=fr4mat;-      reg([bx], delta);-      return bx;+    // 3) FR4 sublayers: clones of the REAL Board body (actual drill holes), z-scaled to+    // each sublayer's thickness. Split fitted to the measured 1.516mm (Fusion design+    // rules hold 2-layer defaults); matches the standard JLC 4-layer stack.+    const boardBytes=await loadPngBytes(R+"grp-board.glb.png");+    pre=sc.meshes.length;+    await B().SceneLoader.AppendAsync("", new File([boardBytes],"board.glb",{type:"model/gltf-binary"}), sc, null, ".glb");+    const boardMeshes=sc.meshes.slice(pre).filter(m=>m.getTotalVertices&&m.getTotalVertices()>0);+    const FR4_TH=1.516*mm, FR4_C=0.758*mm;+    function fr4Layer(zc, th, delta, src){+      const clones=src.map(function(m,i){+        const c=m.clone("fr4_"+zc+"_"+i);+        c.scaling=m.scaling.clone(); c.scaling.z=m.scaling.z*(th/FR4_TH);+        c.position=m.position.clone();+        c.position.z=zc-FR4_C*(th/FR4_TH)+ (m.position.z);+        if(c.material){ c.material=c.material.clone("fr4m"+zc); c.material.alpha=0.8; }+        return c;+      });+      reg(clones, delta);     }-    // zUp:true scenes from this bundle keep Z as up; boxes are Y-up primitives -> rotate so height aligns Z-    slab("ppg_top", 1.416*mm, 0.200*mm, 12*mm-1.416*mm);-    slab("core",    0.758*mm, 1.046*mm,  0-0.758*mm);-    slab("ppg_bot", 0.100*mm, 0.200*mm, -12*mm-0.100*mm);+    fr4Layer(1.416*mm, 0.200*mm, 12*mm-1.416*mm, boardMeshes);+    fr4Layer(0.758*mm, 1.046*mm,  0-0.758*mm,   boardMeshes);+    fr4Layer(0.100*mm, 0.200*mm, -12*mm-0.100*mm, boardMeshes);+    boardMeshes.forEach(m=>{ m.setEnabled(false); });      // 4) gerber quads: silk, mask, inner copper     function quad(name, tex, zc, delta, mirror){@@ -228,20 +235,12 @@ exported bodies + design rules.</p>     quad("mask_bot","layer-mask-bot.png",-0.075*mm,-24*mm+0.075*mm,true);     quad("silk_bot","layer-silk-bot.png",-0.083*mm,-30*mm+0.083*mm,true); -    // 5) environment + lights + shadows+    // 5) lights/env/shadows come from the bundle's SceneBuilder (embedded studio env,+    // hemispheric + spot + PCF shadows) - register our meshes as shadow casters only.     try{-      const env=new (B().EquiRectangularCubeTexture)(R+"studio-env.png",sc,128);-      sc.environmentTexture=env; sc.environmentIntensity=0.9;+      const sg=sc.lights.map(l=>l.getShadowGenerator&&l.getShadowGenerator()).find(Boolean);+      if(sg) LAYERS.forEach(L=>L.meshes.forEach(m=>{ try{ sg.addShadowCaster(m,true);}catch(e){} }));     }catch(e){}-    if(sc.lights.length===0){-      new (B().HemisphericLight)("hemi",new (B().Vector3)(0.2,0.2,1),sc).intensity=0.9;-    }-    const key=new (B().DirectionalLight)("key",new (B().Vector3)(-0.4,-0.5,-1),sc);-    key.intensity=1.3; key.position=new (B().Vector3)(0.1,0.1,0.3);-    const sg=new (B().ShadowGenerator)(2048,key);-    sg.useBlurExponentialShadowMap=true; sg.blurKernel=16;-    LAYERS.forEach(L=>L.meshes.forEach(m=>{ try{ sg.addShadowCaster(m,true);}catch(e){} }));-     // 6) ground: 80% transparent + receives shadows     sc.meshes.forEach(m=>{       if(/ground/i.test(m.name||"")){@@ -249,20 +248,9 @@ exported bodies + design rules.</p>       }     }); -    // 7) frame generously for the exploded extents-    setTimeout(function(){-      try{-        const ext=sc.getWorldExtends();-        const c=new (B().Vector3)((ext.min.x+ext.max.x)/2,(ext.min.y+ext.max.y)/2,(ext.min.z+ext.max.z)/2);-        const dx=ext.max.x-ext.min.x, dy=ext.max.y-ext.min.y, dz=ext.max.z-ext.min.z;-        const diag=Math.sqrt(dx*dx+dy*dy+dz*dz);-        const cam=sc.activeCamera;-        cam.setTarget(c);-        cam.radius=diag*1.5; cam.beta=1.15; cam.alpha=-1.2;-        cam.minZ=diag*0.005; cam.maxZ=diag*300;-        if(typeof cam.wheelPrecision==="number") cam.wheelPrecision=3/diag;-      }catch(e){}-    },400);+    // 7) native frameModel handles framing/spotlight now (true bounds, unquantized);+    // widen slightly for exploded headroom.+    setTimeout(function(){ try{ const cam=sc.activeCamera; cam.radius=cam.radius*1.6; cam.beta=1.15; }catch(e){} },400);     set("animating");   }