# PARCELVAN white-body material audit (r323)

## Asset evidence

Source and packaged asset:

- `reverse-engineering/traffic-ambient-parcelvan-body-a.glb`
- `dist/reverse-engineering/traffic-ambient-parcelvan-body-a.glb`

The exported manifest reports three source objects, 10 GLB primitives, 513 triangles, and four embedded PNGs. The images and their assigned GLB materials are:

| Material | Source key | Image | Role |
| --- | --- | --- | --- |
| `CARBOTTOM` | `0xbd1f0e0a` | image 0 | Underbody map |
| `DRIVER` | `0x5799e60b` | image 1 | Driver/interior overlay; alpha blend |
| `WINDOW_TRAFFIC` | `0x008a6835` | image 2 | Traffic window overlay; alpha blend |
| `TIREBACK` | `0xc8c5a8a4` | image 3 | Tire mask; alpha mask |

The large rear cargo panel is primitive `PARCELVAN_BODY_A_0_slice2_slot0`: 1,020 indices (340 triangles), material `paint_body`. That material has source material hash `0x19e0ecbe`, no `baseColorTexture`, no resolved source texture key, white `baseColorFactor` `[1,1,1,1]`, and `extras.paintState = "unresolved"`. The source geometry's `COLOR_0` values on this slice are grayscale vertex data; they do not encode a colored paint texture. The per-car ambient `CARS/PARCELVAN/TEXTURES.BIN` is empty.

## Renderer trace

`loadTrafficBodyVariant()` in `webgl-city/viewer.js` parses the GLB, calls `uploadTextures(doc, bin)` for its embedded images, and assigns the returned texture array to each uploaded batch. In the traffic draw loop, the renderer sets `uUseTexture` from that material's `baseColorTexture`, binds the indexed texture when present, and writes the material's own base color on every batch. For `paint_body`, the texture reference is absent, so `uUseTexture` is set to zero. Its white appearance is therefore the explicit unresolved-material fallback; it is not a failed upload of one of the four embedded maps or stale texture state from another batch.

The close Chrome capture at `/tmp/nfsu2-route736-traffic-lane-fix-close.png` shows this asset from the rear: its broad cargo panel reads as a plain white box. The capture's debug record is `/tmp/nfsu2-route736-traffic-lane-fix-debug.json`. This view confirms the visible result but does not change the source evidence.

No authentic body paint bitmap or exact paint color is available in this GLB. Reassigning `CARBOTTOM`, `WINDOW_TRAFFIC`, `TIREBACK`, or a decal mask to `paint_body` would place unrelated image content on the cargo panel. The remaining source-backed input is a retail runtime traffic paint/material capture for the `0x19e0ecbe` body draw, including its selected paint and bound texture or color state. Until then, the plain preview material should remain clearly unresolved.

## Related Route 736 placement check

The traffic lane correction is in `trafficVisibleLanePose()` in source and dist viewer files. `updateTrafficDriverPose()` starts from `trafficPoseOnRoadLane()` and constrains its position to road triangles; the returned `laneOffset` is selection metadata, not a request to translate that already shifted position again. The function now preserves dynamic driver X/Y and reports `laneOffsetApplied = 0`, while static route previews still apply their selected texture-gated offset.

In packaged Chrome at `?debug&route=736&distance=107&radius=220&trafficModel=PARCELVAN`, pre-correction telemetry for Route 736 showed `laneOffset = 1.7965` and unsupported road position with zero movement since driver-state initialization. After the correction it showed `laneOffset = 1.7965`, `laneOffsetApplied = 0`, and `roadSurfaceSupported = true`. This validates the preview's mesh support at that pose; it does not establish retail traffic lane selection or paint state.
