Owner instruction: show the building, its entrance, the neighbouring buildings, front-on, and drop the close-up detail framing. - Studies replaced: door-recess / entrance-wide / column-order / entablature-cornice / parapet-motto / window-rhythm / street-wall / banner-detail -> building-front, building-entrance, building-with-neighbours, building-street-front, building-front-oblique, theatre-front-with-neighbours. - ANCHOR_SUFFIX now permits REFRAMING (step back, zoom out, widen the view) so the whole building can fit, while the architecture stays fixed; previously it pinned the camera angle to the reference, which forced cropped results. - Prompts state 'exterior' explicitly (the entrance study otherwise produced an interior) and require sky above the roofline and nothing cut off. Vision pre-check on the regenerated set: building-entrance and building-street-front read as full-elevation frontal plates; the studies anchored on the tightly cropped 2009 facade photo stay cropped, because the model will not invent the parapet and sky the photograph does not contain. That limitation is recorded in the study table comment - a full 6840 plate needs a full-elevation photograph we do not hold. Tests: 40 pass (study table assertions unchanged).
85 lines
5.4 KiB
Markdown
85 lines
5.4 KiB
Markdown
# Tools
|
|
|
|
Repeatable helpers that drive Blender, Unreal, and the reference/asset sources. Nothing here is hand-run twice: every step that produced committed content has a script.
|
|
|
|
Geographic tools live in [`Geo/tools/`](../Geo/README.md) and the Blender-side builders live next to their output in `Art/blender/*/`; this folder holds everything that talks to Unreal, the network, or the repository.
|
|
|
|
## Conventions
|
|
|
|
- One script, one job. Every input is an argument; no interactive prompts.
|
|
- Absolute paths where a tool crosses into a sandbox (Blender Flatpak, the Unreal commandlet). Those processes do not share the repo's working directory.
|
|
- Unreal commandlets swallow `print()`, so each writes a result file under `/tmp/gigline/`. Read the file; do not trust the exit code alone.
|
|
- No credentials, no writes outside the project by default.
|
|
|
|
## Repository and assets
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `check-lfs.sh` | Fails if the `lfs` filter is missing or an LFS-tracked file was committed as a plain blob |
|
|
| `sibling_asset_audit.py` | Reads the sibling project's prop library from GLB headers into `Art/props/reuse-manifest.json`; copies nothing |
|
|
| `scale_test_export.py` / `ue_scale_test_import.py` | The 1 m = 100 uu scale test; the named presets `ue_metric_v1` live in these two files |
|
|
|
|
## Reference gathering
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `commons_fetch.py` | Wikimedia Commons: search, exact `File:` titles, or a whole category; writes a provenance `sidecar.json` |
|
|
| `page_image_fetch.py` | Resolves a web page's `og:image` and downloads it (Flickr, Commons file pages, photo blogs) |
|
|
| `addon_compat_probe.py` | Verifies MPFB/Blosm can load and generate headless on the pinned Blender |
|
|
|
|
## Blender content
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `hero_facade_build.py` | Parametric hero façade; emits a JSON report naming the evidence behind every part |
|
|
| `mpfb_character_export.py` | MPFB human, standard rig, baked skin, FBX export |
|
|
|
|
## Unreal import and level building
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `ue_import_site.py` | Imports the six site FBXs into `/Game/Hollywood/Site`, setting collision complexity per mesh |
|
|
| `ue_hero_facade_import.py` | Imports the façade and places it on the measured building line |
|
|
| `ue_build_demo_map.py` | Builds `/Game/Hollywood/DemoMap`: lighting, façade, site meshes, player start |
|
|
| `ue_build_review_map.py` | Rebuilds `Test/ReviewMap`, stages the shot camera list, and stages the demo-map views |
|
|
| `ue_create_input_assets.py` | Creates `/Game/Input` actions and the mapping context headlessly |
|
|
| `ue_character_import.py` | Skeletal import plus the material/texture chain Interchange skips |
|
|
|
|
## Visual review
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `render_screenshots.py` / `render_screenshots.sh` | Rebuilds the review map, runs the game, captures the shot list into `Screenshots/` |
|
|
| `judge_screenshot.py` | Vision-model pre-check: judges a screenshot against an expected-scene description (`--image` + `--expect`, or `--shots` for every shot in the README). Reads `OPENROUTER_API_KEY` from `.env` (ignored). Optional helper — a human must still approve. |
|
|
|
|
## Gameplay QA
|
|
|
|
| Command | Purpose |
|
|
| --- | --- |
|
|
| `UnrealEditor <uproject> /Game/Hollywood/DemoMap -game -qaselftest` | Headless behaviour check: drives forward input for 2 s, then resets and pauses. Logs `GigLine QA: ... PASS/FAIL` lines and a final `RESULT`. Runs only with `-qaselftest`, so normal play is unaffected. |
|
|
| `-qaselftest` phases | Walk, reset, pause/unpause, a 16-row seam transect (0 holes) and a ground-referenced wall probe (0/35), plus a frame-time capture writing `Saved/Profiling/perf-walk-frametimes.csv` and logging `GigLine PERF:`. |
|
|
| `gigline.SetupLogs` cvar | Spawn/input setup logging, **off by default** (`DefaultEngine.ini [ConsoleVariables]`); enable at runtime with `gigline.SetupLogs 1`. |
|
|
|
|
## Reference and concept generation
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `facade_detail_concepts.py` | Generates **frontal building plates** (whole elevation, entrance in its facade, or building with neighbours) from a local reference photograph with an image model (OpenRouter); close-up detail crops are deliberately not requested because they cannot be measured for proportion. `--list` is free and shows which studies have their reference present; `--all`/`--only <name>` generates. Never overwrites (writes `-v2`, `-v3`), writes a `.refgen.json` sidecar per image (model, prompt, source photo, SHA-256), and puts everything under `Art/reference/facade-details/` — gitignored, local-only, never shipped. Costs money per image, so it is never automatic. |
|
|
| `judge_screenshot.py` | (see Visual review) |
|
|
|
|
## Input injection
|
|
|
|
| Tool | Purpose |
|
|
| --- | --- |
|
|
| `input_emulation.py` | Pure-stdlib `ctypes`/`fcntl` driver that creates a virtual keyboard+mouse on `/dev/uinput`. The desktop treats it as real hardware, so it proves whether OS input actually reaches the game. Needs `/dev/uinput` writable (ACL on this host). |
|
|
| `input_test.py` | Injects a scripted sequence into the focused window: `--sequence move:2,look:3,jump:1,reset:1,pause:1,click`. |
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
python3 -m pip install -r requirements-tools.txt
|
|
python3 -m unittest discover -s Tools/tests -t Tools -p 'test_*.py'
|
|
```
|
|
|
|
Stdlib `unittest`, no Blender/Unreal process. See [`tests/README.md`](tests/README.md): test the pure parts (encoding, classification, maths, parsing); if logic is buried in `main()`, extract it into a function so it can be tested.
|