← Commit history

Enable shadows for everything in the 3D viewer: every content mesh (LED, board, footprint, carrier tape and reel, nozzle, pocket LEDs, cover) now casts AND receives shadows; the ground receives only; translucent ghosts use transparencyShadow for soft alpha-weighted shadows. Updates both the characterization-page hero viewer (IN-S42ATR-viewer.html) and the README landing embed (README.html srcdoc).

AravK ·3f34a71a2e ·3mo ago ·parent 0338337
2 files changed +32−10
IN-S42ATR-viewer.html+16−5
@@ -127,14 +127,24 @@   // older, so we do it here — same effect, no change to his code.) refreshRate=1 keeps the   // cast shadow updating as the LED animates.   const sg = viewer.getShadowGenerator && viewer.getShadowGenerator();-  if (sg) {+  // Shadows for EVERYTHING: every content mesh casts AND receives; the ground only receives;+  // skybox / view-cube / axes are environment helpers (neither). Called once after ALL geometry+  // (model + tape/reel + ghosts) is built so nothing is missed. transparencyShadow lets the+  // translucent ghosts (nozzle, cover tape) cast alpha-weighted shadows instead of hard ones.+  const shadowed = new Set();+  const registerShadows = () => {+    if (!sg) return;+    if (sg.setTransparencyShadow) sg.setTransparencyShadow(true); else sg.transparencyShadow = true;     scene.meshes.forEach(m => {-      if (m.getTotalVertices && m.getTotalVertices() > 0 && !/skyBox|shadowGround|^ground$|viewCube|axis/i.test(m.name)) {-        m.receiveShadows = true; sg.addShadowCaster(m);+      if (!m.getTotalVertices || m.getTotalVertices() === 0) return;+      if (/skyBox|viewCube|axis|gizmo/i.test(m.name)) return;+      m.receiveShadows = true;                                                     // everything receives (incl. ground)+      if (!/shadowGround|^ground$/i.test(m.name) && !shadowed.has(m)) {            // ground receives but doesn't cast+        sg.addShadowCaster(m, true); shadowed.add(m);                              // (Set guard avoids duplicate casters)       }     });     const smap = sg.getShadowMap(); if (smap) smap.refreshRate = 1;-  }+  };    // 3) Translucent ghosts (nozzle + carrier tape + component-in-tape), built with HIS Babylon.   const PX = 0.0065, LED_TOP = 0.00045;@@ -216,6 +226,7 @@   });   const cover = B.MeshBuilder.CreateBox('cover_tape', { width:tLen, height:TW*0.6, depth:0.00003 }, scene);  // clear cover tape   cover.position = new B.Vector3(tCx, PKY + TBo*0.2, 0.00004); cover.material = coverMat; cover.parent = tape;+  registerShadows();   // now that ALL geometry exists (model + tape/reel + nozzle + pocket LEDs + cover), enable shadows on everything    // 4) Motion — manual per-frame interpolation (no baked groups); positions in the model's space.   const LIFT=0.00135, NHI=0.0032, NLO=0.00047, CARRY=0.0027;@@ -302,7 +313,7 @@       applyFrame(m);       statusEl.textContent = 'STATIC · LED insertion (up/down) · toggle Light & FOV in Layers';     } else {-      setNodeEnabled(ghostRoot, true); viewer.addContentRoot(ghostRoot, { castShadows:false, receiveShadows:false });+      setNodeEnabled(ghostRoot, true); viewer.addContentRoot(ghostRoot, { castShadows:true, receiveShadows:true });       if (ledLit) setNodeEnabled(ledLit, false); if (fovCone) setNodeEnabled(fovCone, false); if (ptLight) ptLight.setEnabled(false);       lockLayer('light',true); lockLayer('fov',true);       if (led) setNodeEnabled(led, true);
README.html+16−5
@@ -161,14 +161,24 @@   // older, so we do it here — same effect, no change to his code.) refreshRate=1 keeps the   // cast shadow updating as the LED animates.   const sg = viewer.getShadowGenerator && viewer.getShadowGenerator();-  if (sg) {+  // Shadows for EVERYTHING: every content mesh casts AND receives; the ground only receives;+  // skybox / view-cube / axes are environment helpers (neither). Called once after ALL geometry+  // (model + tape/reel + ghosts) is built so nothing is missed. transparencyShadow lets the+  // translucent ghosts (nozzle, cover tape) cast alpha-weighted shadows instead of hard ones.+  const shadowed = new Set();+  const registerShadows = () => {+    if (!sg) return;+    if (sg.setTransparencyShadow) sg.setTransparencyShadow(true); else sg.transparencyShadow = true;     scene.meshes.forEach(m => {-      if (m.getTotalVertices && m.getTotalVertices() > 0 && !/skyBox|shadowGround|^ground$|viewCube|axis/i.test(m.name)) {-        m.receiveShadows = true; sg.addShadowCaster(m);+      if (!m.getTotalVertices || m.getTotalVertices() === 0) return;+      if (/skyBox|viewCube|axis|gizmo/i.test(m.name)) return;+      m.receiveShadows = true;                                                     // everything receives (incl. ground)+      if (!/shadowGround|^ground$/i.test(m.name) && !shadowed.has(m)) {            // ground receives but doesn't cast+        sg.addShadowCaster(m, true); shadowed.add(m);                              // (Set guard avoids duplicate casters)       }     });     const smap = sg.getShadowMap(); if (smap) smap.refreshRate = 1;-  }+  };    // 3) Translucent ghosts (nozzle + carrier tape + component-in-tape), built with HIS Babylon.   const PX = 0.0065, LED_TOP = 0.00045;@@ -250,6 +260,7 @@   });   const cover = B.MeshBuilder.CreateBox('cover_tape', { width:tLen, height:TW*0.6, depth:0.00003 }, scene);  // clear cover tape   cover.position = new B.Vector3(tCx, PKY + TBo*0.2, 0.00004); cover.material = coverMat; cover.parent = tape;+  registerShadows();   // now that ALL geometry exists (model + tape/reel + nozzle + pocket LEDs + cover), enable shadows on everything    // 4) Motion — manual per-frame interpolation (no baked groups); positions in the model's space.   const LIFT=0.00135, NHI=0.0032, NLO=0.00047, CARRY=0.0027;@@ -336,7 +347,7 @@       applyFrame(m);       statusEl.textContent = 'STATIC · LED insertion (up/down) · toggle Light & FOV in Layers';     } else {-      setNodeEnabled(ghostRoot, true); viewer.addContentRoot(ghostRoot, { castShadows:false, receiveShadows:false });+      setNodeEnabled(ghostRoot, true); viewer.addContentRoot(ghostRoot, { castShadows:true, receiveShadows:true });       if (ledLit) setNodeEnabled(ledLit, false); if (fovCone) setNodeEnabled(fovCone, false); if (ptLight) ptLight.setEnabled(false);       lockLayer('light',true); lockLayer('fov',true);       if (led) setNodeEnabled(led, true);