← Commit history

shadows: use the BUNDLE's own SpotLight+PCF shadow rig (proven in /viewer), repositioned/rescaled for the meter-scale scene, map unfrozen for animation

John Lauer ·8a2ff4b2f2 ·3mo ago ·parent 07f53cb
3 files changed +43−39
package.json+1−1
@@ -2,7 +2,7 @@   "slug": "bq25792-charger",   "title": "BQ25792 Charger",   "type": "component",-  "version": "0.1.68",+  "version": "0.1.69",   "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.68",+  "version": "0.1.69",   "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+32−35
@@ -370,47 +370,44 @@ exported bodies + design rules.</p>     quad("mask_bot","layer-mask-bot.png",-0.075*mm,true,false);     quad("silk_bot","layer-silk-bot.png",-0.083*mm,true,false); -    // Our OWN shadow rig (the bundle's ground has a null material + darkness 0 in this-    // sandbox, so it catches nothing). A directional light casts every layer onto a-    // dedicated semi-transparent ground we own.+    // USE THE BUNDLE'S OWN SHADOW RIG (proven: the built-in /viewer renders gorgeous crisp+    // shadows with it). SceneBuilder makes a SpotLight + 8192 PCF ShadowGenerator at init,+    // tuned for mm-scale scenes and repositioned by frameModel - which we bypass, so we+    // reposition/rescale the spot for our meter-scale board ourselves.     if(sc.lights.length===0){ new (B().HemisphericLight)("rm_hemi",new (B().Vector3)(0.2,0.2,1),sc).intensity=0.9; }-    // Overhead-ish directional light with PCF shadows (the technique the native bundle uses-    // and that actually renders). Slight XY offset so the shadow peeks out from under the board.-    SHADOW_LIGHT=new (B().DirectionalLight)("rm_shadow",new (B().Vector3)(0.25,0.3,-1),sc);-    SHADOW_LIGHT.position=new (B().Vector3)(0.0252,0.0132,0.25);-    SHADOW_LIGHT.intensity=1.1; SHADOW_LIGHT.autoUpdateExtends=true;-    SHADOW_LIGHT.shadowMinZ=0.01; SHADOW_LIGHT.shadowMaxZ=0.6;-    SHADOW_GEN=new (B().ShadowGenerator)(2048,SHADOW_LIGHT);-    SHADOW_GEN.usePercentageCloserFiltering=true; SHADOW_GEN.filteringQuality=B().ShadowGenerator.QUALITY_HIGH;-    SHADOW_GEN.darkness=0.35; SHADOW_GEN.bias=0.00005; SHADOW_GEN.normalBias=0.002;-    SHADOW_GEN.getShadowMap().refreshRate=B().RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYFRAME;-    // cast from EVERY layer mesh (Colby freezes the bundle's map for perf; for animation we-    // keep ours refreshing every frame so shadows track the moving layers).+    const CENTER=new (B().Vector3)(0.0252,0.0132,0);+    SHADOW_LIGHT=sc.getLightByName("spotLight");+    SHADOW_GEN=(viewer.getShadowGenerator && viewer.getShadowGenerator()) ||+               (SHADOW_LIGHT && SHADOW_LIGHT.getShadowGenerator && SHADOW_LIGHT.getShadowGenerator());+    if(SHADOW_LIGHT && SHADOW_GEN){+      // frameModel's job, done by hand: spot at the mm-rig's (600,-300,1500) ratio, scaled to meters+      SHADOW_LIGHT.position=new (B().Vector3)(CENTER.x+0.6, CENTER.y-0.3, 1.5);+      SHADOW_LIGHT.direction=CENTER.subtract(SHADOW_LIGHT.position).normalize();+      SHADOW_LIGHT.intensity=2.2;                    // 2e6 was for mm distances; ~2 at meter scale+      SHADOW_LIGHT.shadowMinZ=0.5; SHADOW_LIGHT.shadowMaxZ=3.0;+    }else{+      // fallback: build a PCF spot matching the bundle's recipe+      SHADOW_LIGHT=new (B().SpotLight)("rm_spot",new (B().Vector3)(CENTER.x+0.6,CENTER.y-0.3,1.5),+        CENTER.subtract(new (B().Vector3)(CENTER.x+0.6,CENTER.y-0.3,1.5)).normalize().scale(-1).scale(-1),Math.PI*0.7,50,sc);+      SHADOW_LIGHT.direction=CENTER.subtract(SHADOW_LIGHT.position).normalize();+      SHADOW_LIGHT.intensity=2.2;+      SHADOW_GEN=new (B().ShadowGenerator)(4096,SHADOW_LIGHT);+      SHADOW_GEN.usePercentageCloserFiltering=true; SHADOW_GEN.filteringQuality=B().ShadowGenerator.QUALITY_HIGH;+      SHADOW_GEN.bias=0.0000002; SHADOW_GEN.normalBias=0.00008; SHADOW_GEN.darkness=-1;+      SHADOW_GEN.forceBackFacesOnly=true;+    }+    // Colby freezes the bundle's shadow map for perf; our layers MOVE, so refresh every frame.+    try{ SHADOW_GEN.getShadowMap().refreshRate=B().RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYFRAME; }catch(e){}     LAYERS.forEach(L=>L.meshes.forEach(m=>{ try{ SHADOW_GEN.addShadowCaster(m,true);}catch(e){} })); -    // Dedicated ground just under the board. Prefer ShadowOnlyMaterial (invisible except-    // where the shadow lands - true see-through ground with a crisp shadow); fall back to a-    // lit translucent plane if the material isn't in the bundle.+    // Semi-transparent ground that receives the bundle's shadow (like /viewer's ground).     GROUND_PLANE=B().MeshBuilder.CreateGround("adomGround",{width:0.3,height:0.3},sc);-    GROUND_PLANE.position=new (B().Vector3)(0.0252,0.0132,-0.0015);+    GROUND_PLANE.position=new (B().Vector3)(CENTER.x,CENTER.y,-0.0015);     GROUND_PLANE.rotation.x=Math.PI/2;           // face up in a z-up scene-    let gm;-    if(B().ShadowOnlyMaterial){-      gm=new (B().ShadowOnlyMaterial)("adomGroundMat",sc);-      gm.activeLight=SHADOW_LIGHT; gm.alpha=0.5; gm.shadowColor=new (B().Color3)(0,0,0);-    }else{-      gm=new (B().StandardMaterial)("adomGroundMat",sc);-      gm.diffuseColor=new (B().Color3)(0.72,0.74,0.78); gm.specularColor=new (B().Color3)(0,0,0);-      gm.emissiveColor=new (B().Color3)(0.20,0.21,0.23);  // ambient floor so the shadow is dark-gray, not black-      gm.alpha=0.4;-    }-    gm.backFaceCulling=false;+    const gm=new (B().StandardMaterial)("adomGroundMat",sc);+    gm.diffuseColor=new (B().Color3)(0.62,0.64,0.68); gm.specularColor=new (B().Color3)(0,0,0);+    gm.alpha=0.35; gm.backFaceCulling=false;     GROUND_PLANE.material=gm; GROUND_PLANE.receiveShadows=true;-    // the shadow light lights ONLY the ground (keeps the copper/parts on the env look) so the-    // occluded region genuinely darkens instead of being washed out by a fill light.-    SHADOW_LIGHT.includedOnlyMeshes=[GROUND_PLANE];-    // hide the bundle's decorative background ground/skybox tinting I mistakenly touched-    sc.meshes.filter(m=>/BackgroundSkybox/i.test(m.name||"")).forEach(m=>{ try{ if(m.material) m.material.alpha=1; }catch(e){} });      // ground: 80% transparent, receives shadows