# Material Library And Targeted Viewport Drop

Working implementation plan for Gitea issues
[`#16`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/16) and
[`#18`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/18).
The shared Material/Material Instance and stable renderer-slot foundation from `#51` is already
present; this slice completes the production-facing catalog and drag/drop workflow.

## Status

Source audit complete. Implementation starts on a clean branch after collaborative-safety `#49` is
published, because both slices touch the Asset Browser and should remain independently reviewable.

## Current Gaps

- Material assets are edited inside generic Asset Browser Details; no dedicated Material Library or
  scene-usage view exists.
- Viewport material/texture drops act on the existing selection instead of the surface under the
  pointer.
- Multi-slot renderers silently assign all slots; the hydrated draw hit already carries
  `HydratedRendererMaterialBinding`, but the drop path does not use it.
- Primitive and brush-face targeting is not explicit, and unsupported authored actors can receive a
  generic `MaterialDesc` instead of an actionable rejection.
- Drag UI describes an eventual action but does not preview the actual affected surface or restore a
  preview on cancel/target change.

## Material Library

1. Add a dockable `Material Library` panel, opened from Window and placed in the existing bottom dock
   without adding another permanent toolbar.
2. Present project Materials and Material Instances with search, Material/Instance filter, thumbnail
   grid/list modes, base/dependency health, and source-control status.
3. Add a scene-usage section that counts renderer-slot, primitive, and brush-face references and can
   select/locate users. Do not revive ambiguous hidden scene-local material clones.
4. Reuse the existing guarded Material/Instance drafts for Apply, Revert, Create Instance, and
   texture-parameter editing. Shared-file edits remain explicit; scene assignment changes use
   history.
5. Material and Instance cells are first-class drag sources and preserve the current pointer-following
   visual identity.

## Targeted Drop Contract

Introduce a frame-updated `ViewportAssetDropTarget` resolved by the existing mesh-picking path:

- A hydrated static/skinned draw maps through `HydratedRendererMaterialBinding` to the authored actor
  and exact stable slot ID.
- A primitive maps to its authored actor-level `MaterialDesc`.
- A brush performs authored face intersection and identifies the stable face ID.
- An authored but unsupported target remains a visible invalid target with a specific reason.
- Empty space remains placement-only for placeable assets and invalid for Material/Texture payloads.

Payload matrix:

| Payload | Renderer slot | Primitive | Brush face |
|---------|---------------|-----------|------------|
| Material / Material Instance | Assign exact hit slot; one-slot actors may assign directly | Replace actor material reference/values | Replace the hit face material reference |
| Texture | Reject with guidance to create/edit a Material Instance | Set base-color texture | Set hit-face base-color texture/material binding |

An explicit `Apply All Slots` command remains available from the renderer inspector/library usage
menu; a viewport hit never silently broadens from one slot to all slots.

## Preview, Commit, And Cancel

1. Start a persistent drop-preview session when a supported Material/Texture payload enters the
   viewport. Snapshot only the target's affected authored state.
2. Apply a transient visual preview without pushing history or marking the scene dirty.
3. When the pointer changes target, restore the previous snapshot before previewing the new target.
4. On release, restore the transient state first, then commit exactly one typed history/operator
   transaction to the identified slot, primitive, or face.
5. On Escape, drag cancellation, leaving the viewport, invalid target, or missing source, restore the
   exact snapshot and remove every preview/helper marker.
6. The drag card and target outline name the payload, actor, slot/face, action, and invalid reason.

## Verification

- Unit-test ray-hit to authored target/slot mapping, primitive/face targeting, and invalid reasons.
- Use `OperatorInvariantHarness` for preview target changes, release commit, Escape/outside cancel,
  dirty-state preservation, helper cleanup, and one-step undo/redo.
- Cover static one/multi-slot, skinned multi-slot, primitive, brush face, Texture rejection on a
  renderer slot, missing material, and linked/locked prefab boundaries.
- Verify Material Library filtering, scene-usage counts, dependency diagnostics, and drag sources in
  headless egui tests.
- Run full source/headless checks. Packaged testing remains deferred until the project owner requests
  it again; live visual acceptance is still required before closing `#16`/`#18`.
