# Adom 3D Viewer

The Babylon 9.5 viewer engine behind every component page's 3D tab on
wiki.adom.inc. A fork of `adom-inc/3d-viewer` (Babylon 7.54) upgraded to
Babylon 9.5 with the redesigned Inspector v9, built as a versioned ESM bundle
that downstream tools vendor (the wiki's native component viewer, chiplinter,
and the next wave of Adom 3D apps).

This page is the canonical home: the source lives on the Files tab
(`adom-wiki repo clone adom/adom-3d-viewer`), and each version's
built bundle is attached as a release asset you can pin.

## What is in 0.4.x

- Layers toolbar: slide-out per-layer visibility panel driven by the node
  naming convention (fr4_board, pad_top, silk, barrel, pin1_marker, ...).
- Z-fighting fixes for PCB models: 10x depth precision, polygon-offset
  tie-breaking for nested shells, near plane at radius/50, XY-area container
  ordering.
- Skybox mesh replaced by a screen-space background layer (tight far plane,
  faded ground rim): frameModel no longer fits a 5000-unit skybox.
- Sandbox storage guard: localStorage/sessionStorage access is wrapped, so the
  viewer initializes fully (lights, IBL, shadows) inside sandboxed iframes.
- Transparent radial-fade ground, hover tooltips, orbit-center UX,
  world-origin and mesh-local axis helpers, laser-etch text overlays.

## Get the bundle (pin a version)

Every release attaches the built bundle as a tarball asset:

```bash
adom-wiki release download adom/adom-3d-viewer <version> adom-3d-viewer-babylon9-<version>.tar.gz
tar -xzf adom-3d-viewer-babylon9-<version>.tar.gz -C ./vendor/3d-viewer/
```

The extracted `VERSION` file records exactly which build you have. The bundle
code-splits into ~60 chunks; serve them all from the same directory as the
entry (`adom-3d-viewer-babylon9.esm.js`) and browsers fetch chunks on demand.

## Embed it

```html
<!-- Browser shim for Node-style globals that @babylonjs/inspector's React
     (Fluent UI) deps assume. Add BEFORE loading the bundle. -->
<script>
  window.process = window.process || { env: { NODE_ENV: "production" } };
  window.global = window.global || window;
</script>

<script type="module">
  await import("./vendor/3d-viewer/adom-3d-viewer-babylon9.esm.js");
  const v = window.Adom3DViewerBabylon9;
  const viewer = v.init(host, { zUp: true, showViewCube: true });
  await viewer.loadModel("chip.glb");
  viewer.frameModel();
</script>
```

## Why ESM (not IIFE)

Babylon 9's `@babylonjs/inspector` has circular imports that resolve to TDZ
when collapsed into a single IIFE scope, regardless of minifier. Vite's ESM
output preserves module boundaries so the inspector initializes cleanly. The
global is `window.Adom3DViewerBabylon9` (distinct from the legacy
`window.Adom3DViewer`), so both bundles can coexist during a migration.

## API

```js
window.Adom3DViewerBabylon9 = {
  init(host, options),         // mounts the viewer, returns ViewerInstance
  rotateYUpToZUp(scene),       // kicad-cli GLBs (Y-up) -> adom viewer (Z-up)
  addLaserEtch(scene, opts),   // bake a laser-etched chip-marking text overlay
  BABYLON: <full @babylonjs/core namespace>,  // re-exported for consumers
};
```

`ViewerInstance` exposes:

- `loadModel(url)` / `clearScene()` / `frameModel(fillFraction?)`
- `getScene()` / `getEngine()` / `getCamera()` / `getShadowGenerator()`
- `addContentRoot(node, opts?)` / `removeContentRoot(node)`
- `toggleDebugLayer()` / `showDebugLayer()` / `hideDebugLayer()`
- `setGroundVisible(visible)` / `goHome()`
- `setProjectionMode(ortho)` / `getProjectionMode()`
- `toggleAxes("world" | "mesh-local", force?)` / `getAxesState()`
- `destroy()`

The full `@babylonjs/core` namespace is exposed at
`Adom3DViewerBabylon9.BABYLON` so consumers do not need their own import side.
chiplinter uses `V.BABYLON.MeshBuilder.CreateDisc`, `V.BABYLON.PBRMaterial`,
`V.BABYLON.Tools.CreateScreenshotUsingRenderTarget`, and friends directly.

## Build from source

```bash
adom-wiki repo clone adom/adom-3d-viewer
cd adom-3d-viewer
npm install
npx vite build --config vite.standalone.config.ts   # -> dist-standalone/
```

`npm run build` (plain `vite build`) produces the npm-consumable `dist/`
library instead; `dist-standalone/` is the self-contained browser bundle the
wiki and release assets ship.

## Consumers

- wiki.adom.inc component pages: git-wiki vendors `dist-standalone/` into
  `static/vendor/adom-3d-viewer-babylon9` and pins it via `VIEWER_BUNDLE_VER`.
- `adom-chiplinter`: vendors the release tarball into `vendor/3d-viewer/`.
- Downstream viewer work is tracked on adom/wiki issues (#48, #53, #60).

## Development

Source of record is this page's repo. GitHub `adom-inc/adom-3d-viewer-babylon9`
is the working mirror where CI and day-to-day commits happen; each released
version is ported here (source push + package publish + bundle release asset).
