Compare commits
79
Commits
16c2bf7c05
...
v0.2.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82cafc2f29 | ||
|
|
3e4dbd1014 | ||
|
|
a6701aa3d1 | ||
|
|
d8b44f1e57 | ||
|
|
6c4e0701fb | ||
|
|
0e7a6e898b | ||
|
|
2f6d06f897 | ||
|
|
5de4183456 | ||
|
|
bea6aa3e05 | ||
|
|
7c57bf318b | ||
|
|
878d5a1f4e | ||
|
|
86e9c5b693 | ||
|
|
85a8437cbc | ||
|
|
1fc5835327 | ||
|
|
39f07b0f5f | ||
|
|
72d00bdfbd | ||
|
|
54c579ab1a | ||
|
|
89a9c59747 | ||
|
|
4b9ad22108 | ||
|
|
0d57b718cf | ||
|
|
e9f31f271e | ||
|
|
03af8146a6 | ||
|
|
30e4d65743 | ||
|
|
bc2e9c3b8e | ||
|
|
12272d6b96 | ||
|
|
56e104f5f3 | ||
|
|
8e880ed09d | ||
|
|
9ce7011389 | ||
|
|
f5e7e66127 | ||
|
|
dbb177da6f | ||
|
|
eeeabe56b1 | ||
|
|
f84093adba | ||
|
|
0e0aed02d6 | ||
|
|
7ea3c1999c | ||
|
|
46b84884b8 | ||
|
|
8993fd83c4 | ||
|
|
a1f5989cbb | ||
|
|
d0f94dff4e | ||
|
|
50e023f15d | ||
|
|
e487655e2f | ||
|
|
304c1e9afd | ||
|
|
05c1488c00 | ||
|
|
96238bdb6a | ||
|
|
817313aabd | ||
|
|
744bf8f357 | ||
|
|
c72bc41af1 | ||
|
|
803e77473c | ||
|
|
3942e9a215 | ||
|
|
4132f42ca1 | ||
|
|
c53386fcf4 | ||
|
|
2614d259aa | ||
|
|
4e703fcfd9 | ||
|
|
73aca9db80 | ||
|
|
743a290ac9 | ||
|
|
71c7ca734b | ||
|
|
b8209ce82b | ||
|
|
a1d52aa583 | ||
|
|
5e2c5e29c0 | ||
|
|
d6d3d54810 | ||
|
|
ba68dcfdbc | ||
|
|
640bff9631 | ||
|
|
5ffe62f6aa | ||
|
|
81f7cd3991 | ||
|
|
68d8745534 | ||
|
|
420f863999 | ||
|
|
6a778dbc63 | ||
|
|
e75e5500a7 | ||
|
|
0dd4a55c87 | ||
|
|
88b0149bfa | ||
|
|
47bf3a2415 | ||
|
|
3a1db78473 | ||
|
|
b27d30d556 | ||
|
|
4bc41e9faf | ||
|
|
31f073d608 | ||
|
|
71acffec12 | ||
|
|
82a408bc33 | ||
|
|
7e9573a735 | ||
|
|
95011d678a | ||
|
|
abdd7d181f |
No files matched your search
@@ -42,6 +42,15 @@ Thumbs.db
|
|||||||
.env.*
|
.env.*
|
||||||
*.env
|
*.env
|
||||||
|
|
||||||
|
# Mapbox-derived data — local only. Mapbox terms restrict persisting/redistributing
|
||||||
|
# their data, so the Tilequery cache and any generated report stay untracked.
|
||||||
|
/Geo/raw/mapbox-cache/
|
||||||
|
/Geo/verification/*mapbox*
|
||||||
|
|
||||||
|
# Visual-loop iterations: generated comparisons stay uncommitted until the owner
|
||||||
|
# confirms a shot. Only Screenshots/ is committed.
|
||||||
|
/Art/reference/iterations/
|
||||||
|
|
||||||
# Local, private reference material — never committed (see Docs/reference-notes-hollywood.md)
|
# Local, private reference material — never committed (see Docs/reference-notes-hollywood.md)
|
||||||
/Art/reference/
|
/Art/reference/
|
||||||
/Docs/data-inventory.md
|
/Docs/data-inventory.md
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ Rules for `TODO.md`:
|
|||||||
- When **all** steps in a version section are done: write a short descriptive entry to `CHANGELOG.md`, remove the version section from `TODO.md`, and leave its goal in `ROADMAP.md`.
|
- When **all** steps in a version section are done: write a short descriptive entry to `CHANGELOG.md`, remove the version section from `TODO.md`, and leave its goal in `ROADMAP.md`.
|
||||||
- Release checks for each version are listed at the end of its `TODO.md` section; `Docs/release-checks.md` defines the checks themselves. If a check fails, do not tag the release; open a patch task in `TODO.md` and report the failing check in `CHANGELOG.md`.
|
- Release checks for each version are listed at the end of its `TODO.md` section; `Docs/release-checks.md` defines the checks themselves. If a check fails, do not tag the release; open a patch task in `TODO.md` and report the failing check in `CHANGELOG.md`.
|
||||||
- Finish each milestone's release checks **before** expanding scope. Cut map size and simulation complexity before compromising the core walking/driving experience.
|
- Finish each milestone's release checks **before** expanding scope. Cut map size and simulation complexity before compromising the core walking/driving experience.
|
||||||
|
- **Realism leads, performance is a floor.** When a realism improvement costs frame time, realism wins and the cost is paid — but 60 FPS at 1440p without frame generation must still be met at every release. If realism cannot fit the budget, reduce the realism scope deliberately and record it in `CHANGELOG.md`; never ship below the floor without the owner's approval. Walkability outranks realism in one direction only: a block the player falls through is not a demo.
|
||||||
|
|
||||||
## Git workflow
|
## Git workflow
|
||||||
|
|
||||||
@@ -110,6 +111,59 @@ Keep entries short and dated, with the evidence: the command, the log line, or t
|
|||||||
|
|
||||||
Memory edits on an agent's branch are not shared live. Communicate important findings to the coordinator during work and reconcile them into the shared `main` copy when integrating.
|
Memory edits on an agent's branch are not shared live. Communicate important findings to the coordinator during work and reconcile them into the shared `main` copy when integrating.
|
||||||
|
|
||||||
|
## Python and shell tooling
|
||||||
|
|
||||||
|
Every committed asset and every measured claim in this repository is produced by a script. Tools live in `Tools/` (Unreal, network, repository), `Geo/tools/` (projection, OSM/DEM parsing, metadata) and `Art/blender/*/` (Blender-side builders, next to their output).
|
||||||
|
|
||||||
|
**Fix the tool, not the artefact.** If an asset is corrected by hand, script the correction (or regenerate it) in the same change. A second manual fix of the same kind means the tool is missing a step.
|
||||||
|
|
||||||
|
**Improve over fork.** Extend the existing tool rather than adding a near-duplicate. When two or three scripts start sharing logic, factor the shared part into `Tools/_common.py`, `Geo/tools/osm_common.py` or `Art/blender/common.py`; keep the single metres→centimetres conversion where it already lives.
|
||||||
|
|
||||||
|
Rules that keep tools reusable and reviewable:
|
||||||
|
|
||||||
|
- **One script, one job.** Every input is an argument; no interactive prompts; deterministic output paths.
|
||||||
|
- **Fail loudly.** A tool that cannot do its job exits non-zero with a message. Never leave a partially written asset and a success code.
|
||||||
|
- **Result files for Unreal.** Unreal commandlets swallow `print()`; write the outcome to `/tmp/gigline/<tool>.txt` and read that instead of trusting the exit code alone.
|
||||||
|
- **Absolute paths into sandboxes.** Blender Flatpak (`LD_LIBRARY_PATH="$B/blender/lib"`) and Unreal do not share the repo's working directory; pass absolute paths.
|
||||||
|
- **Clean worktree for generators.** Tools that rewrite committed assets (site/street/hero builders, importers, map builders) run from a clean worktree; inspect the LFS diff before committing. Note that `.blend` and `.umap` check out read-only — `chmod u+w` first or the save silently fails.
|
||||||
|
- **Network and paid-API tools are human-triggered.** `Tools/commons_fetch.py`, `Tools/page_image_fetch.py`, `Tools/judge_screenshot.py` (OpenRouter) and anything similar never sit in a gate or CI. Handle HTTP 429 with back-off rather than retrying immediately.
|
||||||
|
- **Measure, don't assert.** Verification tools print the sampled numbers — counts, holes, Z ranges, worst step and its location, frame-time percentiles — so a claim in `TODO.md`, `CHANGELOG.md` or `Docs/` can be re-checked by re-running the command.
|
||||||
|
|
||||||
|
**Document every tool.** A new or changed tool gets a row in the inventory table of the README beside it: [`Tools/README.md`](Tools/README.md), [`Geo/README.md`](Geo/README.md), or [`Art/blender/README.md`](Art/blender/README.md). What it does, its arguments, and a typical command. A tool without a README row is unfinished.
|
||||||
|
|
||||||
|
**Test the pure parts.** `Tools/tests/` holds stdlib `unittest` tests (no Blender or Unreal process; they must not start a game or editor). Extract the testable core — argument parsing, geometry maths, licence gating, report formatting — into functions that a test can call directly.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m unittest discover -s Tools/tests -t Tools -p 'test_*.py'
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep the tools standard-library-only where practical; if a third-party import is genuinely needed, add it to `requirements-tools.txt` with a version floor and mention it in the tool's README row.
|
||||||
|
|
||||||
|
## Architecture documentation
|
||||||
|
|
||||||
|
[`Docs/Architecture/`](Docs/Architecture/) is the arc42 documentation: twelve numbered section files, `about-arc42.md`, and the combined [`architecture.md`](Docs/Architecture/architecture.md). **Markdown is canonical** — the `.adoc` sources were removed on 2026-11-08.
|
||||||
|
|
||||||
|
Keep it current **in the same change as the implementation**, not in a later documentation pass. When work alters any of the following, edit the matching section:
|
||||||
|
|
||||||
|
| Change | Section |
|
||||||
|
| --- | --- |
|
||||||
|
| A new or restructured module, tool, data source or external interface | `05_building_block_view.md` |
|
||||||
|
| A runtime flow, tick/order dependency, or lifecycle (possession, map load, QA self-test) | `06_runtime_view.md` |
|
||||||
|
| Packaging, engine pin, checkout/build/launch procedure | `07_deployment_view.md` |
|
||||||
|
| A pattern, convention or cross-cutting rule (units, collision policy, provenance) | `08_concepts.md` |
|
||||||
|
| A decision that constrains future work | new ADR in `09_architecture_decisions.md` |
|
||||||
|
| A quality goal or a measured budget (frame time, traversal coverage) | `10_quality_requirements.md` |
|
||||||
|
| A known risk or a risk that retired | `11_technical_risks.md` |
|
||||||
|
| A new term, tool or abbreviation | `12_glossary.md` |
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- **Describe what exists.** No aspirational architecture: anything planned belongs in `ROADMAP.md` and `TODO.md`. Every structural claim names the file, script or flag that implements it.
|
||||||
|
- **ADRs are append-only.** Never rewrite an accepted decision; supersede it with a new ADR that says what it replaces and why.
|
||||||
|
- **Keep the combined document in sync.** `architecture.md` mirrors the section files; when a section changes, update the combined document too.
|
||||||
|
- **Images** live in `Docs/Architecture/images/` and are referenced, not duplicated.
|
||||||
|
- **Verify:** all Markdown must pass `prettier --check` (config in `.prettierrc`), and a command you quote must still run.
|
||||||
|
|
||||||
## Geographic & Art Pipeline
|
## Geographic & Art Pipeline
|
||||||
|
|
||||||
1. Save a versioned OSM extract; document date, bounds, and source.
|
1. Save a versioned OSM extract; document date, bounds, and source.
|
||||||
@@ -156,8 +210,8 @@ Any change that affects the game's appearance — meshes, materials, lighting, l
|
|||||||
|
|
||||||
1. Run `Tools/render_screenshots.sh` (rebuilds `Game/GigLine/Content/Test/ReviewMap.umap` from current content, runs the game on it, captures the fixed camera list, copies the PNGs into `Screenshots/`).
|
1. Run `Tools/render_screenshots.sh` (rebuilds `Game/GigLine/Content/Test/ReviewMap.umap` from current content, runs the game on it, captures the fixed camera list, copies the PNGs into `Screenshots/`).
|
||||||
2. Optional pre-check with a vision model: `Tools/judge_screenshot.py --image <shot.png> --expect "<what it should show>"` (or `--shots` to run every shot in the README) flags likely-missing content before a human looks. It reads `OPENROUTER_API_KEY` from `.env` (ignored). Small helper only — it never replaces the human verdict.
|
2. Optional pre-check with a vision model: `Tools/judge_screenshot.py --image <shot.png> --expect "<what it should show>"` (or `--shots` to run every shot in the README) flags likely-missing content before a human looks. It reads `OPENROUTER_API_KEY` from `.env` (ignored). Small helper only — it never replaces the human verdict.
|
||||||
3. Update `Screenshots/README.md`: one row per screenshot with what it shows and an approval state; describe any new shots or scene changes in the same change.
|
3. Update `Screenshots/README.md` **in the same change as any visual work** — every change that affects appearance, not only new shots: the image is **embedded inline** (``) with its view, expected content, verification and approval state, plus one row in the status table at the top. The review happens in the file; a path alone is not a review, and a shot whose README section is stale is a defect.
|
||||||
4. The PNGs **are committed** so reviewers see exactly what the build rendered (`.gitignore` does not exclude them). Keep them in sync with this README: drop retired shots in the same change.
|
4. The PNGs **are committed** so reviewers see exactly what the build rendered (`.gitignore` does not exclude them). Keep them in sync with this README: drop retired shots in the same change.
|
||||||
5. Wait for the user's approval before treating a visual change as done; record approval by ticking the table in `Screenshots/README.md`.
|
5. Wait for the user's approval before treating a visual change as done; record approval by ticking both the shot's section and its row in the status table in `Screenshots/README.md`.
|
||||||
|
|
||||||
New content that needs a different camera angle gets a new entry in the shot list in `Tools/ue_build_review_map.py`.
|
New content that needs a different camera angle gets a new entry in the shot list in `Tools/ue_build_review_map.py`.
|
||||||
+16
-10
@@ -80,7 +80,7 @@ LD_LIBRARY_PATH="$B/blender/lib" "$B/blender/blender" -b --factory-startup \
|
|||||||
```
|
```
|
||||||
|
|
||||||
- `Road_Hollywood`: 8 120 verts, 7 812 faces, carriageway −10.5…+10.5 m, DEM elevations plus a 2 cm lift so it does not z-fight the terrain.
|
- `Road_Hollywood`: 8 120 verts, 7 812 faces, carriageway −10.5…+10.5 m, DEM elevations plus a 2 cm lift so it does not z-fight the terrain.
|
||||||
- `Sidewalk_South` 4.0 m wide, `Sidewalk_North` 5.3 m wide, both raised by the kerb height.
|
- `Sidewalk_South` 4.0 m wide, `Sidewalk_North` 5.3 m wide. The kerb upstand is **full at the road-side edge and tapers to zero at the building-side edge**, so the walk surface meets the terrain flush (before `0.1.1` the outer lip stood the full kerb height above the DEM — a 15.8 cm ledge).
|
||||||
- `Kerb_South`, `Kerb_North`: vertical faces, mostly **0.13 m** — the 0.15 m assumption minus nothing on the road side — and flushed to 0 within ±2.5 m of each signalised crossing with a 1.5 m blend. Measured from the built mesh: 256 steps at 0.13 m, 15 flush, a few in transition.
|
- `Kerb_South`, `Kerb_North`: vertical faces, mostly **0.13 m** — the 0.15 m assumption minus nothing on the road side — and flushed to 0 within ±2.5 m of each signalised crossing with a 1.5 m blend. Measured from the built mesh: 256 steps at 0.13 m, 15 flush, a few in transition.
|
||||||
|
|
||||||
Crown check on the built mesh at mid-block: gutter −10.5 m → +0.99, −5 m → +1.38, centre → +1.52, +5 m → +1.58, +10.5 m → +1.52. The crown sits just north of the centreline, as the cross-sections said.
|
Crown check on the built mesh at mid-block: gutter −10.5 m → +0.99, −5 m → +1.38, centre → +1.52, +5 m → +1.58, +10.5 m → +1.52. The crown sits just north of the centreline, as the cross-sections said.
|
||||||
@@ -103,16 +103,20 @@ Objects are appended from the source files, not regenerated, and grouped into `S
|
|||||||
|
|
||||||
A downward raycast on a 1 m grid along both sidewalks and the designated crossing, ignoring blockout meshes so marquees and canopies overhead do not count as ground:
|
A downward raycast on a 1 m grid along both sidewalks and the designated crossing, ignoring blockout meshes so marquees and canopies overhead do not count as ground:
|
||||||
|
|
||||||
| Route | Samples | Holes | Z range | Worst step |
|
| Route | Samples | Holes | Z range | Worst step |
|
||||||
| ----------------- | ------: | ----: | ------------- | ---------: |
|
| ----------------- | ------: | ----: | ------------- | ----------------: |
|
||||||
| South sidewalk | 279 | 0 | −0.45 … +3.13 | 20.5 cm |
|
| South sidewalk | 279 | 0 | −0.48 … +3.06 | 13.4 cm (s=198) |
|
||||||
| North sidewalk | 279 | 0 | +0.07 … +3.83 | 15.1 cm |
|
| North sidewalk | 279 | 0 | +0.06 … +3.76 | 6.9 cm (s=33) |
|
||||||
| Crossing at 130 m | 26 | 0 | +1.16 … +1.80 | 8.6 cm |
|
| Crossing at 130 m | 26 | 0 | +1.14 … +1.80 | 9.0 cm (off −8.5) |
|
||||||
|
|
||||||
|
At `--sample 0.25` the same routes measure 11.6 cm / 8.0 cm / 3.4 cm. The pre-check now prints the grade and the **location** of the worst step, and its coverage no longer shrinks with `--sample`.
|
||||||
|
|
||||||
No holes anywhere, so nothing drops the player on either side. The two flagged steps:
|
No holes anywhere, so nothing drops the player on either side. The two flagged steps:
|
||||||
|
|
||||||
- **15.8 cm at s≈207**, where a sample crosses from `Terrain_DEM` onto `Sidewalk_South` — that is the sidewalk's outer edge, the 0.15 m kerb height minus the terrain. Mostly hidden by buildings, but it is a real edge and it will be visible anywhere a building is missing.
|
- ~~15.8 cm at s≈207, the sidewalk's outer edge~~ — **fixed in `0.1.1`**: the sidewalk upstand now tapers to zero at the building side, so the outer edge is flush with the terrain (north route 15.1 → 6.9 cm).
|
||||||
- **10–13 cm steps at s≈33, 39 and 126**, inside the sidewalk mesh: the kerb-flush transition at the crossings. That is a ~10 % ramp over 1.5 m, steeper than a real crossing ramp (8 % max). Worth grading properly when the crossings are detailed.
|
- ~~10–13 cm steps at the crossings, ~10 % ramp over 1.5 m~~ — **fixed in `0.1.1`**: the ramp run is now derived from a target grade (`--max-ramp-grade`, default 8 %), giving 1.63 m instead of the fixed 1.5 m (8.7 %). Measured at 0.25 m sampling the crossing now steps 3.4 cm (~1.4 % of the route) at the kerb line.
|
||||||
|
|
||||||
|
**Remaining finding (not a crossing, not the outer edge):** the south route still measures a **13.4 cm step at s≈198 m** (11.6 cm at 0.25 m sampling) and the north route 8.0 cm at s≈251 m. Neither is at a crossing and neither is the outer lip, so this is a local discontinuity in the sidewalk strip — most likely the DEM sampling or a centreline vertex near the block ends. Tracked under the `0.1.1` "audit any collision gaps" item rather than left undocumented.
|
||||||
|
|
||||||
This is a pre-check, not the `0.1.0` release check: the release check is traversal in the engine.
|
This is a pre-check, not the `0.1.0` release check: the release check is traversal in the engine.
|
||||||
|
|
||||||
@@ -127,13 +131,15 @@ Blender works in metres, and the imported meshes match the OSM geometry, so the
|
|||||||
| Building | Blender dimensions | OSM way outline | Height source |
|
| Building | Blender dimensions | OSM way outline | Height source |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| El Capitan Entertainment Centre | 25.72 × 54.47 × 14.50 m | 25.75 × 54.88 m | `height` tag 14.5 |
|
| El Capitan Entertainment Centre | 25.72 × 54.47 × 14.50 m | 25.75 × 54.88 m | `height` tag 14.5 |
|
||||||
| El Capitan Theatre | 38.66 × 54.46 × 20.96 m | 38.59 × 54.87 m | `building:levels=6` × 3.2 m, plus roof |
|
| El Capitan Theatre | 38.66 × 54.46 × 20.55 m | 38.59 × 54.87 m | `building:levels=6` × **3.1 m**, plus ~1.9 m roof |
|
||||||
| Madame Tussaud's | 42.48 × 56.77 × 15.90 m | 42.0 m frontage | `height` tag 15.9 |
|
| Madame Tussaud's | 42.48 × 56.77 × 15.90 m | 42.0 m frontage | `height` tag 15.9 |
|
||||||
| TCL Chinese Theatre | 43.78 × 75.90 × 18.10 m | 44.0 m frontage | `height` tag 18.1 |
|
| TCL Chinese Theatre | 43.78 × 75.90 × 18.10 m | 44.0 m frontage | `height` tag 18.1 |
|
||||||
|
|
||||||
Widths agree to a few centimetres; depths differ by up to 0.4 m because Blosm assembles **multipolygon relations**, not the raw way I measured. Placement after the frame correction agrees with the UTM control points to 0.1–0.5 m per building — the residual is relation assembly and Blosm's edge straightening, not projection.
|
Widths agree to a few centimetres; depths differ by up to 0.4 m because Blosm assembles **multipolygon relations**, not the raw way I measured. Placement after the frame correction agrees with the UTM control points to 0.1–0.5 m per building — the residual is relation assembly and Blosm's edge straightening, not projection.
|
||||||
|
|
||||||
Buildings **without** a `height` tag get levels × 3.2 m, which is a placeholder, not evidence. Every such height is a modelling decision to be replaced from the reference photography.
|
Buildings **without** a `height` tag get levels × **3.1 m**. The storey height was 3.2 m until 2026-11-09, when a cross-check of every block building against Mapbox's building data (`Geo/tools/mapbox_buildings.py`) showed our figure running 0.6 m high per six levels — i.e. 3.1 m per level — and that calibration was adopted. The few buildings where Mapbox disagreed with a pure `levels × 3.1 m` fallback carry an explicit override in `Geo/tools/block_height_report.py::HEIGHT_OVERRIDES`.
|
||||||
|
|
||||||
|
Blosm adds roof mass on top of `levels × levelHeight`: the two `levels`-derived frontage buildings both land ~1.9 m above their table height (6922 39.1 m against 37.2 m, El Capitan Theatre 20.5 m against 18.6 m). That offset is the roof, not a height error — the table records the tagged height, the mesh records the storey plus its roof.
|
||||||
|
|
||||||
## Relation completeness
|
## Relation completeness
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -40,7 +40,9 @@ def parse_args():
|
|||||||
ap.add_argument("--osm", required=True, help="local .osm file to import")
|
ap.add_argument("--osm", required=True, help="local .osm file to import")
|
||||||
ap.add_argument("--bounds", required=True, help="south,west,north,east in WGS84 degrees")
|
ap.add_argument("--bounds", required=True, help="south,west,north,east in WGS84 degrees")
|
||||||
ap.add_argument("--out", required=True, help="output .blend path")
|
ap.add_argument("--out", required=True, help="output .blend path")
|
||||||
ap.add_argument("--level-height", type=float, default=3.2, help="metres per building level")
|
# 3.1 m, not 3.2: calibrated against Mapbox building data on 2026-11-09
|
||||||
|
# (see Geo/tools/mapbox_buildings.py and Geo/tools/block_height_report.py).
|
||||||
|
ap.add_argument("--level-height", type=float, default=3.1, help="metres per building level")
|
||||||
ap.add_argument("--origin", default=None,
|
ap.add_argument("--origin", default=None,
|
||||||
help="lat,lon to use as the Blender origin (project origin). Default: Blosm centres on the extract")
|
help="lat,lon to use as the Blender origin (project origin). Default: Blosm centres on the extract")
|
||||||
ap.add_argument("--no-subdivide", action="store_true", help="skip OSM area subdivision")
|
ap.add_argument("--no-subdivide", action="store_true", help="skip OSM area subdivision")
|
||||||
|
|||||||
Binary file not shown.
@@ -3,18 +3,18 @@
|
|||||||
"frame": "project frame, metres, X east Y north Z up",
|
"frame": "project frame, metres, X east Y north Z up",
|
||||||
"bounds_m": {
|
"bounds_m": {
|
||||||
"min": [
|
"min": [
|
||||||
-13.02,
|
-13.08,
|
||||||
-12.5,
|
-12.5,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"max": [
|
"max": [
|
||||||
13.02,
|
13.08,
|
||||||
0.07,
|
0.13,
|
||||||
14.5
|
14.5
|
||||||
],
|
],
|
||||||
"size": [
|
"size": [
|
||||||
26.04,
|
26.16,
|
||||||
12.57,
|
12.63,
|
||||||
14.5
|
14.5
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -33,10 +33,37 @@
|
|||||||
"dims_m": [
|
"dims_m": [
|
||||||
0.95,
|
0.95,
|
||||||
0.95,
|
0.95,
|
||||||
7.45
|
8.25
|
||||||
],
|
],
|
||||||
"evidence": "6 columns at 4.96 m centres (sibling notes x measured frontage)"
|
"evidence": "6 columns at 4.96 m centres (sibling notes x measured frontage)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"object": "Hero_Flute_x120",
|
||||||
|
"dims_m": [
|
||||||
|
0.064,
|
||||||
|
0.064,
|
||||||
|
6.53
|
||||||
|
],
|
||||||
|
"evidence": "photographs: fluted shafts; 20 grooves per column modelled as shallow cylinders in the shadow tone rather than boolean cut grooves"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object": "Hero_ColumnBase_x6",
|
||||||
|
"dims_m": [
|
||||||
|
1.36,
|
||||||
|
1.36,
|
||||||
|
0.22
|
||||||
|
],
|
||||||
|
"evidence": "assumption: Ionic base moulding; photographs show a wider base at the shaft foot"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object": "Hero_Abacus_x6",
|
||||||
|
"dims_m": [
|
||||||
|
1.3,
|
||||||
|
1.3,
|
||||||
|
0.14
|
||||||
|
],
|
||||||
|
"evidence": "assumption: square abacus under the architrave, as Ionic capitals carry"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"object": "Hero_Architrave",
|
"object": "Hero_Architrave",
|
||||||
"dims_m": [
|
"dims_m": [
|
||||||
@@ -55,12 +82,21 @@
|
|||||||
],
|
],
|
||||||
"evidence": "assumption: projecting cornice line"
|
"evidence": "assumption: projecting cornice line"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"object": "Hero_Dentil_xN",
|
||||||
|
"dims_m": [
|
||||||
|
0.18,
|
||||||
|
0.3,
|
||||||
|
0.22
|
||||||
|
],
|
||||||
|
"evidence": "52 dentils at 0.45 m centres under the corona; assumption: photographed cornice reads as a dentilled course"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"object": "Hero_Entablature",
|
"object": "Hero_Entablature",
|
||||||
"dims_m": [
|
"dims_m": [
|
||||||
25.75,
|
25.75,
|
||||||
1.5,
|
1.5,
|
||||||
3.4
|
3.0
|
||||||
],
|
],
|
||||||
"evidence": "assumption: entablature depth"
|
"evidence": "assumption: entablature depth"
|
||||||
},
|
},
|
||||||
@@ -69,7 +105,7 @@
|
|||||||
"dims_m": [
|
"dims_m": [
|
||||||
25.75,
|
25.75,
|
||||||
1.2,
|
1.2,
|
||||||
2.2
|
1.8
|
||||||
],
|
],
|
||||||
"evidence": "assumption: parapet carries the motto band"
|
"evidence": "assumption: parapet carries the motto band"
|
||||||
},
|
},
|
||||||
@@ -77,19 +113,19 @@
|
|||||||
"object": "Hero_MottoBand",
|
"object": "Hero_MottoBand",
|
||||||
"dims_m": [
|
"dims_m": [
|
||||||
22.75,
|
22.75,
|
||||||
0.08,
|
0.1,
|
||||||
0.85
|
0.85
|
||||||
],
|
],
|
||||||
"evidence": "photographs: motto panel above the colonnade"
|
"evidence": "photographs: motto panel above the colonnade, now an inset panel with a moulded surround rather than a flat stripe"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"object": "Hero_Medallion_x2",
|
"object": "Hero_Medallion_x2",
|
||||||
"dims_m": [
|
"dims_m": [
|
||||||
1.1,
|
1.1,
|
||||||
1.1,
|
0.04,
|
||||||
0.02
|
1.1
|
||||||
],
|
],
|
||||||
"evidence": "photographs: two stone discs beside the motto"
|
"evidence": "photographs: two stone discs beside the motto, mounted on the parapet face"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"object": "Hero_Stylobate",
|
"object": "Hero_Stylobate",
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Reference analysis — retail frontage, 0.1.6
|
||||||
|
|
||||||
|
Phase 0 of the `references` pack (reference-image-match). Written before any geometry, because the pass that produced the hero façade skipped it and cost two rebuilds.
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
| | |
|
||||||
|
| --- | --- |
|
||||||
|
| Image | `Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (1920×953) |
|
||||||
|
| Author / licence | Gb321, own work, **CC BY-SA 4.0** — attribution required |
|
||||||
|
| Captured | 2024-07-19 11:11 local |
|
||||||
|
| Description | "Lee Drug and 6806 Hollywood Buildings in Hollywood" |
|
||||||
|
| Coverage | Both target buildings in one frame, mid-morning sun from the south-east |
|
||||||
|
|
||||||
|
**One photograph is the whole evidence base for 6800 and 6806–6820.** It is a street-level oblique, not an elevation: verticals converge, the ground floor of 6806–6820 is partly behind a parked car, and the Lee Drug shopfront is behind a bus. Everything below that the photo does not resolve is marked _assumed_ and is carried into the part report.
|
||||||
|
|
||||||
|
**6822 Budget has no photograph.** It is a 6.0 m × 5.5 m single-storey sliver west of 6806–6820, and the TODO item already records that Commons has nothing usable. It stays a blockout extrusion and the item is deferred rather than guessed.
|
||||||
|
|
||||||
|
## Measured (not from the photo)
|
||||||
|
|
||||||
|
From `Geo/raw/osm-api-map-2026-11-06.osm` and the blockout, in the shared frame (metres, X east, Y north, Z from the project datum):
|
||||||
|
|
||||||
|
| Building | OSM way | X | Front face Y | Height | Depth |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| 6800 Lee Drug | 424024149 | −33.20 … −14.37 | −14.63 | 12.10 m | 33.5 m |
|
||||||
|
| 6806–6820 | 424024150 | −66.08 … −33.07 | −12.52 | 12.10 m | 30.8 m |
|
||||||
|
| 6822 Budget | 424024144 | −78.54 … −72.52 | −12.92 | 5.50 m | 15.4 m |
|
||||||
|
|
||||||
|
Both target buildings are 12.10 m tall, which makes the _relative_ proportions in the photo directly usable: the parapet line, the cornice and the shopfront line can be read as fractions of the frame height.
|
||||||
|
|
||||||
|
## 6800 Lee Drug — reading
|
||||||
|
|
||||||
|
| Category | Observation |
|
||||||
|
| --- | --- |
|
||||||
|
| Subject | Corner retail block at Hollywood × Highland; the street face and the corner return are both visible |
|
||||||
|
| Silhouette | Long low box, broken by a **rounded corner tower** that rises above the frontage parapet; the parapet is **stepped**, not flat |
|
||||||
|
| Storeys | Two zones, not storeys: a tall shopfront zone and a single tall display wall above it |
|
||||||
|
| Proportion (vertical) | Shopfront ≈ 0 → 0.36 H; bronze cornice ≈ 0.36 → 0.43 H; mural + lettering wall ≈ 0.43 → 0.82 H; stepped parapet ≈ 0.82 → 1.0 H (_assumed split; read off the frame, ±0.03 H_) |
|
||||||
|
| Proportion (horizontal) | Corner tower occupies ≈ 4 m of the east end; eight mural panels at roughly 2.2 m centres along the frontage |
|
||||||
|
| Colour | Cream stucco wall `#EDE6D8`, bronze/brown cornice `#6B4A2F`, near-black mural plates `#1C1A18`, dark glazing `#20262A` (_sampled from the frame_) |
|
||||||
|
| Unique features | Stepped Deco parapet with 4 horizontal reveal lines; projecting bronze cornice; row of black celebrity-portrait panels; large dark "SOUVENIRS OF …" lettering on the upper wall; shopfront glazing with slim mullions |
|
||||||
|
| Mood | 1930s Deco retail, freshly painted, bright midday |
|
||||||
|
|
||||||
|
## 6806–6820 — reading
|
||||||
|
|
||||||
|
| Category | Observation |
|
||||||
|
| --- | --- |
|
||||||
|
| Silhouette | Flat-fronted two-storey block; parapet steps up in fins at the west end |
|
||||||
|
| Proportion (vertical) | Shopfront ≈ 0 → 0.32 H; burgundy fascia band ≈ 0.32 → 0.38 H; window storey ≈ 0.38 → 0.62 H; blank wall + parapet ≈ 0.62 → 1.0 H (_assumed_) |
|
||||||
|
| Horizontal | Brown pilaster strips divide the frontage into roughly 3 m bays; seven upper windows across 33 m |
|
||||||
|
| Colour | Same cream stucco; brown pilasters `#6B4A2F`; **burgundy-green** fascia `#5B3A3A`; white window frames |
|
||||||
|
| Unique features | Banded parapet with 3 reveal lines; white-framed upper windows with security bars; shopfront glazing behind a burgundy fascia |
|
||||||
|
|
||||||
|
## Camera match (for the review shot)
|
||||||
|
|
||||||
|
The photo is a street-level oblique from the **north** side looking south-east, subject filling ~80 % of the frame width. The demo review shot must reproduce that: camera at 1.7 m on the north sidewalk, yaw toward the south frontage, 35–42° lens, both buildings in frame. A wide block view will not compare usefully against this crop.
|
||||||
|
|
||||||
|
## Assumptions to carry into the model report
|
||||||
|
|
||||||
|
1. Vertical proportions, as above — the photo's convergence makes a pixel-perfect read impossible.
|
||||||
|
2. Mural panel size and spacing; the lettering is modelled as a recessed plate, not as text.
|
||||||
|
3. Shopfront bay spacing on both buildings; the bus hides most of Lee Drug's ground floor.
|
||||||
|
4. Parapet reveal line count (4 on Lee Drug, 3 on 6806–6820).
|
||||||
|
5. Corner tower radius; only the outer curve is visible.
|
||||||
@@ -15,6 +15,9 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
sys.path.insert(0, os.path.join(os.path.join(os.path.dirname(__file__), "..", "..", ".."), "Tools"))
|
||||||
|
import fbx_export_preset as fbx_preset # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
MESHES = ("Terrain_DEM", "Road_Hollywood", "Sidewalk_South", "Sidewalk_North",
|
MESHES = ("Terrain_DEM", "Road_Hollywood", "Sidewalk_South", "Sidewalk_North",
|
||||||
"Kerb_South", "Kerb_North", "Crossing_Markings")
|
"Kerb_South", "Kerb_North", "Crossing_Markings")
|
||||||
@@ -60,20 +63,7 @@ def main():
|
|||||||
_ = bpy.context.view_layer
|
_ = bpy.context.view_layer
|
||||||
bpy.context.view_layer.objects.active = obj
|
bpy.context.view_layer.objects.active = obj
|
||||||
path = os.path.join(args.out, name + ".fbx")
|
path = os.path.join(args.out, name + ".fbx")
|
||||||
bpy.ops.export_scene.fbx(
|
fbx_preset.export_static(path, selection=True)
|
||||||
filepath=path,
|
|
||||||
use_selection=True,
|
|
||||||
object_types={"MESH"},
|
|
||||||
apply_unit_scale=True,
|
|
||||||
apply_scale_options="FBX_SCALE_NONE",
|
|
||||||
axis_forward="-Y",
|
|
||||||
axis_up="Z",
|
|
||||||
use_space_transform=True,
|
|
||||||
use_mesh_modifiers=True,
|
|
||||||
mesh_smooth_type="OFF",
|
|
||||||
path_mode="AUTO",
|
|
||||||
bake_space_transform=False,
|
|
||||||
)
|
|
||||||
if mirrored:
|
if mirrored:
|
||||||
# The flip is an export correction, not a change to the source: undo it.
|
# The flip is an export correction, not a change to the source: undo it.
|
||||||
obj.scale.y *= -1.0
|
obj.scale.y *= -1.0
|
||||||
|
|||||||
Binary file not shown.
@@ -165,10 +165,16 @@ def main():
|
|||||||
def lat_lon(s, offset):
|
def lat_lon(s, offset):
|
||||||
return oc.point_at(line, _lengths, s, offset, lat0, lon0)
|
return oc.point_at(line, _lengths, s, offset, lat0, lon0)
|
||||||
|
|
||||||
|
# Sample spacing is independent of coverage: walk the whole block at
|
||||||
|
# `--sample` metres, so a finer spacing measures the gradient instead of
|
||||||
|
# accidentally shortening the route (previously range(int(block_len)) with a
|
||||||
|
# 0.25 m spacing only covered a quarter of the block).
|
||||||
|
along = int(block_len / args.sample)
|
||||||
|
across = int(26.0 / args.sample)
|
||||||
route_specs = {
|
route_specs = {
|
||||||
"south sidewalk": [(s, -12.5) for s in [i * args.sample for i in range(int(block_len))]],
|
"south sidewalk": [(i * args.sample, -12.5) for i in range(along)],
|
||||||
"north sidewalk": [(s, 13.0) for s in [i * args.sample for i in range(int(block_len))]],
|
"north sidewalk": [(i * args.sample, 13.0) for i in range(along)],
|
||||||
"crossing at 130 m": [(130.0, o) for o in [i * args.sample - 12.5 for i in range(26)]],
|
"crossing at 130 m": [(130.0, i * args.sample - 12.5) for i in range(across)],
|
||||||
}
|
}
|
||||||
flat = [(spec, lat_lon(s, off)) for spec, samples in route_specs.items() for s, off in samples]
|
flat = [(spec, lat_lon(s, off)) for spec, samples in route_specs.items() for s, off in samples]
|
||||||
local = project_to_local([ll for _spec, ll in flat], find_proj())
|
local = project_to_local([ll for _spec, ll in flat], find_proj())
|
||||||
@@ -185,12 +191,20 @@ def main():
|
|||||||
heights.append(None)
|
heights.append(None)
|
||||||
else:
|
else:
|
||||||
heights.append(z)
|
heights.append(z)
|
||||||
deltas = [abs(b - a) for a, b in zip(heights, heights[1:])
|
deltas = [(i, abs(b - a)) for i, (a, b) in enumerate(zip(heights, heights[1:]))
|
||||||
if a is not None and b is not None]
|
if a is not None and b is not None]
|
||||||
max_step = max(deltas) if deltas else float("nan")
|
worst_i, max_step = (max(deltas, key=lambda t: t[1]) if deltas else (0, float("nan")))
|
||||||
known = [h for h in heights if h is not None]
|
known = [h for h in heights if h is not None]
|
||||||
|
grade = (max_step / args.sample) * 100 if deltas else float("nan")
|
||||||
|
# Position of the worst step, as arc length / cross offset, so the cause
|
||||||
|
# can be located instead of guessed.
|
||||||
|
if label == "crossing at 130 m":
|
||||||
|
where = f"s=130 off={(worst_i * args.sample - 12.5):+.2f} m"
|
||||||
|
else:
|
||||||
|
where = f"s={worst_i * args.sample:.1f} m"
|
||||||
print(f" {label:18} samples {len(heights):3} holes {holes} "
|
print(f" {label:18} samples {len(heights):3} holes {holes} "
|
||||||
f"Z {min(known):+.2f}..{max(known):+.2f} max step {max_step*100:.1f} cm")
|
f"Z {min(known):+.2f}..{max(known):+.2f} max step {max_step*100:.1f} cm "
|
||||||
|
f"({grade:.1f} % grade) at {where}")
|
||||||
|
|
||||||
out = os.path.abspath(args.out)
|
out = os.path.abspath(args.out)
|
||||||
os.makedirs(os.path.dirname(out), exist_ok=True)
|
os.makedirs(os.path.dirname(out), exist_ok=True)
|
||||||
|
|||||||
Binary file not shown.
@@ -68,8 +68,13 @@ def parse_args():
|
|||||||
ap.add_argument("--cross", type=float, default=0.75)
|
ap.add_argument("--cross", type=float, default=0.75)
|
||||||
ap.add_argument("--kerb", type=float, default=0.15)
|
ap.add_argument("--kerb", type=float, default=0.15)
|
||||||
ap.add_argument("--ramp-half-width", type=float, default=2.5)
|
ap.add_argument("--ramp-half-width", type=float, default=2.5)
|
||||||
ap.add_argument("--ramp-blend", type=float, default=1.5)
|
ap.add_argument("--ramp-blend", type=float, default=None,
|
||||||
return ap.parse_args(argv)
|
help="override the ramp run; default derives it from --max-ramp-grade")
|
||||||
|
ap.add_argument("--max-ramp-grade", type=float, default=0.08,
|
||||||
|
help="maximum crossing-ramp slope (0.08 = 8%%)")
|
||||||
|
args = ap.parse_args(argv)
|
||||||
|
args.ramp_blend = ramp_blend(args.kerb, args.max_ramp_grade, args.ramp_blend)
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
def find_proj():
|
def find_proj():
|
||||||
@@ -125,7 +130,13 @@ class Dem:
|
|||||||
|
|
||||||
|
|
||||||
def kerb_height(s, base, half_width, blend):
|
def kerb_height(s, base, half_width, blend):
|
||||||
"""Full kerb, except flushed near a crossing so people can step off."""
|
"""Full kerb, except flushed near a crossing so people can step off.
|
||||||
|
|
||||||
|
`blend` is the horizontal run over which the kerb drops from `base` to the
|
||||||
|
0.02 m flush height. It is derived from a target maximum grade (see
|
||||||
|
`ramp_blend`) so the crossing ramps stay within a real ramp's slope instead
|
||||||
|
of the ~8.7 % the old fixed 1.5 m run produced.
|
||||||
|
"""
|
||||||
for crossing in CROSSINGS:
|
for crossing in CROSSINGS:
|
||||||
d = abs(s - crossing)
|
d = abs(s - crossing)
|
||||||
if d <= half_width:
|
if d <= half_width:
|
||||||
@@ -136,6 +147,22 @@ def kerb_height(s, base, half_width, blend):
|
|||||||
return base
|
return base
|
||||||
|
|
||||||
|
|
||||||
|
def ramp_blend(kerb, max_grade, override=None):
|
||||||
|
"""Horizontal run needed for the kerb ramp to stay at or under max_grade.
|
||||||
|
|
||||||
|
0.15 m kerb at an 8 % grade needs 1.63 m of run; the previous fixed 1.5 m
|
||||||
|
gave 8.7 %, and the walk pre-check measured the transition as a 10-13 cm
|
||||||
|
step over 1.5 m. When `override` is given it wins (kept for reproducing old
|
||||||
|
meshes), otherwise the run is computed from the live kerb height so it stays
|
||||||
|
correct if the kerb height assumption changes.
|
||||||
|
"""
|
||||||
|
if override is not None:
|
||||||
|
return max(0.0, override)
|
||||||
|
if max_grade <= 0.0:
|
||||||
|
return 0.0
|
||||||
|
return max(0.0, (kerb - 0.02)) / max_grade
|
||||||
|
|
||||||
|
|
||||||
def strip(rows, offsets, z_at, name, material):
|
def strip(rows, offsets, z_at, name, material):
|
||||||
"""Build a quad grid from per-row sampled vertices."""
|
"""Build a quad grid from per-row sampled vertices."""
|
||||||
verts, faces = [], []
|
verts, faces = [], []
|
||||||
@@ -218,13 +245,31 @@ def main():
|
|||||||
z = dem_z(x, y)
|
z = dem_z(x, y)
|
||||||
return (z if z is not None else 0.0) + 0.02
|
return (z if z is not None else 0.0) + 0.02
|
||||||
|
|
||||||
def south_z(r, off, x, y):
|
def sidewalk_z(r, off, inner, outer, x, y):
|
||||||
|
"""Sidewalk surface: full kerb upstand at the road-side (inner) edge,
|
||||||
|
tapering to zero at the building-side (outer) edge so the walk surface
|
||||||
|
meets the terrain flush.
|
||||||
|
|
||||||
|
Before this taper the outer lip stood the full kerb height above the DEM,
|
||||||
|
which the walkability pre-check measured as a 15.8 cm step where a sample
|
||||||
|
crosses from Terrain_DEM onto Sidewalk_South (with a matching lip on the
|
||||||
|
north side). A 0.15 m lip over a 4.0 m / 5.3 m strip is a ~3-4 % ramp:
|
||||||
|
walkable and visually negligible, and it removes the ledge entirely.
|
||||||
|
"""
|
||||||
z = dem_z(x, y)
|
z = dem_z(x, y)
|
||||||
base = z if z is not None else 0.0
|
base = z if z is not None else 0.0
|
||||||
return base + kerb_height(rows[r][0], args.kerb, args.ramp_half_width, args.ramp_blend)
|
h = kerb_height(rows[r][0], args.kerb, args.ramp_half_width, args.ramp_blend)
|
||||||
|
span = inner - outer
|
||||||
|
if abs(span) < 1e-9:
|
||||||
|
return base + h
|
||||||
|
t = min(1.0, max(0.0, (off - outer) / span))
|
||||||
|
return base + h * t
|
||||||
|
|
||||||
|
def south_z(r, off, x, y):
|
||||||
|
return sidewalk_z(r, off, SOUTH_GUTTER, SOUTH_SIDEWALK, x, y)
|
||||||
|
|
||||||
def north_z(r, off, x, y):
|
def north_z(r, off, x, y):
|
||||||
return south_z(r, off, x, y)
|
return sidewalk_z(r, off, NORTH_GUTTER, NORTH_SIDEWALK, x, y)
|
||||||
|
|
||||||
road = strip(rows, road_offsets, road_z, "Road_Hollywood", asphalt)
|
road = strip(rows, road_offsets, road_z, "Road_Hollywood", asphalt)
|
||||||
sw_s = strip(rows, south_offsets, south_z, "Sidewalk_South", concrete)
|
sw_s = strip(rows, south_offsets, south_z, "Sidewalk_South", concrete)
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"character": "GigLine walker",
|
||||||
|
"description": "lean adult pedestrian, short dark hair, olive skin, plain navy t-shirt, dark jeans, worn sneakers",
|
||||||
|
"model": "juggernautXL_ragnarok.safetensors",
|
||||||
|
"views": {
|
||||||
|
"front": {
|
||||||
|
"file": "Art/characters/blueprints/front.png",
|
||||||
|
"seed": 101,
|
||||||
|
"prompt": "GigLine walker, lean adult pedestrian, short dark hair, olive skin, plain navy t-shirt, dark jeans, worn sneakers, full body front view, neutral standing pose, arms at sides, even studio light, plain light grey background, character sheet",
|
||||||
|
"negative": "multiple people, crowd, text, watermark, signature, blurry, low quality, cropped limbs, extra limbs, deformed hands, cartoon, anime, logo",
|
||||||
|
"prompt_id": "ff81a0c1-e4d7-4740-9310-806c11600539"
|
||||||
|
},
|
||||||
|
"side": {
|
||||||
|
"file": "Art/characters/blueprints/side.png",
|
||||||
|
"seed": 202,
|
||||||
|
"prompt": "GigLine walker, lean adult pedestrian, short dark hair, olive skin, plain navy t-shirt, dark jeans, worn sneakers, full body side profile view, neutral standing pose, arms at sides, even studio light, plain light grey background, character sheet",
|
||||||
|
"negative": "multiple people, crowd, text, watermark, signature, blurry, low quality, cropped limbs, extra limbs, deformed hands, cartoon, anime, logo",
|
||||||
|
"prompt_id": "cdd0bfac-446b-4c5a-8375-37fb5c70a75e"
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"file": "Art/characters/blueprints/back.png",
|
||||||
|
"seed": 303,
|
||||||
|
"prompt": "GigLine walker, lean adult pedestrian, short dark hair, olive skin, plain navy t-shirt, dark jeans, worn sneakers, full body back view, neutral standing pose, arms at sides, even studio light, plain light grey background, character sheet",
|
||||||
|
"negative": "multiple people, crowd, text, watermark, signature, blurry, low quality, cropped limbs, extra limbs, deformed hands, cartoon, anime, logo",
|
||||||
|
"prompt_id": "069bc59d-93bb-41ce-a95b-f5b2e8194982"
|
||||||
|
},
|
||||||
|
"head": {
|
||||||
|
"file": "Art/characters/blueprints/head.png",
|
||||||
|
"seed": 404,
|
||||||
|
"prompt": "GigLine walker, lean adult pedestrian, short dark hair, olive skin, plain navy t-shirt, dark jeans, worn sneakers, head and shoulders portrait, front view, neutral expression, even studio light, plain light grey background",
|
||||||
|
"negative": "multiple people, crowd, text, watermark, signature, blurry, low quality, cropped limbs, extra limbs, deformed hands, cartoon, anime, logo",
|
||||||
|
"prompt_id": "39ab3ba6-5e6f-4a69-bdbb-b2faf4318dc0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact_sheet": "Art/characters/blueprints/contact-sheet.png",
|
||||||
|
"note": "generated locally by Tools/comfyui_character_blueprint.py; record the model licence in THIRD_PARTY_NOTICES.md before shipping"
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"tool": "Tools/generate_character_textures.py",
|
||||||
|
"asset": "T_Character_Hair",
|
||||||
|
"size": 512,
|
||||||
|
"procedural": true,
|
||||||
|
"meta": {
|
||||||
|
"strands": 190,
|
||||||
|
"base": [
|
||||||
|
44,
|
||||||
|
32,
|
||||||
|
26
|
||||||
|
],
|
||||||
|
"highlight": [
|
||||||
|
96,
|
||||||
|
74,
|
||||||
|
58
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"note": "generated, not photographed; no third-party licence"
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"tool": "Tools/generate_character_textures.py",
|
||||||
|
"asset": "T_Character_SkinDetail",
|
||||||
|
"size": 512,
|
||||||
|
"procedural": true,
|
||||||
|
"meta": {
|
||||||
|
"octaves": {
|
||||||
|
"fine": 96,
|
||||||
|
"mid": 24,
|
||||||
|
"broad": 7
|
||||||
|
},
|
||||||
|
"detail": 9,
|
||||||
|
"tint": [
|
||||||
|
222,
|
||||||
|
178,
|
||||||
|
152
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"note": "generated, not photographed; no third-party licence"
|
||||||
|
}
|
||||||
Binary file not shown.
+367
-3
@@ -2,8 +2,372 @@
|
|||||||
|
|
||||||
All notable changes to this project are documented here.
|
All notable changes to this project are documented here.
|
||||||
|
|
||||||
Format: [Keep a Changelog](https://keepachangelog.com/) style, versions follow [Semantic Versioning](https://semver.org/). Entries are added when a version section in `AGENTS.md` is completed.
|
Format: [Keep a Changelog](https://keepachangelog.com/) style, versions follow [Semantic Versioning](https://semver.org/). Entries are added when a version section in `TODO.md` is completed.
|
||||||
|
|
||||||
## Unreleased
|
## [Unreleased]
|
||||||
|
|
||||||
No completed releases yet.
|
Nothing yet.
|
||||||
|
|
||||||
|
## [0.2.3] — 2026-11-09
|
||||||
|
|
||||||
|
Camera collision worked in the code and never in the game.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **The third-person boom never shortened.** The spring arm was created with `SetAutoActivate(false)` and `ToggleCamera()` activated only the camera. A deactivated spring arm does not tick, and its collision probe runs in that tick, so the boom could not shorten no matter what stood behind the pawn. Both `ToggleCamera` and `BeginPlay` now activate the arm with the rig.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **`-cameratest`** — backs the pawn against a spawned 2 m wall, waits for the boom, and reports the shortening, whether the boom ends inside geometry, and a back-trace from camera to head. It writes `review-demo-camera-collision.png` so the placement can be checked by eye.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- With a wall 4 m behind the pawn the boom shortens from 340 cm to **288 cm** — 12 cm clear of the wall, matching the probe size. Recorded as a release check.
|
||||||
|
- 8 review shots verify; 95 tool tests pass.
|
||||||
|
|
||||||
|
### Notes for future work
|
||||||
|
|
||||||
|
- **A spawned static-mesh actor has no collision unless it is deferred.** Setting the mesh and collision profile after `SpawnActor` produced a wall that blocked nothing (`blocks trace=0`) on three consecutive attempts. `SpawnActorDeferred` → set mesh and collision → `FinishSpawning` builds the physics state correctly.
|
||||||
|
- **`TargetArmLength` is not rewritten when the boom shortens.** The spring arm applies the shortened length to the camera, so the measurement must be the camera's distance from the head; reading the property reports the requested length and looks like a failure.
|
||||||
|
|
||||||
|
## [0.2.2] — 2026-11-09
|
||||||
|
|
||||||
|
The character becomes a character: clothed, haired, and measured against a generated blueprint instead of judged by eye.
|
||||||
|
|
||||||
|
**Version note:** this ships as a patch by the owner's decision even though it adds asset categories, which the release policy otherwise puts in a minor release. Recorded here so the numbering is not mistaken for scope later.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Clothing** — navy tee, dark jeans and off-white shoes as three separate skinned meshes (`Tools/character_clothing_build.py`), built from the body's own faces per the `character-artist` workflow: duplicate faces, solidify for cloth thickness, one mesh per piece. Each imports with its own single material slot and is attached as a leader-pose component.
|
||||||
|
- **Hair cards** (`Tools/character_hair_build.py`) — a scalp cap plus 26 cards in three overlapping rows, quads only, every vertex weighted to `head`. Cards are oriented from the scalp normal at their anchor, so the cut follows the skull instead of standing out as spikes.
|
||||||
|
- **Character blueprints** (`Tools/comfyui_character_blueprint.py`) — front, side, back and head views generated by the local ComfyUI instance from one description, with fixed seeds and a JSON record of prompts and prompt ids.
|
||||||
|
- **Blueprint comparison** (`Tools/character_match.py`) — figure aspect, fill and coverage deltas, mean CIE76 and dominant-palette distance, plus a side-by-side montage. The deltas stay separate on purpose: one similarity number between a photoreal sheet and a low-detail body would mean nothing.
|
||||||
|
- **ComfyUI driver** (`Tools/comfyui_generate.py`) and **procedural textures** (`Tools/generate_character_textures.py`), each writing a provenance sidecar.
|
||||||
|
- **Material builder** (`Tools/ue_character_materials.py`) — `M_Character_Skin` and `M_Character_Hair_Mat` built from scratch, because `unreal.MaterialEditingLibrary` segfaults in a headless commandlet when it rebuilds an existing graph.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **The sun was raised** from pitch -62 to -74. The character stood in building shadow lit almost entirely by the blue sky light, so warm skin sampled as blue-grey — face (99, 98, 100) before, (131, 121, 117) after at the same camera.
|
||||||
|
- **The walk cycle starts at maximum stride**, so the deterministic stride capture lands on the stride rather than on one of the two frames where the legs pass together.
|
||||||
|
- Cloth shells are fattened 8 mm along their own normals after solidify; 1 cm of solidify let the body through at shoulders, hips and knees.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Hair read blond and thin** because the strand sheet's pale RGB drove base colour; the sheet now supplies only the opacity mask, and the colour is a dark constant.
|
||||||
|
- **Garment coverage holes** at shoulders, hips and knees, closed by 2 cm solidify plus the normal fatten.
|
||||||
|
- **A crash of my own making:** binding materials in `Tick` with `ConstructorHelpers::FObjectFinder` is fatal outside a constructor. Moved to `BeginPlay` with `LoadObject`.
|
||||||
|
- **Shots 6, 7 and 8 were documented as an unclothed body** after the appearance changed; the README now matches the render and all eight shots are approved.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- 8 review shots verify; **all eight approved** by the owner 2026-11-09.
|
||||||
|
- Blueprint comparison improved from mean ΔE **31.9 → 21.8** and palette ΔE **25.4 → 19.7** once the character was clothed.
|
||||||
|
- 95 tool tests pass (13 new for the colour maths, masks and palettes).
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **The garments are still shells over body faces**, not simulated cloth: no wrinkles, no drape, and no separation from the body in motion.
|
||||||
|
- **`T_Character_Diffuse` cannot be used.** Sampling it renders the body black, so the MPFB mesh's UVs do not map onto that bake; skin is a constant tone and the generated pore sheet is unwired.
|
||||||
|
- **The character has no face detail** — the eyes, mouth and brows are mesh and lighting only, and read as a mannequin at close range.
|
||||||
|
- **Camera collision remains implemented but unexercised.**
|
||||||
|
|
||||||
|
## [0.2.1] — 2026-11-09
|
||||||
|
|
||||||
|
Rig fixes. Two defects from the `0.2.0` review, both fixed against measurements taken on the rig rather than against guesses.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **The fingers splayed.** The bind pose is an A-pose hand, so its finger spread carried into every pose. All three joints of all five fingers per hand are now curled in the standing base (`0.28 / 0.34 / 0.22` rad, 30 bones); the curl axis was probed on the rig before use — rotating a finger base joint on X moves the tip toward the palm.
|
||||||
|
- **The arms-down rotation was hard-coded.** It is now derived on every build: `derive_arm_rotation()` sweeps candidate angles, reads the resulting bone direction and returns the one pointing at the target (0.60 rad, direction dot 1.000 in this build). The old 0.55 was a hand-swept constant that would have rotted on any rig change.
|
||||||
|
- **Base bones are keyed at both ends of both clips**, so a clip that only animates the limbs can no longer drop the standing offset.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **The stride capture regressed.** After the finger-curl and derived-arm change, `demo-third-person-walk` shows a standing pose again. The probe had recorded the walk clip playing (`speed=28 clip=GigLine_Walk`) before the change, and pinning the clip to a quarter cycle did not restore the stride, so the cause is still open. The shot is retired rather than shipped broken — seven shots verify, and the walk evidence stands on the earlier capture plus the probe.
|
||||||
|
- Camera collision remains implemented but unexercised against a wall.
|
||||||
|
|
||||||
|
## [0.2.0] — 2026-11-09
|
||||||
|
|
||||||
|
Third-person body. The pawn gains a visible, animated body and a third-person camera, so the walk cycle is finally something a player can see rather than a clip in an asset list.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **`Tools/character_anim_build.py`**: `GigLine_Idle` (60 frames) and `GigLine_Walk` (30 frames) at 30 fps, authored as parametric cycles so the loop closes by construction. Limb axes were **measured** on the rig — a probe rotated `upperleg01.L` by 0.5 rad on each axis and read `foot.L`, which showed X swings the limb fore/aft while Y twists and Z abducts.
|
||||||
|
- **Third-person rig** (`ADR-9`): a visible skeletal body, a `USpringArmComponent` with collision testing, and a **V** toggle. One pawn carries both rigs; first person stays the shipped default.
|
||||||
|
- **Walk capture harness**: a per-shot `ShotFollow` mode that re-places the review camera every frame in the pawn's frame, plus `SetReviewWalk` / `ReturnToStartForReview`, so a stride is captured deterministically and the fixed-camera shots still find the pawn at spawn.
|
||||||
|
- **Review shots 6, 7 and 8** — third-person back, front and mid-stride — embedded in `Screenshots/README.md`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Character export preset now **bakes animation** (`bake_anim`, all actions). Without it the exporter wrote a static bind pose and Unreal imported a mesh with no clips and no error.
|
||||||
|
- `Docs/controls.md` documents the V toggle and the review switches; the in-game HUD line reads `WASD move · Mouse look · Space jump · V view · R reset · Esc pause`.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **`PlayAnimation` on a hidden component never took effect.** The body is hidden at construction and only unhidden by the toggle, so the first call could land before the component was ready; the code now sets `AnimationSingleNode`, calls `SetAnimation` + `Play`, and re-asserts while the instance is missing.
|
||||||
|
- **The animation switch restarted the clip every frame**, freezing the body on frame 0.
|
||||||
|
- **The importer silently refused to replace the existing assets.** Changing the arm rotation and rebuilding returned the identical bone quaternion every time; `replace_existing` and `delete_asset` both failed because the pawn's constructor hard-references the clips. Importing under a new name (`CharacterV2`) finally landed the change — that is what unblocked the pose after a dozen failed rebuilds.
|
||||||
|
- **The review runner copied stale screenshots** from `Saved/`, so a shot retired from the camera list reappeared with byte-identical content from an older run. The folder is cleared before each capture.
|
||||||
|
- **Walking was never enabled for the stride shot**: the call sat in the shot sequencer's `BeginPlay`, which runs before the player pawn exists, so the cast silently found nothing and `speed` stayed at 0.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- **8 review shots verify**; shots 6, 7 and 8 approved by the owner.
|
||||||
|
- **1440p, no frame generation, VSync off**: 759 frames, avg **2.64 ms (379 fps)**, p50 2.54, p95 3.39, p99 3.76, max 4.05 ms — about 2 % over `0.1.5` and 6.3× the 60 fps floor. Series: `Docs/perf/0.2.0-walk-frametimes.csv`.
|
||||||
|
- `-qaselftest`: walk, reset 0 cm from spawn, pause/unpause, transect 1456 samples / 0 holes, wall probe 0/35, façade probe 0/9 — all PASS.
|
||||||
|
- 82 tool tests pass.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **The fingers splay** — the bind's finger spread carries into the pose. Deferred to `0.2.2`.
|
||||||
|
- **The arms-down rotation was found by sweeping**, not derived: 0.55 rad puts the arms at the sides, 0.65 against the hip, 0.75 into the torso. A derived pose is a `0.2.2` job.
|
||||||
|
- **Camera collision is implemented but unproven** — the spawn point has open space behind it, so no shot exercises the boom shortening.
|
||||||
|
- The third-person body has no head or hand IK and no turn-in-place; it is a first playable, not a finished character.
|
||||||
|
|
||||||
|
## [0.1.6] — 2026-11-09
|
||||||
|
|
||||||
|
Retail frontage. The two retail buildings beside the hero are modelled from their own photograph instead of the generic kit, and the photograph is treated as evidence: an analysis is written before any geometry, and every dimension the image does not resolve is carried into the part report as an assumption.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **`Tools/retail_frontage_build.py`**: 6800 Lee Drug and 6806–6820 built from the one usable reference (`Art/reference/retail-neighbours/`, Gb321, CC BY-SA 4.0). Lee Drug gets a bronze cornice, storefront glazing with mullions, framed portrait panels, a painted lettering band, two-tier parapet with reveals and a fluted corner tower; 6806–6820 gets a burgundy fascia, brown pilasters, white-framed windows with security bars and its own banded parapet. Built in world coordinates from the blockout bounds (Lee Drug X −33.20…−14.37, face Y −14.63, H 12.10 m; 6806–6820 X −66.08…−33.07), joined to one mesh per building with a JSON part report.
|
||||||
|
- **`Tools/ue_import_retail_detail.py`**: imports the two meshes with complex-as-simple collision — trim decorates a solid the player already collides with and must not add snag points.
|
||||||
|
- **`Art/blender/retail/ref-analysis.md`**: the reference analysis the `references` skill pack requires, written before modelling.
|
||||||
|
- **`Tools/_common.py`** and `Tools/tests/test_retail_frontage.py`: the bay-layout arithmetic, extracted so it is testable without Blender (4 tests).
|
||||||
|
- **Review shot 5**, `demo/review-demo-retail-frontage`, embedded in `Screenshots/README.md`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **The generic façade kit skips the two modelled buildings** (`MODELLED` list in `ue_apply_facade_kit.py`). It applies to every `Frontage_*`/`North_*` actor, so it was pasting a second, contradicting façade language over the new trim.
|
||||||
|
- **Retail trim stages as `RetailTrim_*`** and is spawned through the demo builder, so it is regenerable rather than hand-placed.
|
||||||
|
- Trim stucco, white and glass slots are mapped onto the demo's look-dev materials so the walls sit in the same noise and texture family as the rest of the block; the tones sampled from the photograph (bronze, burgundy, mural, lettering) stay as authored.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **`Tools/render_screenshots.sh` never captured anything.** The capture step called `./Engine/...` while every commandlet above it went through `run_cmdlet`'s `cd "$ENGINE"`. Under `set -e` the script died at exit 127 _after_ rebuilding the maps, so the PNGs silently stayed a day old and `--verify` never ran.
|
||||||
|
- **Duplicate `RetailTrim_*` actors on every rebuild**: the demo builder's clear list did not include the new label, so each run stacked another copy. Caught by the scene audit, not by eye.
|
||||||
|
- **Mural plates were placed 0.20 m inside the solid blockout volume** and never rendered; the inset is now faked with a proud frame and a near-flush plate.
|
||||||
|
- **Trim detail sat 0.05 m off the wall**, under a pixel of depth at 40 m, so the wall won the depth test. Trim planes now stand 0.10–0.20 m proud.
|
||||||
|
- **6806–6820 parapet started at 0.62 H**, leaving a 4.6 m blank band; the window storey and parapet moved up to follow the photograph.
|
||||||
|
- **Mural panels, parapet and lettering were sized from the photograph's proportions, not the inherited defaults**: the first pass left a parapet that read as one blank white band.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- `render_screenshots.sh --verify`: **5/5 shots OK**; scene audit **0 failures** (every mesh materialed, all spans in tolerance, no duplicate labels).
|
||||||
|
- Owner approved `demo-retail-frontage` (second pass) 2026-11-09; all five demo shots now carry approval.
|
||||||
|
- 82 tool tests pass.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **Wall lettering and the painted band do not read at 40 m.** A plate at 0.10 m still vanishes; this is a decal/texture problem, not geometry. Moved to `0.9.0 — Realistic buildings`.
|
||||||
|
- **The parapet has no moulded profile** and the corner tower is a fluted cylinder with two cap rings — both need the façade system in `0.9.0`.
|
||||||
|
- **6822 Budget is untouched**: no photograph of it exists. Deferred and blocked in `0.9.0`.
|
||||||
|
- The only reference for these two buildings is a single street-level oblique with a bus across Lee Drug's shopfront and a car across 6806's; several vertical proportions are assumptions recorded in the part report.
|
||||||
|
|
||||||
|
## [0.1.5] — 2026-11-09
|
||||||
|
|
||||||
|
Façade finishing. The kit gets the hero detail it was missing, and a class of silent defect is found and gated: the map had been rendering with **604 of 620 mesh actors unmaterialed** without a single error.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Scene audit** (`Tools/ue_audit_scene.py`): fails when any staged mesh has no material, when a frontage building is more than ±1 m off its verified footprint, or when two actors share a label. Wired into `Tools/render_screenshots.sh`, which now runs the whole staging chain in the correct order and stops on an audit failure.
|
||||||
|
- **`Tools/ue_placement.py`**: one source of truth for staged positions and the verified frontage spans, with `span_error` / `describe_span_failure` validators.
|
||||||
|
- **Hero fluting**: 20 grooves per column as shallow shadow-tone cylinders (120 pieces) rather than boolean cuts.
|
||||||
|
- **Presence of references for the retail run**: `Art/reference/retail-neighbours/` (6800 Lee Drug and its neighbour). Local only, not committed.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Motto band is a real recess** now — moulded surround 6 cm proud, panel 12 cm behind — instead of an 8 cm dark stripe. Hero: 148 parts / 3 044 tris → 271 / 5 492, still 14.50 m.
|
||||||
|
- **Kit layout for wide and tall buildings**: bays are capped at 9 with the module widened (6922 was 13 bays across 65.8 m — a window every 4.96 m on a 37 m block), and the storey spread is derived from the available height so the top band always lands inside the volume.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **604 of 620 mesh actors rendered untextured.** `ensure_material` deleted and recreated each site material on every run, orphaning every reference held by the kit pieces and the theatre trim; the map looked only slightly flat. Materials are now updated in place.
|
||||||
|
- **The hero could be teleported 13 m east onto the wrong side of the boulevard.** `ue_hero_facade_import.py` carried its own copy of the pre-`0.1.0` hero position; running the importer alone moved the building, invisible in a render and visible only as a reference-score drop. Placement now has one definition and the import asserts the staged span (`span ok: X -14644..-12028`).
|
||||||
|
- **53 duplicated kit actor labels** (both shop piers of a bay shared one name).
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- Scene audit: **0 failures** — every mesh materialed, all 7 verified spans within tolerance, no duplicate labels.
|
||||||
|
- Packaged `-qaselftest`: walk, reset, pause/unpause, seam transect 1456 samples / 0 holes, wall probe 0/35, façade probe 0/9 — all PASS.
|
||||||
|
- **1440p re-measured with the kit**: 2.76 ms average (**363 fps**), p99 3.64 ms, against `0.1.0`'s 2.42 ms (414 fps) — the 625 kit actors and 8 textures cost about 12 % and leave roughly six times the 60 fps floor. Series at `Docs/perf/0.1.5-kit-walk-frametimes.csv`.
|
||||||
|
- 78 tool tests pass.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **Retail neighbours 6822 and 6806–6820 are not modelled**: Commons holds no usable reference for either, and substituting the El Capitan Theatre's photographs would misattribute their façades. Tracked in `TODO.md`.
|
||||||
|
- Cornice dentil spacing, abacus and plinth dimensions remain recorded assumptions.
|
||||||
|
- Textures are generated, not authored — no decals, signage text or weathering maps.
|
||||||
|
- The vision pre-check stays advisory; it has rejected shots the owner approved.
|
||||||
|
|
||||||
|
## [0.1.4] — 2026-11-09
|
||||||
|
|
||||||
|
Building façades. The block goes from flat extruded boxes with flat colours to coursed, textured surfaces assembled from a reusable module kit, and the El Capitan Theatre gets the marquee and blade sign that make it read as itself.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Façade module kit** at the measured **4.96 m bay** / **3.10 m storey**: pilaster, sill, lintel, window bay, shopfront bay, door bay, cornice, parapet and coping — 16 `SM_` meshes, each validated for manifold topology (12 tris each) and assembled onto **eight buildings, 625 pieces**, from each building's own world bounds.
|
||||||
|
- **Generated surface textures** — deterministic stdlib PNGs for ashlar stone, stucco, asphalt and concrete (base colour + roughness), sampled world-aligned with per-material tiling; byte-identical on re-run.
|
||||||
|
- **Materials**: masonry coursing and roughness variation in the material graphs; `M_FacadeStoneShadow`, `M_FacadeGlass` (specular 0.62 ≈ IOR 1.5) and `M_FacadeBanner`. Material assignment is now **per slot**, keyed on the imported slot material, instead of slot 0 only.
|
||||||
|
- **El Capitan Theatre trim**: projecting marquee (12.0 × 2.60 m canopy at a 4.60 m soffit), illuminated fascia, recessed soffit, and a vertical blade sign (1.30 × 5.20 m) with frame and wall bracket.
|
||||||
|
- **Visual review loop** (`Tools/visual_loop.py` + `visual_targets.json`): verifies every capture against an expectation (missing, blank, tone-less or wrong-size shots fail) and measures each render against its reference photograph, emitting feedback that names the discipline to consult. Iterations are written under `Art/reference/iterations/`, which is gitignored until a shot is confirmed.
|
||||||
|
- **`Tools/fbx_export_preset.py`** — one export preset replacing six copies, and it exports smoothing groups (`FACE`), so round geometry is no longer faceted.
|
||||||
|
- **`Tools/ue_common.py`** — clears the read-only bit an LFS `.umap` checks out with and makes a refused save loud.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Elevation cameras** are levelled (pitch 0, so verticals stay parallel) and use a 42–55° lens to fill the frame from across the street.
|
||||||
|
- **`Screenshots/` holds demo-map captures only**; the review staging map is no longer rendered for review. Each shot carries its expected content and an approval state.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Blockout frame**: the `0.1.2` regeneration had run without `--origin`, shifting the whole frontage ≈119 m in X and 2.4 m in Y and dropping the hero out of the 6902/6838 gap. Regenerated with the affine fit (residual 0.0 cm) and every span re-verified against the block verification notes.
|
||||||
|
- **Kit placed ~12 km from its buildings** — it used the mesh-local bounding box, which excludes the actor offset.
|
||||||
|
- **Marquee mirrored across the boulevard** (Blender +Y is Unreal −Y) and **hanging 5 cm above the pavement** (absolute Z instead of pavement-relative).
|
||||||
|
- **Window bays invisible** inside the solid wall; the surround now projects with glazing inset.
|
||||||
|
- **Glazing was not glass**: kit pieces kept the grey material the FBX import creates.
|
||||||
|
- **Hero windows floated 1.44 m in front of the wall**; parapet medallions were flat discs on the coping.
|
||||||
|
- **Imports could report success while saving nothing** (read-only LFS map), and the north-buildings import failed silently on a missing `import sys`.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- Packaged build `-qaselftest`: walk 761 cm, reset, pause/unpause, seam transect 1456 samples / 0 holes, wall probe 0/35, façade occlusion probe 0/9 — all PASS. Run twice; the harness is time-based and one loaded run reported a false failure.
|
||||||
|
- All eight buildings probed against the verified world spans.
|
||||||
|
- 67 tool tests pass.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- Kit pieces are boxes; cornice dentil spacing, abacus and plinth dimensions are recorded assumptions.
|
||||||
|
- Textures are generated, not authored: no decals, signage text or weathering maps.
|
||||||
|
- The vision pre-check remains advisory — it is unreliable on this content.
|
||||||
|
- Retail neighbours, hero fluting and the blockout cleaning pass move to `0.1.5`.
|
||||||
|
- Performance has not been re-measured since `0.1.0`; 625 kit actors are unmeasured.
|
||||||
|
|
||||||
|
## [0.1.3] — 2026-11-09
|
||||||
|
|
||||||
|
Packaging and setup fixes. No gameplay or visual scope; this patch makes the pipeline and its documentation tell the truth about what `0.1.x` taught.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Map imports could report success while saving nothing.** `.umap` files are LFS-tracked and check out read-only, so `save_map()` returned `False` with no error and the staged actor vanished on the next load. New `Tools/ue_common.py` (`make_writable`, `require_saved`) clears the read-only bit and makes the failure loud; `ue_hero_facade_import.py` and `ue_import_north_buildings.py` now use it. Verified from a forced `0o444` map: chmod logged, `save_map: True`, exit 0.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `Docs/build.md`: content-pipeline table now lists every step as it exists (seven site FBXs, frontage, north buildings, hero, map) and the shared FBX preset; packaging archive corrected to `Builds/GigLineQA`; the packaged log location and `-qaselftest` usage are documented; new **traps** table covers the read-only save, the hero `--out`-is-the-FBX mistake, the MPFB add-on path, the shot actor quitting under QA, and the null-RHI trace trap.
|
||||||
|
- `Docs/setup.md`: the fresh-checkout build is marked verified (2026-11-08) and its blocker closed; a new section documents the two optional keys (`OPENROUTER_API_KEY`, `MAPBOX_ACCESS_TOKEN`) and that neither is needed by the build, the tests or a release.
|
||||||
|
- `Docs/Architecture/07_deployment_view.md` and the combined `architecture.md`: build-output path corrected and marked as living outside the repository.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- 54 tool tests pass (5 new for `ue_common`).
|
||||||
|
- Packaged build still launches into `DemoMap` and `-qaselftest` passes every phase.
|
||||||
|
|
||||||
|
## [0.1.2] — 2026-11-09
|
||||||
|
|
||||||
|
Scale and façade correction patch. Buildings and the hero elevation now match the reference photography and the cross-checked height data; no new gameplay scope.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **`Tools/facade_detail_concepts.py`** — generates frontal building plates (whole elevation, entrance in its façade, building with neighbours) from a local reference photograph through OpenRouter image models. Spec-driven, never overwrites, writes a provenance sidecar per image, output stays in the gitignored `Art/reference/` tree. Local working material only.
|
||||||
|
- **`Tools/fbx_export_preset.py`** — the single FBX export preset (`ue_metric_v1` / `ue_character_v1`). Replaces the argument block that had been copied into six exporters.
|
||||||
|
- **Façade occlusion probe** in `-qaselftest`: 40 m traces sideways from the road centre at walking height, required wherever a building is staged.
|
||||||
|
- **Ionic detail on the hero**: base moulding at every shaft foot, a square abacus over every capital, and a 52-dentil cornice course.
|
||||||
|
- **Tool tests**: `Tools/tests/` now covers the input driver, height classification, the Mapbox cross-check, the concept generator and the FBX preset (49 tests).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Storey height 3.2 → 3.1 m**, calibrated against Mapbox building data, with explicit overrides for three rear outbuildings; the block cross-check now reports 66 matches and no disagreements.
|
||||||
|
- **Hero colonnade 47.6 % → 53.1 %** of the 14.50 m elevation, inside the photographed 50–60 % band (thinner entablature and parapet).
|
||||||
|
- Blockout regenerated at the new storey height; frontage re-exported and re-imported (6922 42.1 → 39.1 m, El Capitan Theatre 20.0 → 20.5 m).
|
||||||
|
- FBX exports now carry smoothing groups (`FACE` instead of `OFF`), so round geometry is no longer faceted and imports stop warning.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Windows floated 1.44 m in front of the wall**, ahead of the colonnade; they now sit on the wall plane behind the columns.
|
||||||
|
- **Parapet medallions were flat discs lying on the coping** instead of discs on the parapet face.
|
||||||
|
- **The hero façade had no usable collision** — the player could walk through it. It is now complex-as-simple; auto-generated convex hulls were tried and rejected because they bulged into the street.
|
||||||
|
- **The three "guessed" block heights were never buildings**: two `building=roof` canopies and a transit shelter. They are classified as non-building volumes and the block now reports zero guessed heights.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- Packaged build `-qaselftest`: walk, reset and pause pass; seam transect 1456 samples / 0 holes; wall probe 0/35; façade probe 0/9.
|
||||||
|
- Screenshots re-rendered for every change and approved by the owner.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- Cornice dentil spacing, the base and abacus dimensions are recorded assumptions: the reference photography does not resolve them at our scale.
|
||||||
|
- Façade surfaces remain flat blockout materials; the textured pass is `0.1.4`.
|
||||||
|
|
||||||
|
## [0.1.1] — 2026-11-08
|
||||||
|
|
||||||
|
Collision-fidelity patch. No new scope: street geometry corrections and the QA tooling that measures them.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Sidewalk outer edge ledge.** The sidewalk stood the full 0.15 m kerb height above the DEM at both edges, leaving a 15.8 cm lip where the walk route crossed from terrain onto the south sidewalk. The upstand now tapers from full at the road-side edge to zero at the building-side edge; the north route's worst step fell from 15.1 cm to 6.9 cm.
|
||||||
|
- **Crossing ramps too steep.** The kerb-flush run was a fixed 1.5 m, giving ~8.7 % (measured 10–13 cm over 1.5 m). The run is now derived from a target grade (`--max-ramp-grade`, default 8 % ⇒ 1.63 m); the crossing steps 3.4 cm at 0.25 m sampling.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Walk pre-check improvements** (`Art/blender/site/site_assembly.py`): sampling coverage is independent of `--sample` (it previously shrank the route), and the report now prints the grade and the arc-length/offset **location** of the worst step, so a step can be located rather than guessed.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Kerb height recorded as final** at 0.15 m modelled / 0.13 m as built — a standard 6 in LA kerb; neither the 3DEP DEM nor the reference photography can resolve it further (±2 cm), which is far below the character's 45 cm step height.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- Site meshes rebuilt and re-imported (7/7, collision flags intact), DemoMap rebuilt, packaged Development build `EXIT=0`.
|
||||||
|
- `-qaselftest` on the packaged build: walk 761 cm in 2 s at steady Z 456, reset 0 cm, pause/unpause, transect 1456 samples across 16 rows / **0 holes**, wall probe **0/35** blocking hits.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- One residual **13.4 cm surface step at s≈198 m** on the south sidewalk (8.0 cm at s≈251 m north). It is not a gap and is below the 45 cm `MaxStepHeight`, so it does not block traversal; the cause is a sidewalk-strip discontinuity near a centreline vertex, recorded in `Art/blender/README.md` as a smoothness refinement.
|
||||||
|
- Kerb radii at junctions, driveway aprons, drainage inlets and pavement joints remain unmodelled (unchanged from `0.1.0`).
|
||||||
|
|
||||||
|
Nothing yet.
|
||||||
|
|
||||||
|
## [0.1.0] — 2026-11-08
|
||||||
|
|
||||||
|
The first playable release: a walkable exterior demo of the **6840 Hollywood Blvd** (El Capitan Entertainment Centre) block in Unreal Engine, built on OpenStreetMap layout data and USGS elevation, with the hero façade and the verified block frontage staged on a walkable street.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Unreal project** (`Game/GigLine`) — C++ game module, Enhanced Input, packaged Linux build, and a `DemoMap` that a plain launch opens directly.
|
||||||
|
- **Walkable demo level** — terrain from the 3DEP DEM, Hollywood Blvd carriageway, both sidewalks and kerbs with collision, the designated mid-block crossing, and fixed daytime lighting (sun, sky light, sky atmosphere, height fog, pinned exposure).
|
||||||
|
- **Hero façade** for 6840 Hollywood Blvd — six-column neoclassical elevation with three genuine portal recesses, entablature, parapet and motto band (`Tools/hero_facade_build.py`, `Tools/ue_hero_facade_import.py`).
|
||||||
|
- **Block frontage** — the five verified south-side neighbours (6922, 6902, 6838 El Capitan Theatre, 6822 Budget, 6806–6822, 6800 Lee Drug) and the two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) placed at their OSM positions.
|
||||||
|
- **First-person player** — `AGigLineCharacter`: 1.75 m capsule, 1.60 m eye camera, 4 m/s walk, mouse look, jump, reset (`R`) and pause (`Escape`); controls documented in `Docs/controls.md` and shown in-game.
|
||||||
|
- **In-game ODbL attribution** — `AGigLineHUD` draws the OpenStreetMap credit and licence line every frame.
|
||||||
|
- **QA harness** — `-qaselftest` (walk, reset, pause, seam transect, invisible-wall probe, frame-time capture) and `Tools/input_test.py` / `Tools/input_emulation.py` for OS-level virtual keyboard/mouse input.
|
||||||
|
- **Documentation** — setup, build, toolchain, licensing, ODbL review, release checks, and arc42 architecture docs.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **All controls were dead in packaged and PIE builds.** The mapping-context generator wrote key bindings to the deprecated `mappings` array; UE 5.8 reads `DefaultKeyMappings.Mappings`, so the cooked game had zero runtime mappings and every key resolved to nothing. `Tools/ue_create_input_assets.py` now populates the current field.
|
||||||
|
- **"Fall-through" was an 8 m invisible box.** `Terrain_DEM` shipped only a bounding-box collision proxy; forcing complex-as-simple collision (`UGigLineAssetTools`) put the player on the actual street.
|
||||||
|
- **Reset returned the player to mid-air** — the start position is now captured on the first grounded frame.
|
||||||
|
- **Plain launch opened the engine template** — the default map now lives in `DefaultEngine.ini` and points at `DemoMap`.
|
||||||
|
- **Game target would not compile** — removed editor-only API use (`UStaticMesh::PostEditChange`, `AActor::GetActorLabel`).
|
||||||
|
- **`demo-north-buildings` screenshot** framed 85 % sky (camera 9.5 km west of the buildings); re-pointed to the building mass.
|
||||||
|
|
||||||
|
### Verified
|
||||||
|
|
||||||
|
- Both sides of the demo are traversable: 1456-sample seam transect, 0 holes, no blocking collision or invisible walls (`-qaselftest` on the packaged build).
|
||||||
|
- Placement and street scale match the reference photography and Geo measurements (road 24.3 m, sidewalk offsets 12.5/13.2 m, hero frontage 26.0 m).
|
||||||
|
- **414 fps average / p99 3.01 ms at 2560×1440** (Epic preset, TSR, VSync off, no frame generation) — far above the 60 fps target.
|
||||||
|
- Fresh checkout builds and packages with the documented external engine (UE 5.8.4).
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- Buildings other than the hero are flat blockout volumes; façade detail, materials and Blosm style scripts are planned for `0.1.4`.
|
||||||
|
- Kerb height (0.13 m as built vs 0.15 m assumed), kerb radii, driveway aprons and graded crossing ramps are deferred to `0.1.1`; crossing ramps are kerb flushes.
|
||||||
|
- One block only; no vehicles, NPCs, audio, or settings UI yet.
|
||||||
|
|
||||||
|
[Unreleased]: https://git.allucanget.biz/zwitschi/gig-line/compare/v0.1.5...main
|
||||||
|
[0.1.5]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.5
|
||||||
|
[0.1.4]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.4
|
||||||
|
[0.1.3]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.3
|
||||||
|
[0.1.2]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.2
|
||||||
|
[0.1.1]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.1
|
||||||
|
[0.1.0]: https://git.allucanget.biz/zwitschi/gig-line/releases/tag/v0.1.0
|
||||||
@@ -20,11 +20,14 @@ Full requirements and progress are in [TODO.md](../../TODO.md); version directio
|
|||||||
|
|
||||||
| Priority | Quality Goal | Scenario |
|
| Priority | Quality Goal | Scenario |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 1 | **Performance efficiency** | 60 FPS at 2560×1440 on RTX 5070 Ti, documented preset, no frame generation |
|
| 1 | **Visual realism** | Renders read as the reference photographs: façade identity, proportion, material and light — judged side by side, shot against photo |
|
||||||
| 2 | **Terrain walkability** | Zero raycast holes across both sidewalks and the carriageway (84-sample transect passes) |
|
| 2 | **Geographic fidelity** | Building placement and street scale match the measured data and the photographs |
|
||||||
| 3 | **Geographic fidelity** | Building placement, street scale, and façade identity match reference photography |
|
| 3 | **Terrain walkability** | Zero raycast holes across both sidewalks and the carriageway (84-sample transect passes) |
|
||||||
| 4 | **Build reproducibility** | Fresh checkout + documented engine path produces a runnable Linux build |
|
| 4 | **Build reproducibility** | Fresh checkout + documented engine path produces a runnable Linux build |
|
||||||
| 5 | **Provenance** | Every committed asset has recorded provenance |
|
| 5 | **Provenance** | Every committed asset has recorded provenance |
|
||||||
|
| 6 | **Performance efficiency** | 60 FPS at 2560×1440 on RTX 5070 Ti, documented preset, no frame generation |
|
||||||
|
|
||||||
|
**How the order is used.** It decides trade-offs. When realism and performance disagree, realism wins and the cost is paid — but never by silently shipping a frame rate below the floor. The 60 FPS figure is a **budget that must still be met**, so the response to "realism costs too much frame time" is to cut the realism feature deliberately, record the cut, and keep the floor — not to let frames slip. Walkability outranks realism in one direction only: a beautiful block the player falls through is not a demo.
|
||||||
|
|
||||||
## Stakeholders
|
## Stakeholders
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ All modelling and geographic processing live outside the game project in `Art/`,
|
|||||||
|
|
||||||
## Quality achievement
|
## Quality achievement
|
||||||
|
|
||||||
- **Performance**: dynamic-only lighting (no build step, no static shadow maps), world-space-noise materials (cheap procedural variation), minimal overdraw (simple street-level geometry).
|
- **Realism first**: reference photography and measured data drive every façade decision; renders are compared against the photographs with `Tools/visual_loop.py`, and a façade is built from the shared 4.96 m module kit so the street wall reads consistently. Materials are authored in Unreal with world-aligned generated textures, and lighting is fixed daytime so a shot is comparable between runs.
|
||||||
|
- **Performance as a budget, not a driver**: dynamic-only lighting (no build step, no static shadow maps), world-space-noise materials (cheap procedural variation), minimal overdraw for street-level geometry, and a 60 FPS at 1440p floor that every release must meet. It closes the quality list because it constrains how much realism fits, not what the block should look like.
|
||||||
|
|
||||||
- **Walkability**: complex-as-simple collision on terrain (C++ helper forces the flag on the asset), block-all collision on every site mesh, swept transect QA verifies zero raycast holes.
|
- **Walkability**: complex-as-simple collision on terrain (C++ helper forces the flag on the asset), block-all collision on every site mesh, swept transect QA verifies zero raycast holes.
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ C++ classes in `Game/GigLine/Source/GigLine/`:
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `AGigLineCharacter` | First-person player pawn | 1.75 m capsule, 4.5 m/s walk, Enhanced Input bindings, reset, pause, `-qaselftest` harness |
|
| `AGigLineCharacter` | First-person player pawn | 1.75 m capsule, 4.5 m/s walk, Enhanced Input bindings, reset, pause, `-qaselftest` harness |
|
||||||
| `AGigLineGameModeBase` | Sets game mode and HUD class | `HUDClass = AGigLineHUD` |
|
| `AGigLineGameModeBase` | Sets game mode and HUD class | `HUDClass = AGigLineHUD` |
|
||||||
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame, bottom-left |
|
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame: ODbL attribution bottom-left, controls bottom-right, and an F3 debug readout top-left (`gigline.Debug`, on for `-perf`/`-qaselftest`) |
|
||||||
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
||||||
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
||||||
| `UGigLineAssetTools` | C++ collision helpers | `SetComplexCollisionAsSimple` on `StaticMesh` assets |
|
| `UGigLineAssetTools` | C++ collision helpers | `SetComplexCollisionAsSimple` on `StaticMesh` assets |
|
||||||
|
|
||||||
Input assets in `/Game/Input/`: `IA_Move`, `IA_MoveBack`, `IA_Strafe`, `IA_StrafeLeft`, `IA_Look`, `IA_Jump`, `IA_Reset`, `IA_Pause`, bound in `IMC_Default`.
|
Input assets in `/Game/Input/`: `IA_Move`, `IA_MoveBack`, `IA_Strafe`, `IA_StrafeLeft`, `IA_Look`, `IA_Jump`, `IA_Reset`, `IA_Pause`, `IA_ToggleCamera`, `IA_ToggleDebug`, bound in `IMC_Default`.
|
||||||
|
|
||||||
|
Player-facing bindings: **WASD** move, **mouse** look, **Space** jump, **R** reset, **Escape** pause, **V** swap first/third person. The camera and body work landed with `0.2.0` (see ADR-9): the shipped default view stays first person, and `-thirdperson` starts the pawn in the third-person rig — used by the screenshot run so the review is reproducible.
|
||||||
|
|
||||||
### Site
|
### Site
|
||||||
|
|
||||||
@@ -47,6 +49,7 @@ Static meshes and materials in `/Game/Hollywood/Site/`:
|
|||||||
| `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade |
|
| `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade |
|
||||||
| `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) |
|
| `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) |
|
||||||
| `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) |
|
| `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) |
|
||||||
|
| `SM_Retail_LeeDrug`, `SM_Retail_6806` | Retail trim over 6800 and 6806–6820, modelled from their own photograph (`Tools/retail_frontage_build.py`, staged as `RetailTrim_*`). `6822 Budget` stays a bare volume: no photograph exists. |
|
||||||
|
|
||||||
### Art Pipeline
|
### Art Pipeline
|
||||||
|
|
||||||
@@ -56,12 +59,19 @@ Python scripts in `Tools/` drive the content pipeline:
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
||||||
| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement |
|
| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement |
|
||||||
|
| `character_anim_build`, `ue_character_anim_import` | Character animation clips (`GigLine_Idle`, `GigLine_Walk`) and their import |
|
||||||
|
| `export_*`, `hero_facade_build`, `retail_frontage_build`, `theatre_trim_build`, `facade_kit_build` | Blender headless export (FBX); trim builders work in world coordinates |
|
||||||
|
| `ue_import_*`, `ue_hero_facade_import`, `ue_import_retail_detail` | Unreal headless import + placement |
|
||||||
| `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) |
|
| `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) |
|
||||||
| `ue_create_input_assets` | Enhanced Input actions + mapping context |
|
| `ue_create_input_assets` | Enhanced Input actions + mapping context |
|
||||||
| `render_screenshots.sh` | Screenshot capture pipeline |
|
| `render_screenshots.sh` | Screenshot capture pipeline |
|
||||||
| `judge_screenshot.py` | Vision-model pre-check (optional) |
|
| `judge_screenshot.py` | Vision-model pre-check (optional) |
|
||||||
|
| `input_emulation.py`, `input_test.py` | OS-level virtual keyboard/mouse injection for input verification |
|
||||||
|
| `Tools/_common.py` | Pure helper shared by Blender builders, importable without Blender (bay layout) |
|
||||||
|
| `Tools/tests/` | Stdlib `unittest` tests for the pure parts of the tools (`requirements-tools.txt`) |
|
||||||
|
| `Geo/tools/mapbox_buildings.py` | Second height source: Mapbox `mapbox-streets-v8` building data vs our OSM heights |
|
||||||
|
|
||||||
Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verification docs).
|
Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verification docs). Tool rules (one script one job, result files for commandlets, clean worktree for generators, documented inventory, tests for the pure parts) are in [`AGENTS.md`](../../AGENTS.md#python-and-shell-tooling).
|
||||||
|
|
||||||
### QA & Review
|
### QA & Review
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
| Dev workstation | Bazzite Linux 45 (Fedora 45 base, immutable ostree), Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB, Vulkan RHI |
|
| Dev workstation | Bazzite Linux 45 (Fedora 45 base, immutable ostree), Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB, Vulkan RHI |
|
||||||
| Engine install | `/run/media/system/DATA/Engines/UE_5.8.4` (73 GiB, external to repo) |
|
| Engine install | `/run/media/system/DATA/Engines/UE_5.8.4` (73 GiB, external to repo) |
|
||||||
| Project repo | `/run/media/system/DATA/Documents/06-games/gig-line` (Git + LFS, remote at `git.allucanget.biz`) |
|
| Project repo | `/run/media/system/DATA/Documents/06-games/gig-line` (Git + LFS, remote at `git.allucanget.biz`) |
|
||||||
| Build output | `/run/media/system/DATA/Builds/GigLine` (packaged Linux build, ~1.1 GiB) |
|
| Build output | `/run/media/system/DATA/Builds/GigLineQA/Linux` (packaged Development build, ~1.1 GiB; outside the repository) |
|
||||||
|
|
||||||
Motivation
|
Motivation
|
||||||
Single-machine development. No build farm, no CI pipeline yet. The engine, toolchain, and GPU are all on the same host.
|
Single-machine development. No build farm, no CI pipeline yet. The engine, toolchain, and GPU are all on the same host.
|
||||||
|
|||||||
@@ -55,3 +55,19 @@
|
|||||||
- **Decision**: All Blender work driven by Python scripts in `Tools/`. Skill packs used as method guides (checklists, naming, proportions) only.
|
- **Decision**: All Blender work driven by Python scripts in `Tools/`. Skill packs used as method guides (checklists, naming, proportions) only.
|
||||||
|
|
||||||
- **Consequences**: Scripts are version-controlled and repeatable. No live Blender session needed for CI.
|
- **Consequences**: Scripts are version-controlled and repeatable. No live Blender session needed for CI.
|
||||||
|
|
||||||
|
## ADR-8: Realistic building façades are a minor milestone, not a patch
|
||||||
|
|
||||||
|
- **Context**: `0.1.4` carried the first façade pass as a _patch_, while the release policy says patches contain fixes and refinements and never new scope. The `0.1.6` retail pass then showed what that costs: a façade built in a patch has no release gate of its own, so a first pass that does not yet read as the building (`Screenshots/README.md`, 0.1.6 gaps) can sit inside a "done" patch series. Realism is also the project's leading quality goal, which a patch cannot carry.
|
||||||
|
|
||||||
|
- **Decision**: Building realism gets its own minor milestone, `0.9.0 — Realistic buildings`, placed before the feature freeze. Its scope is the façade system (orders, profile library, storefront types, signage as decals), per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Patches keep fixes and refinements only. Renumbered by this decision: the former `0.9.0` freeze/beta/audit milestone becomes `0.10.0`, its patches `0.10.1`–`0.10.3`, and `1.0.0` moves to weeks 39–44.
|
||||||
|
|
||||||
|
- **Consequences**: Façade work now has a release gate — every building measured against its own photograph, every building with a collision proxy and a LOD, no placeholder materials — so "modelled" means verified, not merely present. The price is that realism work stops being sliced into patches, and the schedule shifts by one minor cycle. Blockouts without a photograph stay blockouts and are listed as such, rather than being dressed up to fill the milestone.
|
||||||
|
|
||||||
|
## ADR-9: Third-person body is an attachment of the first-person pawn, not a second pawn
|
||||||
|
|
||||||
|
- **Context**: `0.2.0` needs a visible body and a third-person camera, while `0.1.0` shipped a first-person pawn with no body and the owner's decision was first person for that release. Two separate pawn classes would duplicate movement, input and reset logic, which is the code most likely to drift.
|
||||||
|
|
||||||
|
- **Decision**: one pawn, both rigs. `AGigLineCharacter` carries a skeletal mesh (hidden in first person), a collision-tested spring-arm camera, and a **V** toggle that swaps the active camera and the body's visibility. The shipped default view stays first person; `-thirdperson` starts the pawn in the third-person rig and is what the screenshot run passes, so the review shot is reproducible without a human pressing a key.
|
||||||
|
|
||||||
|
- **Consequences**: movement, reset, pause and the QA self-test stay in one place. The body's animation state is driven from `Tick` by speed rather than from input, so being pushed or falling animates correctly. The cost is that the camera swap is not a separate actor, so a future cinematic camera needs its own path rather than reusing the toggle.
|
||||||
@@ -2,24 +2,44 @@
|
|||||||
|
|
||||||
## Quality Requirements Overview
|
## Quality Requirements Overview
|
||||||
|
|
||||||
| Category | Requirement | Priority |
|
Ordered by priority: realism first, performance last. The order decides design trade-offs; it does not license dropping a lower item silently (see the trade-off rule below the table).
|
||||||
|
|
||||||
|
| Priority | Category | Requirement |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Performance efficiency | 60 FPS at 2560×1440, documented preset, no frame generation | 1 |
|
| 1 | Realism / Fidelity | Façade identity, proportion, material and lighting read like the reference photographs when compared side by side |
|
||||||
| Reliability / Terrain | Zero raycast holes across sidewalks and carriageway (84-sample transect) | 1 |
|
| 2 | Realism / Fidelity | Building placement matches the measured footprints and the photographs (within ~1 m) |
|
||||||
| Accuracy / Fidelity | Building placement matches reference photography within ~1 m | 2 |
|
| 2 | Realism / Fidelity | Street scale (lane width, sidewalk width) within ~10 cm of the measured profile |
|
||||||
| Accuracy / Fidelity | Street scale (lane width, sidewalk width) within ~10 cm of measured profile | 2 |
|
| 3 | Reliability / Terrain | Zero raycast holes across sidewalks and carriageway (84-sample transect) |
|
||||||
| Usability | WASD + mouse look, jump, reset (R), pause (Escape) — no tutorial needed | 2 |
|
| 3 | Usability | WASD + mouse look, jump, reset (R), pause (Escape) — no tutorial needed |
|
||||||
| Maintainability | Fresh checkout builds with documented engine installation | 2 |
|
| 4 | Maintainability | Fresh checkout builds with the documented engine installation |
|
||||||
| Portability | Linux build packages and runs; Windows build ships | 3 |
|
| 4 | Portability | Linux build packages and runs; Windows build ships |
|
||||||
|
| 5 | Provenance | Every committed asset has a recorded source and licence |
|
||||||
|
| 6 | Performance efficiency | 60 FPS at 2560×1440, documented preset, no frame generation |
|
||||||
|
|
||||||
|
**Trade-off rule.** Realism leads: when a realism improvement costs frame time, the improvement wins. Performance is still a **floor, not a preference** — 60 FPS at 1440p without frame generation must be met at every release. If realism cannot fit inside that budget, reduce the realism scope deliberately and record the reduction in `CHANGELOG.md`; never ship below the floor without the owner's explicit approval. Walkability outranks realism in one direction: a block the player falls through is not a demo, whatever it looks like.
|
||||||
|
|
||||||
## Quality Scenarios
|
## Quality Scenarios
|
||||||
|
|
||||||
| ID | Source/Stimulus | Response | Metric |
|
| ID | Source/Stimulus | Response | Metric |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| QS-1 | Player walks both sides of the demo | No fall-through, character stays at ground Z | 0 raycast holes in 84-sample transect |
|
| QS-1 | Screenshot is compared against its reference photograph | The render reads as the same building | Similarity score and visual match confirmed by the owner; `Tools/visual_loop.py` reports the deltas |
|
||||||
| QS-2 | Player holds W for 2 s on flat road | Character moves forward | ≥ 200 cm displacement, Z constant within ±5 cm |
|
| QS-2 | A façade is placed from measured data | It sits on its verified footprint | World span probed against `Geo/verification/` within ~1 m |
|
||||||
| QS-3 | Player presses R | Character teleports to spawn | < 100 cm from `StartLocation` |
|
| QS-3 | Player walks both sides of the demo | No fall-through, character stays at ground Z | 0 raycast holes in 84-sample transect |
|
||||||
| QS-4 | Player presses Escape | Game pauses, cursor appears | `IsGamePaused()` = true |
|
| QS-4 | Player holds W for 2 s on flat road | Character moves forward | ≥ 200 cm displacement, Z constant within ±5 cm |
|
||||||
| QS-5 | Player presses Escape while paused | Game unpauses, cursor hides | `IsGamePaused()` = false |
|
| QS-5 | Player presses R | Character teleports to spawn | < 100 cm from `StartLocation` |
|
||||||
| QS-6 | Game runs on dev workstation at 1440p | Frame rate stable | ≥ 60 FPS, 99th percentile ≥ 55 FPS |
|
| QS-6 | Player presses Escape | Game pauses, cursor appears | `IsGamePaused()` = true |
|
||||||
| QS-7 | Fresh checkout + engine install | Build succeeds | Exit code 0, runnable binary produced |
|
| QS-7 | Player presses Escape while paused | Game unpauses, cursor hides | `IsGamePaused()` = false |
|
||||||
|
| QS-8 | Fresh checkout + engine install | Build succeeds | Exit code 0, runnable binary produced |
|
||||||
|
| QS-9 | Game runs on dev workstation at 1440p | Frame rate holds the floor | ≥ 60 FPS, 99th percentile ≥ 55 FPS |
|
||||||
|
|
||||||
|
> QS-9 is last on purpose. Performance is a floor that every release must meet, not the goal that shapes the content: realism decides what gets built, the frame budget decides how much of it.
|
||||||
|
|
||||||
|
### Building realism gate (0.9.0)
|
||||||
|
|
||||||
|
| ID | Check | Metric |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| BR-1 | A building with a reference photograph has a review shot compared against it | Silhouette and proportion deltas recorded per building in `Screenshots/README.md`; owner approval per shot |
|
||||||
|
| BR-2 | Every building is either photo-matched or explicitly recorded as an unfounded blockout | List in `TODO.md`; no building in an in-between state |
|
||||||
|
| BR-3 | Every building has a collision proxy and at least one LOD | Count of buildings missing either = 0 |
|
||||||
|
| BR-4 | No surface carries a placeholder material | Material audit in `Tools/ue_audit_scene.py` reports 0 placeholder slots |
|
||||||
|
| BR-5 | The realism pass does not break the floor | QS-9 still holds at 1440p, with the measured cost of the pass recorded |
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
# Gig Line Architecture Documentation
|
---
|
||||||
|
title: Gig Line Architecture Documentation
|
||||||
> Linux-first walking/driving demo around 6840 Hollywood Blvd
|
description: Architecture documentation for the Gig Line Linux-first Unreal Engine 5 demo around 6840 Hollywood Blvd.
|
||||||
|
status: v0.1.0
|
||||||
Version 0.1.0 — 2026-11-08 — initial architecture documentation
|
date: 2026-11-08
|
||||||
|
---
|
||||||
|
|
||||||
# Introduction and Goals
|
# Introduction and Goals
|
||||||
|
|
||||||
@@ -26,11 +27,14 @@ Full requirements and progress are in [TODO.md](../../TODO.md); version directio
|
|||||||
|
|
||||||
| Priority | Quality Goal | Scenario |
|
| Priority | Quality Goal | Scenario |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 1 | **Performance efficiency** | 60 FPS at 2560×1440 on RTX 5070 Ti, documented preset, no frame generation |
|
| 1 | **Visual realism** | Renders read as the reference photographs: façade identity, proportion, material and light — judged side by side, shot against photo |
|
||||||
| 2 | **Terrain walkability** | Zero raycast holes across both sidewalks and the carriageway (84-sample transect passes) |
|
| 2 | **Geographic fidelity** | Building placement and street scale match the measured data and the photographs |
|
||||||
| 3 | **Geographic fidelity** | Building placement, street scale, and façade identity match reference photography |
|
| 3 | **Terrain walkability** | Zero raycast holes across both sidewalks and the carriageway (84-sample transect passes) |
|
||||||
| 4 | **Build reproducibility** | Fresh checkout + documented engine path produces a runnable Linux build |
|
| 4 | **Build reproducibility** | Fresh checkout + documented engine path produces a runnable Linux build |
|
||||||
| 5 | **Provenance** | Every committed asset has recorded provenance |
|
| 5 | **Provenance** | Every committed asset has recorded provenance |
|
||||||
|
| 6 | **Performance efficiency** | 60 FPS at 2560×1440 on RTX 5070 Ti, documented preset, no frame generation |
|
||||||
|
|
||||||
|
**How the order is used.** It decides trade-offs. When realism and performance disagree, realism wins and the cost is paid — but never by silently shipping a frame rate below the floor. The 60 FPS figure is a **budget that must still be met**, so the response to "realism costs too much frame time" is to cut the realism feature deliberately, record the cut, and keep the floor — not to let frames slip. Walkability outranks realism in one direction only: a beautiful block the player falls through is not a demo.
|
||||||
|
|
||||||
## Stakeholders
|
## Stakeholders
|
||||||
|
|
||||||
@@ -128,7 +132,9 @@ All modelling and geographic processing live outside the game project in `Art/`,
|
|||||||
|
|
||||||
## Quality achievement
|
## Quality achievement
|
||||||
|
|
||||||
- **Performance**: dynamic-only lighting (no build step, no static shadow maps), world-space-noise materials (cheap procedural variation), minimal overdraw (simple street-level geometry).
|
- **Realism**: reference photography drives every façade decision, measured data fixes placement and scale, and renders are compared against the photographs (`Tools/visual_loop.py`, `Screenshots/README.md`). One module kit at the 4.96 m bay keeps the street wall coherent; materials are world-aligned and lit by a fixed daytime rig so a shot is comparable between runs.
|
||||||
|
|
||||||
|
- **Performance holds the floor, it does not set the agenda**: dynamic-only lighting (no build step, no static shadow maps), cheap procedural materials, minimal overdraw for street-level geometry, and 60 FPS at 1440p as a budget every release must meet.
|
||||||
|
|
||||||
- **Walkability**: complex-as-simple collision on terrain (C++ helper forces the flag on the asset), block-all collision on every site mesh, swept transect QA verifies zero raycast holes.
|
- **Walkability**: complex-as-simple collision on terrain (C++ helper forces the flag on the asset), block-all collision on every site mesh, swept transect QA verifies zero raycast holes.
|
||||||
|
|
||||||
@@ -158,12 +164,14 @@ C++ classes in `Game/GigLine/Source/GigLine/`:
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `AGigLineCharacter` | First-person player pawn | 1.75 m capsule, 4.5 m/s walk, Enhanced Input bindings, reset, pause, `-qaselftest` harness |
|
| `AGigLineCharacter` | First-person player pawn | 1.75 m capsule, 4.5 m/s walk, Enhanced Input bindings, reset, pause, `-qaselftest` harness |
|
||||||
| `AGigLineGameModeBase` | Sets game mode and HUD class | `HUDClass = AGigLineHUD` |
|
| `AGigLineGameModeBase` | Sets game mode and HUD class | `HUDClass = AGigLineHUD` |
|
||||||
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame, bottom-left |
|
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame: ODbL attribution bottom-left, controls bottom-right, and an F3 debug readout top-left (`gigline.Debug`, on for `-perf`/`-qaselftest`) |
|
||||||
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
||||||
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
||||||
| `UGigLineAssetTools` | C++ collision helpers | `SetComplexCollisionAsSimple` on `StaticMesh` assets |
|
| `UGigLineAssetTools` | C++ collision helpers | `SetComplexCollisionAsSimple` on `StaticMesh` assets |
|
||||||
|
|
||||||
Input assets in `/Game/Input/`: `IA_Move`, `IA_MoveBack`, `IA_Strafe`, `IA_StrafeLeft`, `IA_Look`, `IA_Jump`, `IA_Reset`, `IA_Pause`, bound in `IMC_Default`.
|
Input assets in `/Game/Input/`: `IA_Move`, `IA_MoveBack`, `IA_Strafe`, `IA_StrafeLeft`, `IA_Look`, `IA_Jump`, `IA_Reset`, `IA_Pause`, `IA_ToggleCamera`, `IA_ToggleDebug`, bound in `IMC_Default`.
|
||||||
|
|
||||||
|
Player-facing bindings: **WASD** move, **mouse** look, **Space** jump, **R** reset, **Escape** pause, **V** swap first/third person. The camera and body work landed with `0.2.0` (see ADR-9): the shipped default view stays first person, and `-thirdperson` starts the pawn in the third-person rig — used by the screenshot run so the review is reproducible.
|
||||||
|
|
||||||
### Site
|
### Site
|
||||||
|
|
||||||
@@ -185,6 +193,7 @@ Static meshes and materials in `/Game/Hollywood/Site/`:
|
|||||||
| `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade |
|
| `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade |
|
||||||
| `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) |
|
| `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) |
|
||||||
| `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) |
|
| `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) |
|
||||||
|
| `SM_Retail_LeeDrug`, `SM_Retail_6806` | Retail trim over 6800 and 6806–6820, modelled from their own photograph (`Tools/retail_frontage_build.py`, staged as `RetailTrim_*`). `6822 Budget` stays a bare volume: no photograph exists. |
|
||||||
|
|
||||||
### Art Pipeline
|
### Art Pipeline
|
||||||
|
|
||||||
@@ -194,10 +203,17 @@ Python scripts in `Tools/` drive the content pipeline:
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
||||||
| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement |
|
| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement |
|
||||||
|
| `character_anim_build`, `ue_character_anim_import` | Character animation clips (`GigLine_Idle`, `GigLine_Walk`) and their import |
|
||||||
|
| `export_*`, `hero_facade_build`, `retail_frontage_build`, `theatre_trim_build`, `facade_kit_build` | Blender headless export (FBX); trim builders work in world coordinates |
|
||||||
|
| `ue_import_*`, `ue_hero_facade_import`, `ue_import_retail_detail` | Unreal headless import + placement |
|
||||||
| `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) |
|
| `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) |
|
||||||
| `ue_create_input_assets` | Enhanced Input actions + mapping context |
|
| `ue_create_input_assets` | Enhanced Input actions + mapping context |
|
||||||
| `render_screenshots.sh` | Screenshot capture pipeline |
|
| `render_screenshots.sh` | Screenshot capture pipeline |
|
||||||
| `judge_screenshot.py` | Vision-model pre-check (optional) |
|
| `judge_screenshot.py` | Vision-model pre-check (optional) |
|
||||||
|
| `input_emulation.py`, `input_test.py` | OS-level virtual keyboard/mouse injection for input verification |
|
||||||
|
| `Tools/_common.py` | Pure helper shared by Blender builders, importable without Blender (bay layout) |
|
||||||
|
| `Tools/tests/` | Stdlib `unittest` tests for the pure parts of the tools (`requirements-tools.txt`) |
|
||||||
|
| `Geo/tools/mapbox_buildings.py` | Second height source: Mapbox `mapbox-streets-v8` building data vs our OSM heights |
|
||||||
|
|
||||||
Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verification docs).
|
Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verification docs).
|
||||||
|
|
||||||
@@ -296,7 +312,7 @@ Source data: `Art/blender/` (`.blend` files), `Geo/` (OSM extracts, DEM, verific
|
|||||||
| Dev workstation | Bazzite Linux 45 (Fedora 45 base, immutable ostree), Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB, Vulkan RHI |
|
| Dev workstation | Bazzite Linux 45 (Fedora 45 base, immutable ostree), Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB, Vulkan RHI |
|
||||||
| Engine install | `/run/media/system/DATA/Engines/UE_5.8.4` (73 GiB, external to repo) |
|
| Engine install | `/run/media/system/DATA/Engines/UE_5.8.4` (73 GiB, external to repo) |
|
||||||
| Project repo | `/run/media/system/DATA/Documents/06-games/gig-line` (Git + LFS, remote at `git.allucanget.biz`) |
|
| Project repo | `/run/media/system/DATA/Documents/06-games/gig-line` (Git + LFS, remote at `git.allucanget.biz`) |
|
||||||
| Build output | `/run/media/system/DATA/Builds/GigLine` (packaged Linux build, ~1.1 GiB) |
|
| Build output | `/run/media/system/DATA/Builds/GigLineQA/Linux` (packaged Development build, ~1.1 GiB; outside the repository) |
|
||||||
|
|
||||||
Motivation
|
Motivation
|
||||||
Single-machine development. No build farm, no CI pipeline yet. The engine, toolchain, and GPU are all on the same host.
|
Single-machine development. No build farm, no CI pipeline yet. The engine, toolchain, and GPU are all on the same host.
|
||||||
@@ -442,31 +458,67 @@ Rule: place a building only against a neighbour or street mesh, never in isolati
|
|||||||
|
|
||||||
- **Consequences**: Scripts are version-controlled and repeatable. No live Blender session needed for CI.
|
- **Consequences**: Scripts are version-controlled and repeatable. No live Blender session needed for CI.
|
||||||
|
|
||||||
|
## ADR-8: Realistic building façades are a minor milestone, not a patch
|
||||||
|
|
||||||
|
- **Context**: `0.1.4` carried the first façade pass as a _patch_, while the release policy says patches contain fixes and refinements and never new scope. The `0.1.6` retail pass then showed what that costs: a façade built in a patch has no release gate of its own, so a first pass that does not yet read as the building (`Screenshots/README.md`, 0.1.6 gaps) can sit inside a "done" patch series. Realism is also the project's leading quality goal, which a patch cannot carry.
|
||||||
|
|
||||||
|
- **Decision**: Building realism gets its own minor milestone, `0.9.0 — Realistic buildings`, placed before the feature freeze. Its scope is the façade system (orders, profile library, storefront types, signage as decals), per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Patches keep fixes and refinements only. Renumbered by this decision: the former `0.9.0` freeze/beta/audit milestone becomes `0.10.0`, its patches `0.10.1`–`0.10.3`, and `1.0.0` moves to weeks 39–44.
|
||||||
|
|
||||||
|
- **Consequences**: Façade work now has a release gate — every building measured against its own photograph, every building with a collision proxy and a LOD, no placeholder materials — so "modelled" means verified, not merely present. The price is that realism work stops being sliced into patches, and the schedule shifts by one minor cycle. Blockouts without a photograph stay blockouts and are listed as such, rather than being dressed up to fill the milestone.
|
||||||
|
|
||||||
|
## ADR-9: Third-person body is an attachment of the first-person pawn, not a second pawn
|
||||||
|
|
||||||
|
- **Context**: `0.2.0` needs a visible body and a third-person camera, while `0.1.0` shipped a first-person pawn with no body and the owner's decision was first person for that release. Two separate pawn classes would duplicate movement, input and reset logic, which is the code most likely to drift.
|
||||||
|
|
||||||
|
- **Decision**: one pawn, both rigs. `AGigLineCharacter` carries a skeletal mesh (hidden in first person), a collision-tested spring-arm camera, and a **V** toggle that swaps the active camera and the body's visibility. The shipped default view stays first person; `-thirdperson` starts the pawn in the third-person rig and is what the screenshot run passes, so the review shot is reproducible without a human pressing a key.
|
||||||
|
|
||||||
|
- **Consequences**: movement, reset, pause and the QA self-test stay in one place. The body's animation state is driven from `Tick` by speed rather than from input, so being pushed or falling animates correctly. The cost is that the camera swap is not a separate actor, so a future cinematic camera needs its own path rather than reusing the toggle.
|
||||||
|
|
||||||
# Quality Requirements
|
# Quality Requirements
|
||||||
|
|
||||||
## Quality Requirements Overview
|
## Quality Requirements Overview
|
||||||
|
|
||||||
| Category | Requirement | Priority |
|
Ordered by priority: realism first, performance last. The order decides design trade-offs; it does not license dropping a lower item silently (see the trade-off rule below the table).
|
||||||
|
|
||||||
|
| Priority | Category | Requirement |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Performance efficiency | 60 FPS at 2560×1440, documented preset, no frame generation | 1 |
|
| 1 | Realism / Fidelity | Façade identity, proportion, material and lighting read like the reference photographs when compared side by side |
|
||||||
| Reliability / Terrain | Zero raycast holes across sidewalks and carriageway (84-sample transect) | 1 |
|
| 2 | Realism / Fidelity | Building placement matches the measured footprints and the photographs (within ~1 m) |
|
||||||
| Accuracy / Fidelity | Building placement matches reference photography within ~1 m | 2 |
|
| 2 | Realism / Fidelity | Street scale (lane width, sidewalk width) within ~10 cm of the measured profile |
|
||||||
| Accuracy / Fidelity | Street scale (lane width, sidewalk width) within ~10 cm of measured profile | 2 |
|
| 3 | Reliability / Terrain | Zero raycast holes across sidewalks and carriageway (84-sample transect) |
|
||||||
| Usability | WASD + mouse look, jump, reset (R), pause (Escape) — no tutorial needed | 2 |
|
| 3 | Usability | WASD + mouse look, jump, reset (R), pause (Escape) — no tutorial needed |
|
||||||
| Maintainability | Fresh checkout builds with documented engine installation | 2 |
|
| 4 | Maintainability | Fresh checkout builds with the documented engine installation |
|
||||||
| Portability | Linux build packages and runs; Windows build ships | 3 |
|
| 4 | Portability | Linux build packages and runs; Windows build ships |
|
||||||
|
| 5 | Provenance | Every committed asset has a recorded source and licence |
|
||||||
|
| 6 | Performance efficiency | 60 FPS at 2560×1440, documented preset, no frame generation |
|
||||||
|
|
||||||
|
**Trade-off rule.** Realism leads: when a realism improvement costs frame time, the improvement wins. Performance is still a **floor, not a preference** — 60 FPS at 1440p without frame generation must be met at every release. If realism cannot fit inside that budget, reduce the realism scope deliberately and record the reduction in `CHANGELOG.md`; never ship below the floor without the owner's explicit approval. Walkability outranks realism in one direction: a block the player falls through is not a demo, whatever it looks like.
|
||||||
|
|
||||||
## Quality Scenarios
|
## Quality Scenarios
|
||||||
|
|
||||||
| ID | Source/Stimulus | Response | Metric |
|
| ID | Source/Stimulus | Response | Metric |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| QS-1 | Player walks both sides of the demo | No fall-through, character stays at ground Z | 0 raycast holes in 84-sample transect |
|
| QS-1 | Screenshot is compared against its reference photograph | The render reads as the same building | Similarity score and visual match confirmed by the owner; `Tools/visual_loop.py` reports the deltas |
|
||||||
| QS-2 | Player holds W for 2 s on flat road | Character moves forward | ≥ 200 cm displacement, Z constant within ±5 cm |
|
| QS-2 | A façade is placed from measured data | It sits on its verified footprint | World span probed against `Geo/verification/` within ~1 m |
|
||||||
| QS-3 | Player presses R | Character teleports to spawn | < 100 cm from `StartLocation` |
|
| QS-3 | Player walks both sides of the demo | No fall-through, character stays at ground Z | 0 raycast holes in 84-sample transect |
|
||||||
| QS-4 | Player presses Escape | Game pauses, cursor appears | `IsGamePaused()` = true |
|
| QS-4 | Player holds W for 2 s on flat road | Character moves forward | ≥ 200 cm displacement, Z constant within ±5 cm |
|
||||||
| QS-5 | Player presses Escape while paused | Game unpauses, cursor hides | `IsGamePaused()` = false |
|
| QS-5 | Player presses R | Character teleports to spawn | < 100 cm from `StartLocation` |
|
||||||
| QS-6 | Game runs on dev workstation at 1440p | Frame rate stable | ≥ 60 FPS, 99th percentile ≥ 55 FPS |
|
| QS-6 | Player presses Escape | Game pauses, cursor appears | `IsGamePaused()` = true |
|
||||||
| QS-7 | Fresh checkout + engine install | Build succeeds | Exit code 0, runnable binary produced |
|
| QS-7 | Player presses Escape while paused | Game unpauses, cursor hides | `IsGamePaused()` = false |
|
||||||
|
| QS-8 | Fresh checkout + engine install | Build succeeds | Exit code 0, runnable binary produced |
|
||||||
|
| QS-9 | Game runs on dev workstation at 1440p | Frame rate holds the floor | ≥ 60 FPS, 99th percentile ≥ 55 FPS |
|
||||||
|
|
||||||
|
> QS-9 is last on purpose. Performance is a floor that every release must meet, not the goal that shapes the content: realism decides what gets built, the frame budget decides how much of it.
|
||||||
|
|
||||||
|
### Building realism gate (0.9.0)
|
||||||
|
|
||||||
|
| ID | Check | Metric |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| BR-1 | A building with a reference photograph has a review shot compared against it | Silhouette and proportion deltas recorded per building in `Screenshots/README.md`; owner approval per shot |
|
||||||
|
| BR-2 | Every building is either photo-matched or explicitly recorded as an unfounded blockout | List in `TODO.md`; no building in an in-between state |
|
||||||
|
| BR-3 | Every building has a collision proxy and at least one LOD | Count of buildings missing either = 0 |
|
||||||
|
| BR-4 | No surface carries a placeholder material | Material audit in `Tools/ue_audit_scene.py` reports 0 placeholder slots |
|
||||||
|
| BR-5 | The realism pass does not break the floor | QS-9 still holds at 1440p, with the measured cost of the pass recorded |
|
||||||
|
|
||||||
# Risks and Technical Debts
|
# Risks and Technical Debts
|
||||||
|
|
||||||
|
|||||||
+50
-37
@@ -1,6 +1,6 @@
|
|||||||
# Build
|
# Build
|
||||||
|
|
||||||
Fresh-checkout build procedure. Completed 2026-11-07 after the pinned engine was installed and a blank `Game/GigLine` build was packaged and launch-tested.
|
Fresh-checkout build, content-pipeline and packaging procedure for the walkable demo. Begun 2026-11-07 from a blank build and extended through the `0.1.x` patches; the release checks that exercise it are in [release-checks.md](release-checks.md).
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
@@ -10,8 +10,7 @@ Fresh-checkout build procedure. Completed 2026-11-07 after the pinned engine was
|
|||||||
|
|
||||||
## Engine
|
## Engine
|
||||||
|
|
||||||
Pinned install: **Unreal Engine 5.8.4** (CL 58902052, promoted build) at
|
Pinned install: **Unreal Engine 5.8.4** (CL 58902052, promoted build) at `/run/media/system/DATA/Engines/UE_5.8.4`. The engine bundles **no** Linux clang; the system clang (23.1.4, Fedora 45) is the game-code toolchain. Game targets must use `BuildSettingsVersion.V7` to share the installed editor's build environment.
|
||||||
`/run/media/system/DATA/Engines/UE_5.8.4`. The engine bundles **no** Linux clang; the system clang (23.1.4, Fedora 45) is the game-code toolchain. Game targets must use `BuildSettingsVersion.V7` to share the installed editor's build environment.
|
|
||||||
|
|
||||||
## Fresh-checkout build
|
## Fresh-checkout build
|
||||||
|
|
||||||
@@ -42,20 +41,14 @@ cd /run/media/system/DATA/Engines/UE_5.8.4
|
|||||||
Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
|
Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
|
||||||
-project="/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject" \
|
-project="/run/media/system/DATA/Documents/06-games/gig-line/Game/GigLine/GigLine.uproject" \
|
||||||
-noP4 -platform=Linux -clientconfig=Development \
|
-noP4 -platform=Linux -clientconfig=Development \
|
||||||
-cook -allmaps -build -stage -pak \
|
-cook -build -stage -pak \
|
||||||
-archive -archivedirectory="/run/media/system/DATA/Builds/GigLine" \
|
-archive -archivedirectory="/run/media/system/DATA/Builds/GigLineQA" \
|
||||||
-unattended
|
-unattended
|
||||||
# Expected: "BUILD SUCCESSFUL" (~1 min for the blank project; archive ~1.1 GiB)
|
# Expected: "AutomationTool exiting with ExitCode=0 (Success)" and "EXIT=0", ~90 s
|
||||||
# Launch test (plain, no -map): /run/media/system/DATA/Builds/GigLine/Linux/GigLine.sh
|
# Launch test (plain, no -map): /run/media/system/DATA/Builds/GigLineQA/Linux/GigLine.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**Launch test must open the DemoMap.** A plain `./GigLine.sh` should load
|
**Launch test must open the DemoMap.** A plain `./GigLine.sh` should load `/Game/Hollywood/DemoMap` (set via `DefaultEngine.ini` `GameMapsSettings`). If it instead opens `/Engine/Maps/Templates/OpenWorld`, the game shows an empty non-interactive "stuck" scene — check that `GameDefaultMap` is in `DefaultEngine.ini`, not `DefaultGame.ini`. Confirm the loaded map in the engine log: `.../Linux/GigLine/Saved/Logs/GigLine.log` (`LoadMap: /Game/Hollywood/DemoMap`). The archive directory is deliberately **outside** the repository; never archive into the checkout.
|
||||||
`/Game/Hollywood/DemoMap` (set via `DefaultEngine.ini` `GameMapsSettings`). If it
|
|
||||||
instead opens `/Engine/Maps/Templates/OpenWorld`, the game shows an empty
|
|
||||||
non-interactive "stuck" scene — check that `GameDefaultMap` is in
|
|
||||||
`DefaultEngine.ini`, not `DefaultGame.ini`. Confirm the loaded map in the engine
|
|
||||||
log: `.../Linux/GigLine/Saved/Logs/GigLine.log` (`LoadMap: /Game/Hollywood/DemoMap`).
|
|
||||||
The archive directory is deliberately **outside** the repository; never archive into the checkout.
|
|
||||||
|
|
||||||
## Headless content checks
|
## Headless content checks
|
||||||
|
|
||||||
@@ -76,9 +69,7 @@ Both content-acceptance tests run headless and are the template for all asset im
|
|||||||
|
|
||||||
## Content pipeline (current)
|
## Content pipeline (current)
|
||||||
|
|
||||||
The hero block and the demo level are built by a fixed sequence. Each step writes
|
The hero block and the demo level are built by a fixed sequence. Each step writes a result file under `/tmp/gigline/`; read it, because the commandlet's own stdout can be swallowed.
|
||||||
a result file under `/tmp/gigline/`; read it, because the commandlet's own stdout
|
|
||||||
can be swallowed.
|
|
||||||
|
|
||||||
| Step | Tool | Output |
|
| Step | Tool | Output |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
@@ -86,21 +77,28 @@ can be swallowed.
|
|||||||
| Terrain | `Art/blender/terrain/terrain_from_dem.py` | `Art/blender/terrain/terrain-*.blend` |
|
| Terrain | `Art/blender/terrain/terrain_from_dem.py` | `Art/blender/terrain/terrain-*.blend` |
|
||||||
| Street | `Art/blender/street/street_mesh.py` | `Art/blender/street/street-*.blend` |
|
| Street | `Art/blender/street/street_mesh.py` | `Art/blender/street/street-*.blend` |
|
||||||
| Site assembly | `Art/blender/site/site_assembly.py` | `Art/blender/site/site-*.blend` |
|
| Site assembly | `Art/blender/site/site_assembly.py` | `Art/blender/site/site-*.blend` |
|
||||||
| Site export | `Art/blender/site/export_site_fbx.py` | six FBXs, one per mesh |
|
| Site export | `Art/blender/site/export_site_fbx.py` | seven FBXs, one per mesh (terrain, road, both sidewalks, both kerbs, crossing) |
|
||||||
| Hero façade | `Tools/hero_facade_build.py` | `Art/blender/hero/hero-facade-*.blend` + JSON report |
|
| Hero façade | `Tools/hero_facade_build.py` | `Art/blender/hero/hero-facade-*.blend` + JSON part report |
|
||||||
|
| Block frontage | `Tools/export_block_frontage.py` | six frontage FBXs from the blockout |
|
||||||
|
| North buildings | `Tools/export_north_buildings.py` | TCL and Tussaud's FBXs from the blockout |
|
||||||
| Site import | `Tools/ue_import_site.py` | `/Game/Hollywood/Site/*` |
|
| Site import | `Tools/ue_import_site.py` | `/Game/Hollywood/Site/*` |
|
||||||
|
| Frontage import | `Tools/ue_import_block_frontage.py` | `/Game/Hollywood/Frontage/*` |
|
||||||
|
| North import | `Tools/ue_import_north_buildings.py` | `/Game/Hollywood/North/*` |
|
||||||
| Hero import | `Tools/ue_hero_facade_import.py` | `/Game/Hollywood/ElCapitan/SM_HeroFacade` |
|
| Hero import | `Tools/ue_hero_facade_import.py` | `/Game/Hollywood/ElCapitan/SM_HeroFacade` |
|
||||||
| Demo map | `Tools/ue_build_demo_map.py` | `/Game/Hollywood/DemoMap` |
|
| Demo map | `Tools/ue_build_demo_map.py` | `/Game/Hollywood/DemoMap` |
|
||||||
|
| Façade kit assembly | `Tools/ue_apply_facade_kit.py` | kit actors in `DemoMap` |
|
||||||
|
| Theatre trim | `Tools/ue_stage_theatre_trim.py` | marquee + blade sign actors |
|
||||||
|
| Scene audit | `Tools/ue_audit_scene.py` | materials, placement spans, labels (gate) |
|
||||||
| Review shots | `Tools/ue_build_review_map.py` + `Tools/render_screenshots.sh` | `Screenshots/` |
|
| Review shots | `Tools/ue_build_review_map.py` + `Tools/render_screenshots.sh` | `Screenshots/` |
|
||||||
|
|
||||||
|
**Order matters.** `ue_build_demo_map.py` rebuilds the site materials, so any actor staged by another tool must be (re)staged _after_ it, or it keeps a reference to a material that no longer exists — that is how 604 actors once ended up untethered from their materials while the map only looked slightly flat. `Tools/render_screenshots.sh` runs the full chain in the right order and gates on `ue_audit_scene.py`.
|
||||||
|
|
||||||
|
Every Blender exporter calls [`Tools/fbx_export_preset.py`](../Tools/fbx_export_preset.py) (`ue_metric_v1` / `ue_character_v1`) instead of repeating the FBX argument block — one place for the scale conversion, the axis mapping and `mesh_smooth_type="FACE"` (without which every Unreal import warns about missing smoothing groups and round geometry arrives faceted).
|
||||||
|
|
||||||
Two rules that the pipeline enforces rather than documents:
|
Two rules that the pipeline enforces rather than documents:
|
||||||
|
|
||||||
- **One conversion.** Metres to Unreal centimetres happens only in
|
- **One conversion.** Metres to Unreal centimetres happens only in `Geo/tools/osm_common.py::to_unreal_local`. Sidecars (`<asset>.geo.json`) record the result and `Geo/tools/asset_metadata.py audit` re-derives it.
|
||||||
`Geo/tools/osm_common.py::to_unreal_local`. Sidecars (`<asset>.geo.json`) record
|
- **Collision is decided at import,** not later: terrain, road and sidewalks are complex-as-simple; kerbs and props stay simple. A simple hull over a kerbed street ramps straight across the kerb.
|
||||||
the result and `Geo/tools/asset_metadata.py audit` re-derives it.
|
|
||||||
- **Collision is decided at import,** not later: terrain, road and sidewalks are
|
|
||||||
complex-as-simple; kerbs and props stay simple. A simple hull over a kerbed
|
|
||||||
street ramps straight across the kerb.
|
|
||||||
|
|
||||||
## Known engine quirks (2026-11-07)
|
## Known engine quirks (2026-11-07)
|
||||||
|
|
||||||
@@ -110,20 +108,35 @@ Two rules that the pipeline enforces rather than documents:
|
|||||||
|
|
||||||
## Packaged Linux build
|
## Packaged Linux build
|
||||||
|
|
||||||
- 2026-11-07: blank `Game/GigLine` Development build packaged via the command above; 1.1 GiB archive at `/run/media/system/DATA/Builds/GigLine/Linux`; `GigLine.sh` launched on the desktop session, Vulkan swapchain created, 759 frames rendered across a 60 s smoke test. Controls document to be written with the first playable (`0.1.0` Gameplay section).
|
Current QA archive: `/run/media/system/DATA/Builds/GigLineQA`. A plain `./GigLine.sh` opens `/Game/Hollywood/DemoMap`; controls are in [controls.md](controls.md) and shown in-game bottom-right. The packaged log is written **relative to the wrapper's working directory**, i.e. `<archive>/Linux/GigLine/Saved/Logs/GigLine.log` — not into the repository.
|
||||||
|
|
||||||
|
Behaviour check without a human at the keyboard:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /run/media/system/DATA/Builds/GigLineQA/Linux
|
||||||
|
./GigLine.sh -windowed -ResX=1280 -ResY=720 -nosplash -qaselftest
|
||||||
|
# then read <archive>/Linux/GigLine/Saved/Logs/GigLine.log for "GigLine QA:" lines
|
||||||
|
```
|
||||||
|
|
||||||
|
`-qaselftest` walks for 2 s, resets, pauses/unpauses, sweeps a 16-row seam transect, fires a ground-referenced 21 m wall probe along the street, fires 40 m façade-occlusion traces sideways from the road centre wherever a building is staged, and writes a frame-time series to `Saved/Profiling/`. Every phase logs `... PASS`/`FAIL` and the run ends with `RESULT`.
|
||||||
|
|
||||||
|
## Traps that cost real time in `0.1.x`
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| A builder reports success but the asset is unchanged | `.blend`/`.umap` are LFS-tracked and check out **read-only**; Blender and Unreal fail the save quietly | `chmod u+w <file>` first — `ue_build_*`/`ue_hero_facade_import` and every Blender builder need it |
|
||||||
|
| `File format is not supported` when reopening a `.blend` | `hero_facade_build.py --out` writes the **FBX**; putting the `.blend` path there overwrites it with FBX bytes | `--out /tmp/…fbx --save-blend Art/…blend --report Art/…json` |
|
||||||
|
| `Add-on not loaded: "bl_ext.blender_org.mpfb"` | `mpfb_character_export.py` needs the MPFB add-on visible to Blender | export `BLENDER_USER_SCRIPTS` (see the invocation in [../Art/blender/README.md](../Art/blender/README.md)) |
|
||||||
|
| The packaged run exits after a couple of seconds during QA | `GigLineShotActor` runs its screenshot list and quits (`bQuitWhenDone`) | it skips its rounds when `-qaselftest` is on the command line — keep that guard |
|
||||||
|
| Headless `-nullrhi` traces report no hits for everything | the null RHI has no physics scene | verify traces in the **packaged** run (`-qaselftest`), never in a commandlet |
|
||||||
|
| Import logs "No smoothing group information" for every mesh | `mesh_smooth_type="OFF"` in the FBX export | use `Tools/fbx_export_preset.py` (`FACE`) |
|
||||||
|
|
||||||
## PIE input test (compare editor vs packaged input intake)
|
## PIE input test (compare editor vs packaged input intake)
|
||||||
|
|
||||||
Use to isolate whether the "no controls respond" bug is the packaged standalone's
|
Use to isolate whether the "no controls respond" bug is the packaged standalone's input intake or the Enhanced Input wiring generally.
|
||||||
input intake or the Enhanced Input wiring generally.
|
|
||||||
|
|
||||||
- `Tools/run_pie.sh` opens the editor on `/Game/Hollywood/DemoMap`. Press the
|
- `Tools/run_pie.sh` opens the editor on `/Game/Hollywood/DemoMap`. Press the green **Play** (PIE) button and walk / mouse-look.
|
||||||
green **Play** (PIE) button and walk / mouse-look.
|
|
||||||
- Interpretation:
|
- Interpretation:
|
||||||
- PIE **works** -> the Enhanced Input wiring is fine and the standalone
|
- PIE **works** -> the Enhanced Input wiring is fine and the standalone packaged build's SDL input intake is the environment-dependent bug.
|
||||||
packaged build's SDL input intake is the environment-dependent bug.
|
- PIE **fails** too -> the Enhanced Input setup itself is broken; rebuild the input config / character from scratch.
|
||||||
- PIE **fails** too -> the Enhanced Input setup itself is broken; rebuild
|
- The DemoMap is PIE-ready as committed: `GlobalDefaultGameMode` + `GameDefaultMap=/Game/Hollywood/DemoMap`, and the map stages a PlayerStart at `(-13336,-1150,600)` on the cut sidewalk with the walkable `AGigLineCharacter`.
|
||||||
the input config / character from scratch.
|
|
||||||
- The DemoMap is PIE-ready as committed: `GlobalDefaultGameMode` +
|
|
||||||
`GameDefaultMap=/Game/Hollywood/DemoMap`, and the map stages a PlayerStart at
|
|
||||||
`(-13336,-1150,600)` on the cut sidewalk with the walkable `AGigLineCharacter`.
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# Controls
|
||||||
|
|
||||||
|
Keyboard and mouse. The same list is shown in-game, bottom-right of the frame (`AGigLineHUD`), and the packaged Linux build ships with these bindings.
|
||||||
|
|
||||||
|
| Action | Key | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Move forward | `W` | 4 m/s walk |
|
||||||
|
| Move back | `S` | |
|
||||||
|
| Strafe right | `D` | |
|
||||||
|
| Strafe left | `A` | |
|
||||||
|
| Look | Mouse | Captured on launch; `Escape` releases it |
|
||||||
|
| Jump | `Space` | |
|
||||||
|
| Reset to start | `R` | Returns to the grounded spawn point |
|
||||||
|
| Pause / release mouse | `Escape` | Second press resumes and recaptures the mouse |
|
||||||
|
| Swap first / third person | `V` | First person is the default; the body is hidden in that view |
|
||||||
|
| Show / hide debug overlay | `F3` | FPS, frame time, worst frame, view mode, speed and player position |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Movement is relative to where you are looking (controller yaw), so the capsule stays upright on the sloped street.
|
||||||
|
- The mouse is captured on launch, so looking works without clicking first. `Escape` toggles the capture as part of pause.
|
||||||
|
- Bindings are Enhanced Input actions in `/Game/Input` built by `Tools/ue_create_input_assets.py`; the mapping context is `IMC_Default`.
|
||||||
|
|
||||||
|
## Changes since `0.1.0`
|
||||||
|
|
||||||
|
- **`V` swaps first and third person** (`0.2.0`, `IA_ToggleCamera`). The shipped default view is still first person, as the owner decided for `0.1.0`; third person adds a collision-tested spring-arm camera and a visible, animated body. `Escape` still pauses and releases the mouse in either view.
|
||||||
|
|
||||||
|
## Debug overlay
|
||||||
|
|
||||||
|
`F3` toggles a top-left readout: smoothed **FPS** and frame time, the **worst** frame in a rolling two-second window, the active view (first or third person), player speed, a frame counter, and the player's position in metres from the project origin. The first two seconds of a session are a warm-up window and are excluded from the worst-frame figure, because shader and streaming hitches there made a healthy run read as a 400 ms stall.
|
||||||
|
|
||||||
|
It is **off in the built demo** — a player should not see an FPS counter over Hollywood Boulevard — and **on automatically** when the process is started with `-perf` or `-qaselftest`, so a performance capture never depends on someone pressing a key first. In a running build it can also be forced with the console variable `gigline.Debug 1`.
|
||||||
|
|
||||||
|
Cost: about **5 %** of frame time at 1440p in the demo (2.64 → 2.77 ms average), measured in the same self-test route. The performance release check is recorded without the overlay for that reason; the overlay run is kept beside it as `Docs/perf/0.2.0-walk-frametimes-overlay.csv`.
|
||||||
|
|
||||||
|
## Review and harness switches
|
||||||
|
|
||||||
|
These are command-line switches for the screenshot pipeline and QA runs, not player controls. They exist so a capture is reproducible rather than dependent on a human pressing keys at the right moment.
|
||||||
|
|
||||||
|
| Switch | Effect |
|
||||||
|
| --- | --- |
|
||||||
|
| `-thirdperson` | Starts the pawn in the third-person rig, so a capture shows the body without anyone pressing `V` |
|
||||||
|
| `-walk` | Holds forward input from the first frame — what makes the stride shot possible |
|
||||||
|
| `-qaselftest` | Runs the scripted walk / reset / pause / transect checks and quits; also enables the debug overlay |
|
||||||
|
| `-perf` | Enables the debug overlay for a manual frame-time check |
|
||||||
|
|
||||||
|
The walking shot is driven per shot rather than by the switch: the shot actor enables the walk only while a tracking (`ShotFollow`) camera is being captured, and returns the pawn to spawn afterwards, so the fixed-camera shots still find it in place.
|
||||||
|
|
||||||
|
## Testing input without a physical keyboard
|
||||||
|
|
||||||
|
`Tools/input_test.py` injects OS-level keyboard/mouse events through a virtual `/dev/uinput` device (see `Tools/input_emulation.py`), e.g.:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 Tools/input_test.py --sequence move:2,look:3
|
||||||
|
```
|
||||||
|
|
||||||
|
It drives the focused game window exactly like real hardware, which is how the controls were regression-tested on the packaged build.
|
||||||
@@ -21,6 +21,7 @@ Project-owned documentation is also dedicated under [CC0 1.0](../LICENSE). Third
|
|||||||
## Open decisions
|
## Open decisions
|
||||||
|
|
||||||
- **Reference photography retention.** Decided 2026-11-06: reference images are **not** committed. Licensing is not the gate for local, private development use, so images are simply kept out of the repository (`Art/reference/` is gitignored) and their provenance stays in the local sidecars. The gate moves to the shipped output: if a shipped asset would derive from a reference photograph, that is a release-time licensing decision, recorded in `THIRD_PARTY_NOTICES.md` before the asset ships.
|
- **Reference photography retention.** Decided 2026-11-06: reference images are **not** committed. Licensing is not the gate for local, private development use, so images are simply kept out of the repository (`Art/reference/` is gitignored) and their provenance stays in the local sidecars. The gate moves to the shipped output: if a shipped asset would derive from a reference photograph, that is a release-time licensing decision, recorded in `THIRD_PARTY_NOTICES.md` before the asset ships.
|
||||||
|
- **ODbL posture for OSM-derived geometry.** Decided 2026-11-08: the shipped streets/footprints/sidewalks are a Produced Work of the OpenStreetMap database. Obligations held: on-screen attribution (HUD), ODbL link, and the source extract committed with provenance. Share-alike applies to the data layer only; project code and art stay CC0. Full review in [Docs/odbl-review.md](Docs/odbl-review.md).
|
||||||
|
|
||||||
## Provenance sources
|
## Provenance sources
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# ODbL review — OpenStreetMap-derived data in the shipped build
|
||||||
|
|
||||||
|
Status: **decision recorded 2026-11-08** (closes the TODO "Review ODbL obligations" item).
|
||||||
|
|
||||||
|
## 1. What OSM data the project touches
|
||||||
|
|
||||||
|
| Use | Where it lives | In the shipped build? |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Raw OSM extract (Hollywood block, 2026-11-06) | `Geo/raw/osm-api-map-2026-11-06.osm` (+2 building ways `.json`), committed | No — dev data only, not packed |
|
||||||
|
| Blosm blockout geometry (streets, building footprints, sidewalks) | Crates/site meshes derived from the extract, imported to Unreal | **Yes** — the walkable block geometry derives from OSM layout |
|
||||||
|
| USGS 3DEP DEM elevation | `Geo/raw/dem-3dep-1m-26911-2026-11-06.tif` | Yes — but public domain (US Government work), independent of ODbL |
|
||||||
|
|
||||||
|
So the shipped build contains **buildings, streets and sidewalks whose footprints come from OSM data** (layout geometry). That geometry is a **derivative database/knowledge extract** under the ODbL framing.
|
||||||
|
|
||||||
|
## 2. ODbL obligations (Open Database Licence 1.0)
|
||||||
|
|
||||||
|
ODbL = Open Database Licence (Open Data Commons, version 1.0). The OSM community contract uses it for the OpenStreetMap database.
|
||||||
|
|
||||||
|
Key obligations when you **redistribute or produce a derivative database**:
|
||||||
|
|
||||||
|
1. **Attribution** — credit the database, with a notice visible to users, and provide a link to the licence.
|
||||||
|
2. **Share-alike** — a derivative database (including a "Produced Work" from it) must be offered under ODbL, and changes must be made available.
|
||||||
|
3. **Keep the data open** — do not add technical or legal restrictions that prevent others from using the database under ODbL.
|
||||||
|
4. **No database right / extraction limits** — substantial extraction/use must follow the licence's "extraction and reuse" terms.
|
||||||
|
|
||||||
|
Important nuance: ODbL governs the **database** (the OSM data as a collection and the knowledge it encodes). **Separate creative content** — art, code, models authored by the project — is not a "database" and does not carry the share-alike obligation. The game's own code and artist-authored geometry are project-owned (CC0 per `LICENSE`).
|
||||||
|
|
||||||
|
## 3. Where the project stands
|
||||||
|
|
||||||
|
| Obligation | Held by | Evidence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Attribution in the game | **Yes** — on-screen credit every frame | `AGigLineHUD` draws "© OpenStreetMap contributors" and "Data © OpenStreetMap contributors, ODbL 1.0 — openstreetmap.org/copyright" bottom-left (`GigLineHUD.h` lines 29/33) |
|
||||||
|
| Attribution in the repo | **Yes** — provenance + licence recorded | `THIRD_PARTY_NOTICES.md` Geographic data table; `Geo/manifests/2026-11-06-osm-api-map.md` |
|
||||||
|
| Licence text available | **Yes** — link + notice | HUD link to openstreetmap.org/copyright (ODbL); THIRD_PARTY_NOTICES points at ODbL 1.0 |
|
||||||
|
| Source data available (share-alike enabler) | **Yes** — the exact extract is committed, with bbox/date/hash | `Geo/raw/osm-api-map-2026-11-06.osm` + manifest |
|
||||||
|
| Derivative database offered under ODbL | **Recorded as a decision** — see §4 | This document |
|
||||||
|
|
||||||
|
## 4. Decision: posture for the derived geometry
|
||||||
|
|
||||||
|
The OSM-derived block geometry (streets, footprints, sidewalks) is treated as a **Produced Work / derivative database** of the OpenStreetMap database.
|
||||||
|
|
||||||
|
- The **share-alike obligation is accepted for the data layer only**. The release must carry: (a) the on-screen attribution (implemented), (b) the ODbL link (implemented), and (c) an offer of the OSM source for the geometry — satisfied by the committed raw extract plus its manifest.
|
||||||
|
- **Project creative work (code, shaders, artist-authored façades, textures) is NOT under ODbL.** It remains project-owned CC0 (see `LICENSE`) and carries no share-alike obligation. Only geometry that can be argued to encode OSM database facts (streets, building footprints, sidewalk layouts) is in scope.
|
||||||
|
- **No new obligation is created by the DEM**: 3DEP is US Government public domain and is independent of ODbL.
|
||||||
|
- **Do not** import OSM imagery/panoramas as textures (OSM map tiles or aerial imagery are separately licensed); the project already treats OSM as layout only (`Docs/licensing.md` rule 3).
|
||||||
|
|
||||||
|
Release checklist items this lands:
|
||||||
|
|
||||||
|
- [x] In-game attribution shown (HUD).
|
||||||
|
- [x] ODbL notice + link (HUD + THIRD_PARTY_NOTICES).
|
||||||
|
- [x] Source OSM data committed with provenance (manifest: date, bbox, SHA-256).
|
||||||
|
- [x] Posture recorded here for the release gate.
|
||||||
|
|
||||||
|
## 5. Remaining (tracked separately)
|
||||||
|
|
||||||
|
- **Blosm add-on licence** is still `pending` in THIRD_PARTY_NOTICES (tool-only, not distributed — must be checked once, not a release blocker for ODbL).
|
||||||
|
- Façade signage/trademarks: separate rights from the photograph, own the geometry; not an ODbL question (see THIRD_PARTY_NOTICES "Reference photography" rules).
|
||||||
|
|
||||||
|
## 6. Sources checked
|
||||||
|
|
||||||
|
- ODbL text: <https://opendatacommons.org/licenses/odbl/1-0/>
|
||||||
|
- OSM licence summary: <https://www.openstreetmap.org/copyright>
|
||||||
|
- ISPRS/ODbL practice notes on derived game geometry from OSM footprints (objective standard: attribution + produced-work offer, share-alike limited to the data layer).
|
||||||
|
|
||||||
|
Not reviewed here (out of scope for this item): engine redistribution terms (Epic), MPFB asset terms, street-prop reuse terms — all tracked in `THIRD_PARTY_NOTICES.md`.
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
frame,ms
|
||||||
|
0,2.419
|
||||||
|
1,2.502
|
||||||
|
2,2.360
|
||||||
|
3,2.395
|
||||||
|
4,2.174
|
||||||
|
5,2.539
|
||||||
|
6,2.421
|
||||||
|
7,2.322
|
||||||
|
8,2.455
|
||||||
|
9,2.345
|
||||||
|
10,2.510
|
||||||
|
11,2.076
|
||||||
|
12,2.287
|
||||||
|
13,2.345
|
||||||
|
14,2.398
|
||||||
|
15,2.451
|
||||||
|
16,2.358
|
||||||
|
17,2.303
|
||||||
|
18,2.322
|
||||||
|
19,2.325
|
||||||
|
20,2.370
|
||||||
|
21,2.277
|
||||||
|
22,2.591
|
||||||
|
23,2.312
|
||||||
|
24,2.333
|
||||||
|
25,2.281
|
||||||
|
26,2.453
|
||||||
|
27,2.351
|
||||||
|
28,2.348
|
||||||
|
29,2.452
|
||||||
|
30,2.402
|
||||||
|
31,2.271
|
||||||
|
32,2.314
|
||||||
|
33,2.304
|
||||||
|
34,2.377
|
||||||
|
35,2.443
|
||||||
|
36,2.589
|
||||||
|
37,2.267
|
||||||
|
38,2.554
|
||||||
|
39,2.075
|
||||||
|
40,2.406
|
||||||
|
41,2.395
|
||||||
|
42,2.509
|
||||||
|
43,2.291
|
||||||
|
44,2.370
|
||||||
|
45,2.278
|
||||||
|
46,2.531
|
||||||
|
47,2.289
|
||||||
|
48,2.345
|
||||||
|
49,2.459
|
||||||
|
50,2.495
|
||||||
|
51,2.319
|
||||||
|
52,2.310
|
||||||
|
53,2.528
|
||||||
|
54,2.266
|
||||||
|
55,2.134
|
||||||
|
56,2.413
|
||||||
|
57,2.479
|
||||||
|
58,2.307
|
||||||
|
59,2.343
|
||||||
|
60,2.343
|
||||||
|
61,2.313
|
||||||
|
62,2.317
|
||||||
|
63,2.437
|
||||||
|
64,2.618
|
||||||
|
65,2.316
|
||||||
|
66,2.275
|
||||||
|
67,2.355
|
||||||
|
68,2.496
|
||||||
|
69,3.997
|
||||||
|
70,1.704
|
||||||
|
71,2.353
|
||||||
|
72,2.285
|
||||||
|
73,2.434
|
||||||
|
74,2.389
|
||||||
|
75,2.356
|
||||||
|
76,2.330
|
||||||
|
77,2.531
|
||||||
|
78,2.477
|
||||||
|
79,2.260
|
||||||
|
80,2.493
|
||||||
|
81,2.136
|
||||||
|
82,2.432
|
||||||
|
83,2.324
|
||||||
|
84,2.498
|
||||||
|
85,2.430
|
||||||
|
86,2.364
|
||||||
|
87,2.346
|
||||||
|
88,2.374
|
||||||
|
89,2.370
|
||||||
|
90,2.469
|
||||||
|
91,2.394
|
||||||
|
92,2.653
|
||||||
|
93,2.326
|
||||||
|
94,2.441
|
||||||
|
95,2.285
|
||||||
|
96,2.397
|
||||||
|
97,2.411
|
||||||
|
98,2.333
|
||||||
|
99,2.582
|
||||||
|
100,2.372
|
||||||
|
101,2.375
|
||||||
|
102,2.631
|
||||||
|
103,2.965
|
||||||
|
104,3.026
|
||||||
|
105,2.361
|
||||||
|
106,2.379
|
||||||
|
107,2.281
|
||||||
|
108,2.321
|
||||||
|
109,2.503
|
||||||
|
110,2.532
|
||||||
|
111,2.646
|
||||||
|
112,2.486
|
||||||
|
113,2.462
|
||||||
|
114,2.115
|
||||||
|
115,2.502
|
||||||
|
116,2.149
|
||||||
|
117,2.329
|
||||||
|
118,2.306
|
||||||
|
119,2.578
|
||||||
|
120,2.298
|
||||||
|
121,2.323
|
||||||
|
122,2.318
|
||||||
|
123,2.307
|
||||||
|
124,2.482
|
||||||
|
125,2.383
|
||||||
|
126,2.470
|
||||||
|
127,2.285
|
||||||
|
128,2.392
|
||||||
|
129,2.402
|
||||||
|
130,2.455
|
||||||
|
131,2.296
|
||||||
|
132,2.294
|
||||||
|
133,2.577
|
||||||
|
134,2.288
|
||||||
|
135,2.537
|
||||||
|
136,2.214
|
||||||
|
137,2.279
|
||||||
|
138,2.664
|
||||||
|
139,2.348
|
||||||
|
140,2.444
|
||||||
|
141,2.430
|
||||||
|
142,2.269
|
||||||
|
143,2.317
|
||||||
|
144,2.392
|
||||||
|
145,2.350
|
||||||
|
146,2.333
|
||||||
|
147,2.558
|
||||||
|
148,2.401
|
||||||
|
149,2.335
|
||||||
|
150,2.203
|
||||||
|
151,2.473
|
||||||
|
152,2.471
|
||||||
|
153,2.677
|
||||||
|
154,1.980
|
||||||
|
155,2.721
|
||||||
|
156,2.139
|
||||||
|
157,2.277
|
||||||
|
158,2.348
|
||||||
|
159,2.312
|
||||||
|
160,2.412
|
||||||
|
161,2.498
|
||||||
|
162,2.372
|
||||||
|
163,2.421
|
||||||
|
164,2.249
|
||||||
|
165,2.525
|
||||||
|
166,2.750
|
||||||
|
167,2.465
|
||||||
|
168,2.560
|
||||||
|
169,2.400
|
||||||
|
170,2.310
|
||||||
|
171,2.423
|
||||||
|
172,2.274
|
||||||
|
173,2.482
|
||||||
|
174,2.581
|
||||||
|
175,2.375
|
||||||
|
176,2.285
|
||||||
|
177,2.325
|
||||||
|
178,2.386
|
||||||
|
179,2.379
|
||||||
|
180,2.344
|
||||||
|
181,2.424
|
||||||
|
182,2.635
|
||||||
|
183,2.188
|
||||||
|
184,2.378
|
||||||
|
185,2.258
|
||||||
|
186,2.361
|
||||||
|
187,2.445
|
||||||
|
188,2.280
|
||||||
|
189,2.589
|
||||||
|
190,2.373
|
||||||
|
191,2.349
|
||||||
|
192,2.514
|
||||||
|
193,2.153
|
||||||
|
194,2.271
|
||||||
|
195,2.519
|
||||||
|
196,2.469
|
||||||
|
197,2.509
|
||||||
|
198,2.293
|
||||||
|
199,2.324
|
||||||
|
200,2.317
|
||||||
|
201,2.569
|
||||||
|
202,2.400
|
||||||
|
203,2.527
|
||||||
|
204,2.406
|
||||||
|
205,2.347
|
||||||
|
206,2.361
|
||||||
|
207,2.414
|
||||||
|
208,2.320
|
||||||
|
209,2.481
|
||||||
|
210,2.462
|
||||||
|
211,2.333
|
||||||
|
212,2.306
|
||||||
|
213,2.334
|
||||||
|
214,2.377
|
||||||
|
215,2.447
|
||||||
|
216,2.465
|
||||||
|
217,2.431
|
||||||
|
218,2.304
|
||||||
|
219,2.551
|
||||||
|
220,2.308
|
||||||
|
221,2.373
|
||||||
|
222,2.286
|
||||||
|
223,2.389
|
||||||
|
224,2.524
|
||||||
|
225,2.309
|
||||||
|
226,2.367
|
||||||
|
227,2.358
|
||||||
|
228,2.512
|
||||||
|
229,2.235
|
||||||
|
230,2.320
|
||||||
|
231,2.581
|
||||||
|
232,2.308
|
||||||
|
233,2.410
|
||||||
|
234,2.531
|
||||||
|
235,2.322
|
||||||
|
236,2.585
|
||||||
|
237,2.453
|
||||||
|
238,2.407
|
||||||
|
239,2.279
|
||||||
|
240,2.464
|
||||||
|
241,2.336
|
||||||
|
242,2.282
|
||||||
|
243,2.487
|
||||||
|
244,2.557
|
||||||
|
245,2.214
|
||||||
|
246,2.390
|
||||||
|
247,2.535
|
||||||
|
248,2.234
|
||||||
|
249,2.220
|
||||||
|
250,2.491
|
||||||
|
251,2.446
|
||||||
|
252,2.356
|
||||||
|
253,2.296
|
||||||
|
254,2.502
|
||||||
|
255,2.400
|
||||||
|
256,2.255
|
||||||
|
257,2.592
|
||||||
|
258,2.288
|
||||||
|
259,2.310
|
||||||
|
260,2.443
|
||||||
|
261,2.326
|
||||||
|
262,2.392
|
||||||
|
263,2.414
|
||||||
|
264,2.332
|
||||||
|
265,2.501
|
||||||
|
266,2.381
|
||||||
|
267,2.331
|
||||||
|
268,2.355
|
||||||
|
269,2.331
|
||||||
|
270,2.452
|
||||||
|
271,2.476
|
||||||
|
272,2.625
|
||||||
|
273,2.297
|
||||||
|
274,2.411
|
||||||
|
275,2.254
|
||||||
|
276,2.355
|
||||||
|
277,2.368
|
||||||
|
278,2.416
|
||||||
|
279,2.531
|
||||||
|
280,2.358
|
||||||
|
281,2.349
|
||||||
|
282,2.372
|
||||||
|
283,2.355
|
||||||
|
284,2.388
|
||||||
|
285,2.253
|
||||||
|
286,2.679
|
||||||
|
287,2.415
|
||||||
|
288,2.346
|
||||||
|
289,2.340
|
||||||
|
290,2.390
|
||||||
|
291,2.356
|
||||||
|
292,2.311
|
||||||
|
293,2.582
|
||||||
|
294,2.344
|
||||||
|
295,2.532
|
||||||
|
296,2.309
|
||||||
|
297,2.319
|
||||||
|
298,2.434
|
||||||
|
299,2.413
|
||||||
|
300,2.510
|
||||||
|
301,2.509
|
||||||
|
302,2.441
|
||||||
|
303,2.262
|
||||||
|
304,2.482
|
||||||
|
305,2.397
|
||||||
|
306,2.386
|
||||||
|
307,2.498
|
||||||
|
308,2.409
|
||||||
|
309,2.321
|
||||||
|
310,2.395
|
||||||
|
311,2.927
|
||||||
|
312,2.988
|
||||||
|
313,2.479
|
||||||
|
314,2.328
|
||||||
|
315,2.392
|
||||||
|
316,2.764
|
||||||
|
317,1.912
|
||||||
|
318,2.353
|
||||||
|
319,2.569
|
||||||
|
320,2.505
|
||||||
|
321,2.299
|
||||||
|
322,2.310
|
||||||
|
323,2.414
|
||||||
|
324,2.342
|
||||||
|
325,2.488
|
||||||
|
326,2.365
|
||||||
|
327,2.515
|
||||||
|
328,2.224
|
||||||
|
329,2.466
|
||||||
|
330,2.309
|
||||||
|
331,2.380
|
||||||
|
332,2.319
|
||||||
|
333,2.453
|
||||||
|
334,2.639
|
||||||
|
335,2.300
|
||||||
|
336,2.480
|
||||||
|
337,2.116
|
||||||
|
338,2.343
|
||||||
|
339,2.263
|
||||||
|
340,2.641
|
||||||
|
341,2.473
|
||||||
|
342,2.281
|
||||||
|
343,2.511
|
||||||
|
344,2.300
|
||||||
|
345,2.290
|
||||||
|
346,2.348
|
||||||
|
347,2.306
|
||||||
|
348,2.820
|
||||||
|
349,2.170
|
||||||
|
350,2.425
|
||||||
|
351,2.290
|
||||||
|
352,2.354
|
||||||
|
353,2.256
|
||||||
|
354,2.316
|
||||||
|
355,2.586
|
||||||
|
356,2.308
|
||||||
|
357,2.318
|
||||||
|
358,2.376
|
||||||
|
359,2.364
|
||||||
|
360,2.347
|
||||||
|
361,2.451
|
||||||
|
362,2.297
|
||||||
|
363,2.574
|
||||||
|
364,2.518
|
||||||
|
365,2.191
|
||||||
|
366,2.312
|
||||||
|
367,2.314
|
||||||
|
368,2.421
|
||||||
|
369,2.476
|
||||||
|
370,2.697
|
||||||
|
371,2.183
|
||||||
|
372,2.402
|
||||||
|
373,2.322
|
||||||
|
374,2.690
|
||||||
|
375,3.341
|
||||||
|
376,2.525
|
||||||
|
377,2.423
|
||||||
|
378,2.467
|
||||||
|
379,2.350
|
||||||
|
380,2.235
|
||||||
|
381,3.062
|
||||||
|
382,2.342
|
||||||
|
383,2.556
|
||||||
|
384,2.308
|
||||||
|
385,2.366
|
||||||
|
386,2.396
|
||||||
|
387,2.573
|
||||||
|
388,2.818
|
||||||
|
389,2.460
|
||||||
|
390,2.367
|
||||||
|
391,2.335
|
||||||
|
392,2.323
|
||||||
|
393,2.529
|
||||||
|
394,2.554
|
||||||
|
395,2.758
|
||||||
|
396,2.544
|
||||||
|
397,2.394
|
||||||
|
398,2.332
|
||||||
|
399,2.289
|
||||||
|
400,2.703
|
||||||
|
401,2.451
|
||||||
|
402,2.682
|
||||||
|
403,2.498
|
||||||
|
404,2.500
|
||||||
|
405,2.281
|
||||||
|
406,2.429
|
||||||
|
407,2.493
|
||||||
|
408,2.963
|
||||||
|
409,2.419
|
||||||
|
410,2.304
|
||||||
|
411,2.322
|
||||||
|
412,2.302
|
||||||
|
413,2.604
|
||||||
|
414,2.349
|
||||||
|
415,2.797
|
||||||
|
416,2.552
|
||||||
|
417,2.296
|
||||||
|
418,2.340
|
||||||
|
419,2.585
|
||||||
|
420,2.463
|
||||||
|
421,2.269
|
||||||
|
422,2.782
|
||||||
|
423,2.479
|
||||||
|
424,2.491
|
||||||
|
425,2.206
|
||||||
|
426,2.709
|
||||||
|
427,2.325
|
||||||
|
428,2.589
|
||||||
|
429,2.607
|
||||||
|
430,2.445
|
||||||
|
431,2.410
|
||||||
|
432,2.897
|
||||||
|
433,2.166
|
||||||
|
434,2.247
|
||||||
|
435,2.815
|
||||||
|
436,2.430
|
||||||
|
437,2.368
|
||||||
|
438,2.544
|
||||||
|
439,2.543
|
||||||
|
440,2.277
|
||||||
|
441,2.422
|
||||||
|
442,2.779
|
||||||
|
443,2.530
|
||||||
|
444,2.373
|
||||||
|
445,2.642
|
||||||
|
446,2.475
|
||||||
|
447,2.233
|
||||||
|
448,2.323
|
||||||
|
449,3.161
|
||||||
|
450,2.036
|
||||||
|
451,2.269
|
||||||
|
452,2.700
|
||||||
|
453,2.355
|
||||||
|
454,2.284
|
||||||
|
455,2.931
|
||||||
|
456,2.389
|
||||||
|
457,2.426
|
||||||
|
458,2.341
|
||||||
|
459,2.396
|
||||||
|
460,2.296
|
||||||
|
461,2.438
|
||||||
|
462,2.583
|
||||||
|
463,2.309
|
||||||
|
464,2.647
|
||||||
|
465,2.184
|
||||||
|
466,2.401
|
||||||
|
467,2.276
|
||||||
|
468,2.330
|
||||||
|
469,2.550
|
||||||
|
470,2.469
|
||||||
|
471,2.370
|
||||||
|
472,2.376
|
||||||
|
473,2.483
|
||||||
|
474,2.213
|
||||||
|
475,2.286
|
||||||
|
476,2.339
|
||||||
|
477,2.522
|
||||||
|
478,2.374
|
||||||
|
479,2.354
|
||||||
|
480,2.356
|
||||||
|
481,2.309
|
||||||
|
482,2.523
|
||||||
|
483,2.589
|
||||||
|
484,2.007
|
||||||
|
485,2.830
|
||||||
|
486,2.211
|
||||||
|
487,2.350
|
||||||
|
488,2.338
|
||||||
|
489,2.271
|
||||||
|
490,2.740
|
||||||
|
491,2.495
|
||||||
|
492,2.356
|
||||||
|
493,2.351
|
||||||
|
494,2.355
|
||||||
|
495,2.284
|
||||||
|
496,2.340
|
||||||
|
497,2.367
|
||||||
|
498,2.666
|
||||||
|
499,2.702
|
||||||
|
500,2.653
|
||||||
|
501,1.895
|
||||||
|
502,2.422
|
||||||
|
503,2.288
|
||||||
|
504,2.468
|
||||||
|
505,2.813
|
||||||
|
506,2.235
|
||||||
|
507,2.862
|
||||||
|
508,2.273
|
||||||
|
509,2.495
|
||||||
|
510,2.192
|
||||||
|
511,2.684
|
||||||
|
512,2.679
|
||||||
|
513,2.292
|
||||||
|
514,2.370
|
||||||
|
515,2.447
|
||||||
|
516,2.570
|
||||||
|
517,3.059
|
||||||
|
518,2.939
|
||||||
|
519,2.289
|
||||||
|
520,2.375
|
||||||
|
521,2.357
|
||||||
|
522,2.420
|
||||||
|
523,2.280
|
||||||
|
524,2.570
|
||||||
|
525,2.590
|
||||||
|
526,2.522
|
||||||
|
527,2.200
|
||||||
|
528,2.229
|
||||||
|
529,2.466
|
||||||
|
530,2.722
|
||||||
|
531,2.056
|
||||||
|
532,2.658
|
||||||
|
533,2.298
|
||||||
|
534,2.329
|
||||||
|
535,2.516
|
||||||
|
536,2.205
|
||||||
|
537,2.390
|
||||||
|
538,2.366
|
||||||
|
539,2.439
|
||||||
|
540,2.361
|
||||||
|
541,2.326
|
||||||
|
542,2.376
|
||||||
|
543,2.427
|
||||||
|
544,2.362
|
||||||
|
545,2.336
|
||||||
|
546,2.494
|
||||||
|
547,2.334
|
||||||
|
548,2.319
|
||||||
|
549,2.386
|
||||||
|
550,2.384
|
||||||
|
551,2.273
|
||||||
|
552,2.379
|
||||||
|
553,2.656
|
||||||
|
554,2.264
|
||||||
|
555,2.298
|
||||||
|
556,2.375
|
||||||
|
557,2.378
|
||||||
|
558,2.416
|
||||||
|
559,2.486
|
||||||
|
560,2.395
|
||||||
|
561,2.456
|
||||||
|
562,2.256
|
||||||
|
563,2.282
|
||||||
|
564,2.300
|
||||||
|
565,2.439
|
||||||
|
566,2.439
|
||||||
|
567,2.896
|
||||||
|
568,2.049
|
||||||
|
569,2.322
|
||||||
|
570,2.372
|
||||||
|
571,2.432
|
||||||
|
572,2.295
|
||||||
|
573,2.298
|
||||||
|
574,2.552
|
||||||
|
575,2.365
|
||||||
|
576,2.444
|
||||||
|
577,2.421
|
||||||
|
578,2.704
|
||||||
|
579,2.255
|
||||||
|
580,2.904
|
||||||
|
581,2.389
|
||||||
|
582,2.314
|
||||||
|
583,2.528
|
||||||
|
584,2.223
|
||||||
|
585,2.588
|
||||||
|
586,2.296
|
||||||
|
587,2.282
|
||||||
|
588,2.676
|
||||||
|
589,2.286
|
||||||
|
590,2.390
|
||||||
|
591,2.408
|
||||||
|
592,2.361
|
||||||
|
593,2.404
|
||||||
|
594,2.326
|
||||||
|
595,2.483
|
||||||
|
596,2.412
|
||||||
|
597,2.468
|
||||||
|
598,2.454
|
||||||
|
599,2.245
|
||||||
|
600,2.580
|
||||||
|
601,2.306
|
||||||
|
602,2.496
|
||||||
|
603,2.445
|
||||||
|
604,2.363
|
||||||
|
605,2.316
|
||||||
|
606,2.504
|
||||||
|
607,2.185
|
||||||
|
608,2.649
|
||||||
|
609,2.218
|
||||||
|
610,2.401
|
||||||
|
611,2.494
|
||||||
|
612,2.271
|
||||||
|
613,2.332
|
||||||
|
614,2.296
|
||||||
|
615,2.479
|
||||||
|
616,2.406
|
||||||
|
617,2.377
|
||||||
|
618,2.382
|
||||||
|
619,2.437
|
||||||
|
620,2.222
|
||||||
|
621,2.428
|
||||||
|
622,2.316
|
||||||
|
623,2.569
|
||||||
|
624,2.450
|
||||||
|
625,2.354
|
||||||
|
626,2.305
|
||||||
|
627,2.297
|
||||||
|
628,2.346
|
||||||
|
629,2.435
|
||||||
|
630,2.506
|
||||||
|
631,2.671
|
||||||
|
632,2.185
|
||||||
|
633,2.293
|
||||||
|
634,2.362
|
||||||
|
635,2.552
|
||||||
|
636,2.566
|
||||||
|
637,2.446
|
||||||
|
638,2.304
|
||||||
|
639,2.348
|
||||||
|
640,2.352
|
||||||
|
641,2.357
|
||||||
|
642,2.371
|
||||||
|
643,2.557
|
||||||
|
644,2.339
|
||||||
|
645,2.333
|
||||||
|
646,2.325
|
||||||
|
647,2.420
|
||||||
|
648,2.355
|
||||||
|
649,2.457
|
||||||
|
650,2.512
|
||||||
|
651,2.364
|
||||||
|
652,2.790
|
||||||
|
653,2.245
|
||||||
|
654,2.109
|
||||||
|
655,2.333
|
||||||
|
656,2.338
|
||||||
|
657,2.555
|
||||||
|
658,2.351
|
||||||
|
659,2.486
|
||||||
|
660,2.342
|
||||||
|
661,2.283
|
||||||
|
662,2.240
|
||||||
|
663,2.468
|
||||||
|
664,2.655
|
||||||
|
665,2.314
|
||||||
|
666,2.281
|
||||||
|
667,2.452
|
||||||
|
668,2.320
|
||||||
|
669,2.366
|
||||||
|
670,2.533
|
||||||
|
671,2.590
|
||||||
|
672,2.264
|
||||||
|
673,2.365
|
||||||
|
674,2.354
|
||||||
|
675,2.350
|
||||||
|
676,2.377
|
||||||
|
677,2.627
|
||||||
|
678,2.369
|
||||||
|
679,2.394
|
||||||
|
680,2.389
|
||||||
|
681,2.261
|
||||||
|
682,2.363
|
||||||
|
683,2.400
|
||||||
|
684,2.308
|
||||||
|
685,2.565
|
||||||
|
686,2.394
|
||||||
|
687,2.347
|
||||||
|
688,2.329
|
||||||
|
689,2.369
|
||||||
|
690,2.417
|
||||||
|
691,2.520
|
||||||
|
692,2.222
|
||||||
|
693,2.428
|
||||||
|
694,2.368
|
||||||
|
695,2.390
|
||||||
|
696,2.291
|
||||||
|
697,2.474
|
||||||
|
698,2.309
|
||||||
|
699,2.732
|
||||||
|
700,2.419
|
||||||
|
701,2.291
|
||||||
|
702,2.367
|
||||||
|
703,2.422
|
||||||
|
704,2.476
|
||||||
|
705,2.211
|
||||||
|
706,2.560
|
||||||
|
707,2.351
|
||||||
|
708,2.350
|
||||||
|
709,2.352
|
||||||
|
710,2.284
|
||||||
|
711,2.377
|
||||||
|
712,2.393
|
||||||
|
713,2.682
|
||||||
|
714,2.155
|
||||||
|
715,2.364
|
||||||
|
716,2.369
|
||||||
|
717,2.345
|
||||||
|
718,2.338
|
||||||
|
719,2.379
|
||||||
|
720,2.601
|
||||||
|
721,2.433
|
||||||
|
722,2.513
|
||||||
|
723,2.496
|
||||||
|
724,2.967
|
||||||
|
725,2.579
|
||||||
|
726,2.513
|
||||||
|
727,2.497
|
||||||
|
728,2.268
|
||||||
|
729,2.610
|
||||||
|
730,2.122
|
||||||
|
731,2.441
|
||||||
|
732,2.628
|
||||||
|
733,2.468
|
||||||
|
734,2.228
|
||||||
|
735,2.377
|
||||||
|
736,2.401
|
||||||
|
737,2.267
|
||||||
|
738,2.391
|
||||||
|
739,2.624
|
||||||
|
740,2.467
|
||||||
|
741,2.334
|
||||||
|
742,2.281
|
||||||
|
743,2.385
|
||||||
|
744,2.297
|
||||||
|
745,2.432
|
||||||
|
746,2.300
|
||||||
|
747,2.591
|
||||||
|
748,2.408
|
||||||
|
749,2.330
|
||||||
|
750,2.275
|
||||||
|
751,2.374
|
||||||
|
752,2.385
|
||||||
|
753,2.336
|
||||||
|
754,2.628
|
||||||
|
755,2.263
|
||||||
|
756,2.397
|
||||||
|
757,2.431
|
||||||
|
758,2.387
|
||||||
|
759,2.326
|
||||||
|
760,2.398
|
||||||
|
761,2.554
|
||||||
|
762,2.389
|
||||||
|
763,2.310
|
||||||
|
764,2.465
|
||||||
|
765,2.402
|
||||||
|
766,2.263
|
||||||
|
767,2.688
|
||||||
|
768,2.262
|
||||||
|
769,2.439
|
||||||
|
770,2.164
|
||||||
|
771,2.312
|
||||||
|
772,2.342
|
||||||
|
773,2.395
|
||||||
|
774,2.322
|
||||||
|
775,2.617
|
||||||
|
776,2.289
|
||||||
|
777,2.343
|
||||||
|
778,2.333
|
||||||
|
779,2.348
|
||||||
|
780,2.497
|
||||||
|
781,2.299
|
||||||
|
782,2.589
|
||||||
|
783,2.358
|
||||||
|
784,2.442
|
||||||
|
785,2.235
|
||||||
|
786,2.716
|
||||||
|
787,2.350
|
||||||
|
788,2.839
|
||||||
|
789,2.490
|
||||||
|
790,2.439
|
||||||
|
791,2.438
|
||||||
|
792,2.464
|
||||||
|
793,2.527
|
||||||
|
794,2.897
|
||||||
|
795,1.939
|
||||||
|
796,2.509
|
||||||
|
797,3.275
|
||||||
|
798,2.123
|
||||||
|
799,2.300
|
||||||
|
800,2.425
|
||||||
|
801,2.699
|
||||||
|
802,2.275
|
||||||
|
803,2.523
|
||||||
|
804,2.232
|
||||||
|
805,3.105
|
||||||
|
806,2.195
|
||||||
|
807,2.389
|
||||||
|
808,2.264
|
||||||
|
809,2.813
|
||||||
|
810,2.257
|
||||||
|
811,2.300
|
||||||
|
812,2.543
|
||||||
|
813,2.283
|
||||||
|
814,2.533
|
||||||
|
815,2.308
|
||||||
|
816,2.481
|
||||||
|
817,2.374
|
||||||
|
818,2.504
|
||||||
|
819,3.008
|
||||||
|
820,2.266
|
||||||
|
821,2.351
|
||||||
|
822,2.459
|
||||||
|
823,2.748
|
||||||
|
824,2.512
|
||||||
|
825,2.257
|
||||||
|
826,2.434
|
||||||
|
827,2.430
|
||||||
|
828,2.253
|
||||||
|
@@ -0,0 +1,728 @@
|
|||||||
|
frame,ms
|
||||||
|
0,2.599
|
||||||
|
1,2.877
|
||||||
|
2,2.709
|
||||||
|
3,2.646
|
||||||
|
4,3.168
|
||||||
|
5,2.729
|
||||||
|
6,2.524
|
||||||
|
7,2.726
|
||||||
|
8,2.639
|
||||||
|
9,2.814
|
||||||
|
10,2.819
|
||||||
|
11,2.708
|
||||||
|
12,2.822
|
||||||
|
13,2.703
|
||||||
|
14,2.365
|
||||||
|
15,2.796
|
||||||
|
16,2.899
|
||||||
|
17,2.972
|
||||||
|
18,2.908
|
||||||
|
19,2.356
|
||||||
|
20,2.781
|
||||||
|
21,2.574
|
||||||
|
22,3.148
|
||||||
|
23,2.306
|
||||||
|
24,2.668
|
||||||
|
25,2.855
|
||||||
|
26,2.588
|
||||||
|
27,3.321
|
||||||
|
28,3.419
|
||||||
|
29,3.121
|
||||||
|
30,3.391
|
||||||
|
31,2.355
|
||||||
|
32,2.679
|
||||||
|
33,3.463
|
||||||
|
34,2.614
|
||||||
|
35,2.922
|
||||||
|
36,2.429
|
||||||
|
37,2.830
|
||||||
|
38,2.842
|
||||||
|
39,2.782
|
||||||
|
40,3.252
|
||||||
|
41,2.731
|
||||||
|
42,2.577
|
||||||
|
43,2.363
|
||||||
|
44,2.786
|
||||||
|
45,2.547
|
||||||
|
46,2.594
|
||||||
|
47,2.652
|
||||||
|
48,2.836
|
||||||
|
49,2.792
|
||||||
|
50,2.552
|
||||||
|
51,2.792
|
||||||
|
52,2.718
|
||||||
|
53,3.333
|
||||||
|
54,2.165
|
||||||
|
55,2.880
|
||||||
|
56,2.613
|
||||||
|
57,2.460
|
||||||
|
58,2.919
|
||||||
|
59,2.770
|
||||||
|
60,2.551
|
||||||
|
61,2.622
|
||||||
|
62,2.712
|
||||||
|
63,2.818
|
||||||
|
64,3.155
|
||||||
|
65,2.472
|
||||||
|
66,2.861
|
||||||
|
67,2.651
|
||||||
|
68,2.573
|
||||||
|
69,2.892
|
||||||
|
70,2.689
|
||||||
|
71,2.729
|
||||||
|
72,2.668
|
||||||
|
73,2.753
|
||||||
|
74,2.812
|
||||||
|
75,2.606
|
||||||
|
76,2.686
|
||||||
|
77,2.842
|
||||||
|
78,2.660
|
||||||
|
79,2.903
|
||||||
|
80,2.486
|
||||||
|
81,2.591
|
||||||
|
82,3.626
|
||||||
|
83,2.455
|
||||||
|
84,2.475
|
||||||
|
85,2.922
|
||||||
|
86,2.603
|
||||||
|
87,2.728
|
||||||
|
88,3.057
|
||||||
|
89,2.731
|
||||||
|
90,3.632
|
||||||
|
91,1.950
|
||||||
|
92,2.694
|
||||||
|
93,3.020
|
||||||
|
94,2.230
|
||||||
|
95,2.796
|
||||||
|
96,2.707
|
||||||
|
97,2.807
|
||||||
|
98,2.658
|
||||||
|
99,2.697
|
||||||
|
100,2.453
|
||||||
|
101,3.051
|
||||||
|
102,2.758
|
||||||
|
103,2.662
|
||||||
|
104,2.599
|
||||||
|
105,2.733
|
||||||
|
106,2.751
|
||||||
|
107,2.894
|
||||||
|
108,2.501
|
||||||
|
109,2.753
|
||||||
|
110,2.873
|
||||||
|
111,2.439
|
||||||
|
112,2.634
|
||||||
|
113,2.682
|
||||||
|
114,2.913
|
||||||
|
115,2.692
|
||||||
|
116,2.735
|
||||||
|
117,2.758
|
||||||
|
118,2.726
|
||||||
|
119,2.907
|
||||||
|
120,2.568
|
||||||
|
121,2.764
|
||||||
|
122,2.815
|
||||||
|
123,2.530
|
||||||
|
124,2.684
|
||||||
|
125,2.719
|
||||||
|
126,2.846
|
||||||
|
127,2.879
|
||||||
|
128,2.647
|
||||||
|
129,2.770
|
||||||
|
130,2.477
|
||||||
|
131,2.657
|
||||||
|
132,2.675
|
||||||
|
133,2.917
|
||||||
|
134,2.700
|
||||||
|
135,2.493
|
||||||
|
136,2.678
|
||||||
|
137,2.786
|
||||||
|
138,3.004
|
||||||
|
139,2.697
|
||||||
|
140,2.642
|
||||||
|
141,2.624
|
||||||
|
142,2.684
|
||||||
|
143,2.717
|
||||||
|
144,2.743
|
||||||
|
145,2.740
|
||||||
|
146,2.825
|
||||||
|
147,2.849
|
||||||
|
148,2.991
|
||||||
|
149,2.297
|
||||||
|
150,3.084
|
||||||
|
151,2.459
|
||||||
|
152,3.214
|
||||||
|
153,2.260
|
||||||
|
154,2.550
|
||||||
|
155,2.621
|
||||||
|
156,2.660
|
||||||
|
157,2.739
|
||||||
|
158,2.574
|
||||||
|
159,3.078
|
||||||
|
160,2.735
|
||||||
|
161,2.607
|
||||||
|
162,2.793
|
||||||
|
163,2.798
|
||||||
|
164,2.584
|
||||||
|
165,2.637
|
||||||
|
166,2.627
|
||||||
|
167,2.726
|
||||||
|
168,2.656
|
||||||
|
169,2.788
|
||||||
|
170,2.674
|
||||||
|
171,2.782
|
||||||
|
172,2.766
|
||||||
|
173,2.613
|
||||||
|
174,2.724
|
||||||
|
175,2.770
|
||||||
|
176,2.709
|
||||||
|
177,2.700
|
||||||
|
178,2.600
|
||||||
|
179,2.686
|
||||||
|
180,2.747
|
||||||
|
181,2.841
|
||||||
|
182,2.601
|
||||||
|
183,2.666
|
||||||
|
184,2.846
|
||||||
|
185,2.599
|
||||||
|
186,2.806
|
||||||
|
187,3.126
|
||||||
|
188,2.521
|
||||||
|
189,2.634
|
||||||
|
190,2.716
|
||||||
|
191,2.584
|
||||||
|
192,2.714
|
||||||
|
193,2.923
|
||||||
|
194,2.277
|
||||||
|
195,2.706
|
||||||
|
196,2.606
|
||||||
|
197,2.758
|
||||||
|
198,2.747
|
||||||
|
199,2.958
|
||||||
|
200,2.798
|
||||||
|
201,2.387
|
||||||
|
202,2.596
|
||||||
|
203,2.861
|
||||||
|
204,2.801
|
||||||
|
205,2.521
|
||||||
|
206,2.869
|
||||||
|
207,2.884
|
||||||
|
208,2.515
|
||||||
|
209,2.592
|
||||||
|
210,3.723
|
||||||
|
211,2.474
|
||||||
|
212,2.736
|
||||||
|
213,2.774
|
||||||
|
214,2.769
|
||||||
|
215,3.007
|
||||||
|
216,2.768
|
||||||
|
217,2.716
|
||||||
|
218,2.694
|
||||||
|
219,2.722
|
||||||
|
220,2.862
|
||||||
|
221,2.587
|
||||||
|
222,2.833
|
||||||
|
223,2.792
|
||||||
|
224,2.746
|
||||||
|
225,2.585
|
||||||
|
226,2.741
|
||||||
|
227,2.585
|
||||||
|
228,2.802
|
||||||
|
229,2.674
|
||||||
|
230,2.742
|
||||||
|
231,2.718
|
||||||
|
232,2.881
|
||||||
|
233,2.707
|
||||||
|
234,2.585
|
||||||
|
235,2.810
|
||||||
|
236,2.948
|
||||||
|
237,2.718
|
||||||
|
238,2.773
|
||||||
|
239,2.571
|
||||||
|
240,2.788
|
||||||
|
241,2.702
|
||||||
|
242,2.634
|
||||||
|
243,2.788
|
||||||
|
244,2.678
|
||||||
|
245,2.914
|
||||||
|
246,2.527
|
||||||
|
247,2.637
|
||||||
|
248,2.877
|
||||||
|
249,2.693
|
||||||
|
250,2.644
|
||||||
|
251,2.670
|
||||||
|
252,2.700
|
||||||
|
253,2.877
|
||||||
|
254,2.638
|
||||||
|
255,2.617
|
||||||
|
256,2.774
|
||||||
|
257,2.660
|
||||||
|
258,2.731
|
||||||
|
259,2.671
|
||||||
|
260,2.838
|
||||||
|
261,2.726
|
||||||
|
262,2.671
|
||||||
|
263,2.744
|
||||||
|
264,2.735
|
||||||
|
265,2.684
|
||||||
|
266,3.850
|
||||||
|
267,2.120
|
||||||
|
268,2.669
|
||||||
|
269,2.729
|
||||||
|
270,2.712
|
||||||
|
271,2.817
|
||||||
|
272,2.926
|
||||||
|
273,2.678
|
||||||
|
274,2.786
|
||||||
|
275,2.927
|
||||||
|
276,2.493
|
||||||
|
277,2.846
|
||||||
|
278,2.610
|
||||||
|
279,2.644
|
||||||
|
280,2.577
|
||||||
|
281,2.939
|
||||||
|
282,2.727
|
||||||
|
283,2.595
|
||||||
|
284,2.819
|
||||||
|
285,2.778
|
||||||
|
286,2.774
|
||||||
|
287,2.628
|
||||||
|
288,2.711
|
||||||
|
289,2.699
|
||||||
|
290,2.715
|
||||||
|
291,2.763
|
||||||
|
292,2.710
|
||||||
|
293,2.892
|
||||||
|
294,2.721
|
||||||
|
295,2.575
|
||||||
|
296,3.608
|
||||||
|
297,2.811
|
||||||
|
298,2.739
|
||||||
|
299,2.751
|
||||||
|
300,2.608
|
||||||
|
301,2.913
|
||||||
|
302,3.052
|
||||||
|
303,2.862
|
||||||
|
304,2.653
|
||||||
|
305,2.727
|
||||||
|
306,2.646
|
||||||
|
307,2.888
|
||||||
|
308,3.338
|
||||||
|
309,2.743
|
||||||
|
310,2.639
|
||||||
|
311,2.681
|
||||||
|
312,2.846
|
||||||
|
313,2.766
|
||||||
|
314,3.184
|
||||||
|
315,2.834
|
||||||
|
316,2.728
|
||||||
|
317,2.581
|
||||||
|
318,2.770
|
||||||
|
319,3.351
|
||||||
|
320,3.157
|
||||||
|
321,2.508
|
||||||
|
322,2.835
|
||||||
|
323,2.754
|
||||||
|
324,2.411
|
||||||
|
325,3.398
|
||||||
|
326,2.802
|
||||||
|
327,2.611
|
||||||
|
328,3.058
|
||||||
|
329,2.407
|
||||||
|
330,2.640
|
||||||
|
331,3.645
|
||||||
|
332,2.729
|
||||||
|
333,2.580
|
||||||
|
334,2.902
|
||||||
|
335,2.523
|
||||||
|
336,3.005
|
||||||
|
337,3.173
|
||||||
|
338,2.840
|
||||||
|
339,2.610
|
||||||
|
340,2.576
|
||||||
|
341,2.706
|
||||||
|
342,3.405
|
||||||
|
343,2.849
|
||||||
|
344,2.678
|
||||||
|
345,2.796
|
||||||
|
346,2.782
|
||||||
|
347,2.636
|
||||||
|
348,3.475
|
||||||
|
349,2.798
|
||||||
|
350,2.745
|
||||||
|
351,2.564
|
||||||
|
352,2.792
|
||||||
|
353,2.714
|
||||||
|
354,3.496
|
||||||
|
355,2.841
|
||||||
|
356,2.465
|
||||||
|
357,2.708
|
||||||
|
358,2.692
|
||||||
|
359,2.934
|
||||||
|
360,3.304
|
||||||
|
361,2.561
|
||||||
|
362,2.689
|
||||||
|
363,2.749
|
||||||
|
364,2.780
|
||||||
|
365,2.940
|
||||||
|
366,3.025
|
||||||
|
367,2.706
|
||||||
|
368,2.881
|
||||||
|
369,2.619
|
||||||
|
370,2.716
|
||||||
|
371,3.133
|
||||||
|
372,2.874
|
||||||
|
373,2.816
|
||||||
|
374,2.414
|
||||||
|
375,2.737
|
||||||
|
376,2.797
|
||||||
|
377,2.651
|
||||||
|
378,2.920
|
||||||
|
379,3.032
|
||||||
|
380,2.606
|
||||||
|
381,2.710
|
||||||
|
382,2.649
|
||||||
|
383,2.700
|
||||||
|
384,3.469
|
||||||
|
385,2.224
|
||||||
|
386,2.567
|
||||||
|
387,2.733
|
||||||
|
388,2.511
|
||||||
|
389,2.950
|
||||||
|
390,3.979
|
||||||
|
391,2.798
|
||||||
|
392,2.487
|
||||||
|
393,2.740
|
||||||
|
394,2.741
|
||||||
|
395,2.718
|
||||||
|
396,3.291
|
||||||
|
397,2.769
|
||||||
|
398,2.697
|
||||||
|
399,2.796
|
||||||
|
400,2.641
|
||||||
|
401,2.652
|
||||||
|
402,3.151
|
||||||
|
403,2.673
|
||||||
|
404,2.741
|
||||||
|
405,2.606
|
||||||
|
406,2.665
|
||||||
|
407,2.859
|
||||||
|
408,2.739
|
||||||
|
409,2.586
|
||||||
|
410,2.910
|
||||||
|
411,2.745
|
||||||
|
412,2.698
|
||||||
|
413,2.670
|
||||||
|
414,2.797
|
||||||
|
415,2.829
|
||||||
|
416,2.643
|
||||||
|
417,2.776
|
||||||
|
418,2.772
|
||||||
|
419,2.530
|
||||||
|
420,2.567
|
||||||
|
421,2.826
|
||||||
|
422,2.782
|
||||||
|
423,2.738
|
||||||
|
424,2.640
|
||||||
|
425,2.967
|
||||||
|
426,2.600
|
||||||
|
427,3.020
|
||||||
|
428,2.502
|
||||||
|
429,2.642
|
||||||
|
430,2.625
|
||||||
|
431,2.770
|
||||||
|
432,2.659
|
||||||
|
433,2.717
|
||||||
|
434,2.698
|
||||||
|
435,2.780
|
||||||
|
436,2.992
|
||||||
|
437,2.686
|
||||||
|
438,2.560
|
||||||
|
439,3.048
|
||||||
|
440,2.721
|
||||||
|
441,2.507
|
||||||
|
442,2.694
|
||||||
|
443,2.695
|
||||||
|
444,2.892
|
||||||
|
445,3.443
|
||||||
|
446,2.633
|
||||||
|
447,2.908
|
||||||
|
448,2.823
|
||||||
|
449,2.346
|
||||||
|
450,2.599
|
||||||
|
451,2.914
|
||||||
|
452,2.774
|
||||||
|
453,3.391
|
||||||
|
454,2.384
|
||||||
|
455,2.585
|
||||||
|
456,2.667
|
||||||
|
457,2.704
|
||||||
|
458,2.674
|
||||||
|
459,2.755
|
||||||
|
460,2.718
|
||||||
|
461,2.804
|
||||||
|
462,2.583
|
||||||
|
463,2.694
|
||||||
|
464,2.797
|
||||||
|
465,3.079
|
||||||
|
466,2.434
|
||||||
|
467,2.723
|
||||||
|
468,3.671
|
||||||
|
469,2.211
|
||||||
|
470,2.567
|
||||||
|
471,2.701
|
||||||
|
472,2.717
|
||||||
|
473,2.657
|
||||||
|
474,2.581
|
||||||
|
475,2.889
|
||||||
|
476,3.006
|
||||||
|
477,2.595
|
||||||
|
478,2.703
|
||||||
|
479,2.498
|
||||||
|
480,2.694
|
||||||
|
481,2.915
|
||||||
|
482,2.655
|
||||||
|
483,2.686
|
||||||
|
484,2.833
|
||||||
|
485,2.717
|
||||||
|
486,2.723
|
||||||
|
487,2.451
|
||||||
|
488,2.913
|
||||||
|
489,2.784
|
||||||
|
490,2.684
|
||||||
|
491,2.651
|
||||||
|
492,2.809
|
||||||
|
493,2.819
|
||||||
|
494,2.676
|
||||||
|
495,2.851
|
||||||
|
496,2.775
|
||||||
|
497,2.638
|
||||||
|
498,2.520
|
||||||
|
499,2.824
|
||||||
|
500,2.930
|
||||||
|
501,2.757
|
||||||
|
502,2.608
|
||||||
|
503,2.808
|
||||||
|
504,2.508
|
||||||
|
505,2.819
|
||||||
|
506,2.654
|
||||||
|
507,2.748
|
||||||
|
508,2.705
|
||||||
|
509,2.798
|
||||||
|
510,2.559
|
||||||
|
511,2.694
|
||||||
|
512,2.821
|
||||||
|
513,2.706
|
||||||
|
514,2.612
|
||||||
|
515,2.928
|
||||||
|
516,2.475
|
||||||
|
517,2.830
|
||||||
|
518,2.658
|
||||||
|
519,2.784
|
||||||
|
520,2.572
|
||||||
|
521,2.935
|
||||||
|
522,2.688
|
||||||
|
523,2.600
|
||||||
|
524,2.675
|
||||||
|
525,2.828
|
||||||
|
526,2.774
|
||||||
|
527,2.848
|
||||||
|
528,2.764
|
||||||
|
529,2.379
|
||||||
|
530,2.962
|
||||||
|
531,2.989
|
||||||
|
532,2.528
|
||||||
|
533,2.639
|
||||||
|
534,2.906
|
||||||
|
535,2.543
|
||||||
|
536,2.582
|
||||||
|
537,2.949
|
||||||
|
538,2.813
|
||||||
|
539,2.504
|
||||||
|
540,2.754
|
||||||
|
541,2.638
|
||||||
|
542,2.695
|
||||||
|
543,2.662
|
||||||
|
544,2.922
|
||||||
|
545,2.616
|
||||||
|
546,2.810
|
||||||
|
547,2.675
|
||||||
|
548,2.551
|
||||||
|
549,2.894
|
||||||
|
550,2.754
|
||||||
|
551,2.632
|
||||||
|
552,2.748
|
||||||
|
553,2.827
|
||||||
|
554,2.751
|
||||||
|
555,2.759
|
||||||
|
556,2.684
|
||||||
|
557,2.766
|
||||||
|
558,2.948
|
||||||
|
559,2.461
|
||||||
|
560,2.621
|
||||||
|
561,2.772
|
||||||
|
562,2.985
|
||||||
|
563,2.582
|
||||||
|
564,2.897
|
||||||
|
565,2.574
|
||||||
|
566,2.661
|
||||||
|
567,2.742
|
||||||
|
568,2.797
|
||||||
|
569,2.632
|
||||||
|
570,2.755
|
||||||
|
571,2.878
|
||||||
|
572,2.759
|
||||||
|
573,3.812
|
||||||
|
574,2.651
|
||||||
|
575,2.862
|
||||||
|
576,2.577
|
||||||
|
577,2.634
|
||||||
|
578,3.173
|
||||||
|
579,2.418
|
||||||
|
580,2.714
|
||||||
|
581,2.746
|
||||||
|
582,2.794
|
||||||
|
583,2.774
|
||||||
|
584,2.583
|
||||||
|
585,3.659
|
||||||
|
586,3.222
|
||||||
|
587,2.489
|
||||||
|
588,2.868
|
||||||
|
589,2.558
|
||||||
|
590,2.586
|
||||||
|
591,2.599
|
||||||
|
592,2.930
|
||||||
|
593,2.401
|
||||||
|
594,2.540
|
||||||
|
595,2.889
|
||||||
|
596,2.733
|
||||||
|
597,2.664
|
||||||
|
598,2.877
|
||||||
|
599,2.588
|
||||||
|
600,2.677
|
||||||
|
601,2.897
|
||||||
|
602,2.672
|
||||||
|
603,2.780
|
||||||
|
604,2.740
|
||||||
|
605,2.780
|
||||||
|
606,2.493
|
||||||
|
607,2.794
|
||||||
|
608,2.631
|
||||||
|
609,2.768
|
||||||
|
610,2.870
|
||||||
|
611,2.626
|
||||||
|
612,2.862
|
||||||
|
613,2.602
|
||||||
|
614,2.868
|
||||||
|
615,2.627
|
||||||
|
616,2.638
|
||||||
|
617,2.702
|
||||||
|
618,2.904
|
||||||
|
619,2.918
|
||||||
|
620,2.487
|
||||||
|
621,3.225
|
||||||
|
622,2.350
|
||||||
|
623,2.820
|
||||||
|
624,2.837
|
||||||
|
625,2.408
|
||||||
|
626,2.593
|
||||||
|
627,3.526
|
||||||
|
628,2.554
|
||||||
|
629,2.746
|
||||||
|
630,2.684
|
||||||
|
631,2.729
|
||||||
|
632,2.762
|
||||||
|
633,2.768
|
||||||
|
634,3.034
|
||||||
|
635,2.514
|
||||||
|
636,2.732
|
||||||
|
637,2.739
|
||||||
|
638,2.692
|
||||||
|
639,2.832
|
||||||
|
640,2.810
|
||||||
|
641,2.484
|
||||||
|
642,2.632
|
||||||
|
643,3.284
|
||||||
|
644,2.311
|
||||||
|
645,3.079
|
||||||
|
646,2.656
|
||||||
|
647,2.683
|
||||||
|
648,2.622
|
||||||
|
649,2.668
|
||||||
|
650,2.779
|
||||||
|
651,2.796
|
||||||
|
652,2.874
|
||||||
|
653,2.427
|
||||||
|
654,2.644
|
||||||
|
655,2.872
|
||||||
|
656,2.867
|
||||||
|
657,2.404
|
||||||
|
658,2.917
|
||||||
|
659,2.773
|
||||||
|
660,2.857
|
||||||
|
661,2.789
|
||||||
|
662,2.443
|
||||||
|
663,2.651
|
||||||
|
664,2.839
|
||||||
|
665,2.814
|
||||||
|
666,2.575
|
||||||
|
667,2.796
|
||||||
|
668,2.709
|
||||||
|
669,2.873
|
||||||
|
670,2.670
|
||||||
|
671,2.936
|
||||||
|
672,2.496
|
||||||
|
673,2.608
|
||||||
|
674,2.641
|
||||||
|
675,2.793
|
||||||
|
676,2.765
|
||||||
|
677,2.736
|
||||||
|
678,2.679
|
||||||
|
679,2.987
|
||||||
|
680,2.884
|
||||||
|
681,2.469
|
||||||
|
682,2.774
|
||||||
|
683,2.948
|
||||||
|
684,2.598
|
||||||
|
685,3.478
|
||||||
|
686,2.856
|
||||||
|
687,4.623
|
||||||
|
688,3.038
|
||||||
|
689,2.507
|
||||||
|
690,2.717
|
||||||
|
691,2.682
|
||||||
|
692,2.807
|
||||||
|
693,2.778
|
||||||
|
694,2.699
|
||||||
|
695,2.802
|
||||||
|
696,2.605
|
||||||
|
697,2.650
|
||||||
|
698,2.789
|
||||||
|
699,2.791
|
||||||
|
700,3.015
|
||||||
|
701,2.539
|
||||||
|
702,2.790
|
||||||
|
703,2.698
|
||||||
|
704,2.637
|
||||||
|
705,2.657
|
||||||
|
706,2.800
|
||||||
|
707,2.720
|
||||||
|
708,2.702
|
||||||
|
709,2.845
|
||||||
|
710,2.583
|
||||||
|
711,2.780
|
||||||
|
712,2.782
|
||||||
|
713,2.593
|
||||||
|
714,2.695
|
||||||
|
715,2.747
|
||||||
|
716,2.871
|
||||||
|
717,2.671
|
||||||
|
718,2.676
|
||||||
|
719,2.991
|
||||||
|
720,2.727
|
||||||
|
721,2.576
|
||||||
|
722,2.539
|
||||||
|
723,2.770
|
||||||
|
724,2.712
|
||||||
|
725,2.818
|
||||||
|
726,2.615
|
||||||
|
@@ -0,0 +1,723 @@
|
|||||||
|
frame,ms
|
||||||
|
0,2.607
|
||||||
|
1,2.532
|
||||||
|
2,2.324
|
||||||
|
3,3.432
|
||||||
|
4,2.808
|
||||||
|
5,2.870
|
||||||
|
6,2.367
|
||||||
|
7,2.311
|
||||||
|
8,2.756
|
||||||
|
9,3.278
|
||||||
|
10,2.418
|
||||||
|
11,2.665
|
||||||
|
12,2.438
|
||||||
|
13,2.646
|
||||||
|
14,2.461
|
||||||
|
15,2.941
|
||||||
|
16,2.975
|
||||||
|
17,3.164
|
||||||
|
18,2.766
|
||||||
|
19,2.341
|
||||||
|
20,2.543
|
||||||
|
21,3.395
|
||||||
|
22,2.772
|
||||||
|
23,2.575
|
||||||
|
24,2.737
|
||||||
|
25,2.427
|
||||||
|
26,2.538
|
||||||
|
27,2.708
|
||||||
|
28,3.183
|
||||||
|
29,2.734
|
||||||
|
30,2.425
|
||||||
|
31,2.546
|
||||||
|
32,2.600
|
||||||
|
33,2.545
|
||||||
|
34,3.705
|
||||||
|
35,2.563
|
||||||
|
36,2.907
|
||||||
|
37,2.368
|
||||||
|
38,2.470
|
||||||
|
39,2.411
|
||||||
|
40,3.778
|
||||||
|
41,3.735
|
||||||
|
42,2.292
|
||||||
|
43,2.458
|
||||||
|
44,2.566
|
||||||
|
45,3.044
|
||||||
|
46,3.449
|
||||||
|
47,2.914
|
||||||
|
48,3.243
|
||||||
|
49,2.084
|
||||||
|
50,3.872
|
||||||
|
51,1.633
|
||||||
|
52,3.389
|
||||||
|
53,2.448
|
||||||
|
54,2.474
|
||||||
|
55,2.509
|
||||||
|
56,2.346
|
||||||
|
57,3.192
|
||||||
|
58,2.762
|
||||||
|
59,2.788
|
||||||
|
60,2.538
|
||||||
|
61,2.520
|
||||||
|
62,2.517
|
||||||
|
63,3.036
|
||||||
|
64,3.205
|
||||||
|
65,3.080
|
||||||
|
66,2.514
|
||||||
|
67,2.429
|
||||||
|
68,2.515
|
||||||
|
69,2.963
|
||||||
|
70,3.555
|
||||||
|
71,2.430
|
||||||
|
72,2.742
|
||||||
|
73,2.435
|
||||||
|
74,2.526
|
||||||
|
75,3.304
|
||||||
|
76,3.511
|
||||||
|
77,2.477
|
||||||
|
78,2.472
|
||||||
|
79,2.452
|
||||||
|
80,2.421
|
||||||
|
81,3.334
|
||||||
|
82,3.286
|
||||||
|
83,2.725
|
||||||
|
84,2.411
|
||||||
|
85,2.597
|
||||||
|
86,2.440
|
||||||
|
87,3.213
|
||||||
|
88,3.411
|
||||||
|
89,3.047
|
||||||
|
90,2.365
|
||||||
|
91,2.530
|
||||||
|
92,2.877
|
||||||
|
93,3.249
|
||||||
|
94,3.186
|
||||||
|
95,2.684
|
||||||
|
96,2.304
|
||||||
|
97,2.406
|
||||||
|
98,2.948
|
||||||
|
99,3.652
|
||||||
|
100,2.822
|
||||||
|
101,2.552
|
||||||
|
102,2.575
|
||||||
|
103,2.354
|
||||||
|
104,2.676
|
||||||
|
105,2.775
|
||||||
|
106,3.865
|
||||||
|
107,2.480
|
||||||
|
108,2.501
|
||||||
|
109,2.675
|
||||||
|
110,2.724
|
||||||
|
111,3.671
|
||||||
|
112,2.828
|
||||||
|
113,3.064
|
||||||
|
114,2.153
|
||||||
|
115,2.752
|
||||||
|
116,2.936
|
||||||
|
117,3.008
|
||||||
|
118,2.932
|
||||||
|
119,2.648
|
||||||
|
120,2.441
|
||||||
|
121,3.471
|
||||||
|
122,1.885
|
||||||
|
123,4.435
|
||||||
|
124,2.504
|
||||||
|
125,3.241
|
||||||
|
126,2.813
|
||||||
|
127,2.445
|
||||||
|
128,3.321
|
||||||
|
129,3.055
|
||||||
|
130,3.222
|
||||||
|
131,2.766
|
||||||
|
132,2.582
|
||||||
|
133,2.597
|
||||||
|
134,3.637
|
||||||
|
135,3.150
|
||||||
|
136,3.163
|
||||||
|
137,2.675
|
||||||
|
138,2.708
|
||||||
|
139,2.581
|
||||||
|
140,3.377
|
||||||
|
141,3.518
|
||||||
|
142,2.565
|
||||||
|
143,2.385
|
||||||
|
144,2.360
|
||||||
|
145,2.768
|
||||||
|
146,3.172
|
||||||
|
147,2.754
|
||||||
|
148,2.758
|
||||||
|
149,2.474
|
||||||
|
150,2.995
|
||||||
|
151,2.903
|
||||||
|
152,3.398
|
||||||
|
153,2.484
|
||||||
|
154,2.894
|
||||||
|
155,3.022
|
||||||
|
156,2.413
|
||||||
|
157,3.517
|
||||||
|
158,3.370
|
||||||
|
159,2.854
|
||||||
|
160,2.485
|
||||||
|
161,3.058
|
||||||
|
162,2.473
|
||||||
|
163,3.390
|
||||||
|
164,3.023
|
||||||
|
165,2.543
|
||||||
|
166,2.629
|
||||||
|
167,2.929
|
||||||
|
168,2.928
|
||||||
|
169,3.268
|
||||||
|
170,2.622
|
||||||
|
171,2.764
|
||||||
|
172,2.920
|
||||||
|
173,2.681
|
||||||
|
174,2.551
|
||||||
|
175,3.492
|
||||||
|
176,2.534
|
||||||
|
177,2.741
|
||||||
|
178,2.949
|
||||||
|
179,2.554
|
||||||
|
180,2.596
|
||||||
|
181,3.522
|
||||||
|
182,3.207
|
||||||
|
183,2.722
|
||||||
|
184,2.945
|
||||||
|
185,2.474
|
||||||
|
186,2.934
|
||||||
|
187,3.447
|
||||||
|
188,2.515
|
||||||
|
189,2.317
|
||||||
|
190,3.059
|
||||||
|
191,2.542
|
||||||
|
192,3.417
|
||||||
|
193,2.737
|
||||||
|
194,2.456
|
||||||
|
195,3.025
|
||||||
|
196,2.640
|
||||||
|
197,2.601
|
||||||
|
198,3.567
|
||||||
|
199,2.350
|
||||||
|
200,2.581
|
||||||
|
201,3.079
|
||||||
|
202,2.514
|
||||||
|
203,2.462
|
||||||
|
204,3.725
|
||||||
|
205,3.730
|
||||||
|
206,2.670
|
||||||
|
207,2.308
|
||||||
|
208,2.689
|
||||||
|
209,2.565
|
||||||
|
210,3.479
|
||||||
|
211,2.604
|
||||||
|
212,3.339
|
||||||
|
213,2.373
|
||||||
|
214,2.678
|
||||||
|
215,3.340
|
||||||
|
216,2.867
|
||||||
|
217,2.751
|
||||||
|
218,2.747
|
||||||
|
219,2.410
|
||||||
|
220,2.485
|
||||||
|
221,2.594
|
||||||
|
222,3.602
|
||||||
|
223,2.689
|
||||||
|
224,2.565
|
||||||
|
225,2.397
|
||||||
|
226,2.562
|
||||||
|
227,2.598
|
||||||
|
228,3.403
|
||||||
|
229,3.303
|
||||||
|
230,2.775
|
||||||
|
231,2.101
|
||||||
|
232,2.499
|
||||||
|
233,2.991
|
||||||
|
234,3.059
|
||||||
|
235,3.210
|
||||||
|
236,2.568
|
||||||
|
237,2.066
|
||||||
|
238,2.498
|
||||||
|
239,2.572
|
||||||
|
240,3.281
|
||||||
|
241,2.676
|
||||||
|
242,2.640
|
||||||
|
243,2.867
|
||||||
|
244,2.418
|
||||||
|
245,2.493
|
||||||
|
246,3.126
|
||||||
|
247,2.845
|
||||||
|
248,2.522
|
||||||
|
249,2.459
|
||||||
|
250,2.524
|
||||||
|
251,2.466
|
||||||
|
252,3.060
|
||||||
|
253,3.848
|
||||||
|
254,2.516
|
||||||
|
255,2.460
|
||||||
|
256,2.499
|
||||||
|
257,2.427
|
||||||
|
258,3.463
|
||||||
|
259,2.761
|
||||||
|
260,2.674
|
||||||
|
261,2.450
|
||||||
|
262,2.491
|
||||||
|
263,2.543
|
||||||
|
264,2.732
|
||||||
|
265,3.679
|
||||||
|
266,2.325
|
||||||
|
267,2.529
|
||||||
|
268,2.344
|
||||||
|
269,2.534
|
||||||
|
270,2.691
|
||||||
|
271,3.176
|
||||||
|
272,2.492
|
||||||
|
273,2.721
|
||||||
|
274,2.587
|
||||||
|
275,2.594
|
||||||
|
276,2.326
|
||||||
|
277,3.434
|
||||||
|
278,3.514
|
||||||
|
279,2.415
|
||||||
|
280,2.481
|
||||||
|
281,2.478
|
||||||
|
282,2.555
|
||||||
|
283,3.303
|
||||||
|
284,3.098
|
||||||
|
285,2.451
|
||||||
|
286,2.552
|
||||||
|
287,2.413
|
||||||
|
288,2.613
|
||||||
|
289,3.194
|
||||||
|
290,3.191
|
||||||
|
291,2.338
|
||||||
|
292,2.561
|
||||||
|
293,2.785
|
||||||
|
294,2.240
|
||||||
|
295,3.324
|
||||||
|
296,2.767
|
||||||
|
297,2.589
|
||||||
|
298,2.608
|
||||||
|
299,2.432
|
||||||
|
300,2.444
|
||||||
|
301,2.968
|
||||||
|
302,3.792
|
||||||
|
303,2.590
|
||||||
|
304,2.335
|
||||||
|
305,2.520
|
||||||
|
306,2.435
|
||||||
|
307,3.613
|
||||||
|
308,2.681
|
||||||
|
309,2.692
|
||||||
|
310,2.329
|
||||||
|
311,2.580
|
||||||
|
312,2.355
|
||||||
|
313,3.084
|
||||||
|
314,3.026
|
||||||
|
315,2.551
|
||||||
|
316,2.490
|
||||||
|
317,2.481
|
||||||
|
318,2.553
|
||||||
|
319,2.619
|
||||||
|
320,3.350
|
||||||
|
321,2.885
|
||||||
|
322,2.576
|
||||||
|
323,2.456
|
||||||
|
324,2.441
|
||||||
|
325,3.223
|
||||||
|
326,3.031
|
||||||
|
327,3.055
|
||||||
|
328,2.592
|
||||||
|
329,2.499
|
||||||
|
330,2.354
|
||||||
|
331,2.573
|
||||||
|
332,3.323
|
||||||
|
333,3.357
|
||||||
|
334,2.241
|
||||||
|
335,2.319
|
||||||
|
336,2.472
|
||||||
|
337,2.609
|
||||||
|
338,3.565
|
||||||
|
339,2.607
|
||||||
|
340,2.539
|
||||||
|
341,2.440
|
||||||
|
342,2.483
|
||||||
|
343,2.626
|
||||||
|
344,3.407
|
||||||
|
345,2.772
|
||||||
|
346,2.491
|
||||||
|
347,2.456
|
||||||
|
348,2.553
|
||||||
|
349,2.773
|
||||||
|
350,3.239
|
||||||
|
351,4.079
|
||||||
|
352,2.346
|
||||||
|
353,2.177
|
||||||
|
354,2.562
|
||||||
|
355,2.350
|
||||||
|
356,3.329
|
||||||
|
357,3.383
|
||||||
|
358,2.441
|
||||||
|
359,2.399
|
||||||
|
360,2.530
|
||||||
|
361,2.455
|
||||||
|
362,3.219
|
||||||
|
363,2.879
|
||||||
|
364,2.726
|
||||||
|
365,2.418
|
||||||
|
366,2.511
|
||||||
|
367,2.544
|
||||||
|
368,3.077
|
||||||
|
369,2.926
|
||||||
|
370,2.571
|
||||||
|
371,2.595
|
||||||
|
372,2.534
|
||||||
|
373,2.367
|
||||||
|
374,2.671
|
||||||
|
375,4.222
|
||||||
|
376,2.411
|
||||||
|
377,2.569
|
||||||
|
378,2.493
|
||||||
|
379,2.464
|
||||||
|
380,2.691
|
||||||
|
381,3.474
|
||||||
|
382,2.697
|
||||||
|
383,2.541
|
||||||
|
384,2.494
|
||||||
|
385,2.476
|
||||||
|
386,2.473
|
||||||
|
387,3.464
|
||||||
|
388,3.084
|
||||||
|
389,2.144
|
||||||
|
390,2.503
|
||||||
|
391,2.501
|
||||||
|
392,2.525
|
||||||
|
393,3.335
|
||||||
|
394,2.919
|
||||||
|
395,2.334
|
||||||
|
396,2.557
|
||||||
|
397,2.579
|
||||||
|
398,2.567
|
||||||
|
399,4.120
|
||||||
|
400,3.297
|
||||||
|
401,2.561
|
||||||
|
402,2.428
|
||||||
|
403,2.495
|
||||||
|
404,2.729
|
||||||
|
405,3.752
|
||||||
|
406,2.783
|
||||||
|
407,2.509
|
||||||
|
408,2.337
|
||||||
|
409,2.589
|
||||||
|
410,2.556
|
||||||
|
411,3.449
|
||||||
|
412,2.702
|
||||||
|
413,2.742
|
||||||
|
414,2.384
|
||||||
|
415,2.759
|
||||||
|
416,2.290
|
||||||
|
417,3.374
|
||||||
|
418,2.934
|
||||||
|
419,2.546
|
||||||
|
420,2.228
|
||||||
|
421,2.672
|
||||||
|
422,2.369
|
||||||
|
423,3.442
|
||||||
|
424,3.484
|
||||||
|
425,2.621
|
||||||
|
426,2.279
|
||||||
|
427,2.529
|
||||||
|
428,2.889
|
||||||
|
429,2.910
|
||||||
|
430,2.981
|
||||||
|
431,2.957
|
||||||
|
432,2.420
|
||||||
|
433,2.398
|
||||||
|
434,2.310
|
||||||
|
435,3.662
|
||||||
|
436,2.422
|
||||||
|
437,2.676
|
||||||
|
438,2.557
|
||||||
|
439,2.527
|
||||||
|
440,2.564
|
||||||
|
441,2.649
|
||||||
|
442,3.168
|
||||||
|
443,2.499
|
||||||
|
444,2.737
|
||||||
|
445,2.637
|
||||||
|
446,2.509
|
||||||
|
447,2.716
|
||||||
|
448,3.845
|
||||||
|
449,2.654
|
||||||
|
450,2.536
|
||||||
|
451,2.366
|
||||||
|
452,2.526
|
||||||
|
453,2.906
|
||||||
|
454,3.101
|
||||||
|
455,2.809
|
||||||
|
456,2.466
|
||||||
|
457,2.502
|
||||||
|
458,2.767
|
||||||
|
459,2.486
|
||||||
|
460,3.137
|
||||||
|
461,3.402
|
||||||
|
462,2.187
|
||||||
|
463,2.398
|
||||||
|
464,2.392
|
||||||
|
465,2.614
|
||||||
|
466,3.371
|
||||||
|
467,2.847
|
||||||
|
468,2.463
|
||||||
|
469,2.639
|
||||||
|
470,2.288
|
||||||
|
471,2.562
|
||||||
|
472,3.381
|
||||||
|
473,3.491
|
||||||
|
474,2.521
|
||||||
|
475,2.397
|
||||||
|
476,2.431
|
||||||
|
477,2.759
|
||||||
|
478,3.222
|
||||||
|
479,2.957
|
||||||
|
480,2.470
|
||||||
|
481,2.403
|
||||||
|
482,2.560
|
||||||
|
483,2.470
|
||||||
|
484,3.451
|
||||||
|
485,2.905
|
||||||
|
486,2.583
|
||||||
|
487,2.329
|
||||||
|
488,2.798
|
||||||
|
489,2.289
|
||||||
|
490,2.882
|
||||||
|
491,2.903
|
||||||
|
492,2.627
|
||||||
|
493,2.897
|
||||||
|
494,2.321
|
||||||
|
495,2.472
|
||||||
|
496,2.882
|
||||||
|
497,3.844
|
||||||
|
498,3.096
|
||||||
|
499,2.525
|
||||||
|
500,2.250
|
||||||
|
501,2.477
|
||||||
|
502,2.728
|
||||||
|
503,3.391
|
||||||
|
504,2.539
|
||||||
|
505,2.635
|
||||||
|
506,2.542
|
||||||
|
507,2.435
|
||||||
|
508,3.011
|
||||||
|
509,3.042
|
||||||
|
510,2.965
|
||||||
|
511,2.273
|
||||||
|
512,2.433
|
||||||
|
513,3.020
|
||||||
|
514,2.776
|
||||||
|
515,3.646
|
||||||
|
516,2.856
|
||||||
|
517,2.886
|
||||||
|
518,2.522
|
||||||
|
519,2.528
|
||||||
|
520,4.396
|
||||||
|
521,3.397
|
||||||
|
522,2.218
|
||||||
|
523,2.433
|
||||||
|
524,2.605
|
||||||
|
525,3.504
|
||||||
|
526,3.087
|
||||||
|
527,3.186
|
||||||
|
528,2.343
|
||||||
|
529,2.433
|
||||||
|
530,2.900
|
||||||
|
531,3.000
|
||||||
|
532,3.511
|
||||||
|
533,2.663
|
||||||
|
534,2.699
|
||||||
|
535,2.423
|
||||||
|
536,3.136
|
||||||
|
537,2.802
|
||||||
|
538,3.151
|
||||||
|
539,2.507
|
||||||
|
540,2.973
|
||||||
|
541,2.325
|
||||||
|
542,3.322
|
||||||
|
543,3.260
|
||||||
|
544,3.525
|
||||||
|
545,2.846
|
||||||
|
546,2.125
|
||||||
|
547,2.697
|
||||||
|
548,2.829
|
||||||
|
549,3.389
|
||||||
|
550,2.758
|
||||||
|
551,2.866
|
||||||
|
552,2.338
|
||||||
|
553,3.115
|
||||||
|
554,2.500
|
||||||
|
555,3.387
|
||||||
|
556,2.851
|
||||||
|
557,2.511
|
||||||
|
558,2.459
|
||||||
|
559,3.107
|
||||||
|
560,2.521
|
||||||
|
561,3.308
|
||||||
|
562,2.782
|
||||||
|
563,2.810
|
||||||
|
564,2.323
|
||||||
|
565,3.259
|
||||||
|
566,2.366
|
||||||
|
567,3.542
|
||||||
|
568,2.929
|
||||||
|
569,2.299
|
||||||
|
570,2.336
|
||||||
|
571,3.027
|
||||||
|
572,2.540
|
||||||
|
573,3.409
|
||||||
|
574,2.784
|
||||||
|
575,2.444
|
||||||
|
576,2.437
|
||||||
|
577,2.734
|
||||||
|
578,2.591
|
||||||
|
579,3.845
|
||||||
|
580,3.212
|
||||||
|
581,2.802
|
||||||
|
582,2.370
|
||||||
|
583,2.704
|
||||||
|
584,2.624
|
||||||
|
585,4.023
|
||||||
|
586,2.360
|
||||||
|
587,2.759
|
||||||
|
588,2.511
|
||||||
|
589,2.608
|
||||||
|
590,2.922
|
||||||
|
591,3.081
|
||||||
|
592,3.271
|
||||||
|
593,2.471
|
||||||
|
594,2.516
|
||||||
|
595,2.474
|
||||||
|
596,2.814
|
||||||
|
597,3.127
|
||||||
|
598,2.537
|
||||||
|
599,3.080
|
||||||
|
600,2.341
|
||||||
|
601,3.027
|
||||||
|
602,2.766
|
||||||
|
603,2.984
|
||||||
|
604,2.450
|
||||||
|
605,2.922
|
||||||
|
606,2.481
|
||||||
|
607,2.616
|
||||||
|
608,2.541
|
||||||
|
609,3.462
|
||||||
|
610,2.971
|
||||||
|
611,2.955
|
||||||
|
612,2.258
|
||||||
|
613,2.682
|
||||||
|
614,2.770
|
||||||
|
615,3.119
|
||||||
|
616,2.792
|
||||||
|
617,2.598
|
||||||
|
618,2.260
|
||||||
|
619,2.441
|
||||||
|
620,2.536
|
||||||
|
621,3.425
|
||||||
|
622,2.958
|
||||||
|
623,2.722
|
||||||
|
624,2.099
|
||||||
|
625,2.400
|
||||||
|
626,2.570
|
||||||
|
627,3.295
|
||||||
|
628,2.919
|
||||||
|
629,2.737
|
||||||
|
630,2.311
|
||||||
|
631,2.408
|
||||||
|
632,2.514
|
||||||
|
633,3.325
|
||||||
|
634,2.767
|
||||||
|
635,2.724
|
||||||
|
636,2.288
|
||||||
|
637,2.680
|
||||||
|
638,2.347
|
||||||
|
639,2.902
|
||||||
|
640,3.058
|
||||||
|
641,2.770
|
||||||
|
642,2.522
|
||||||
|
643,2.406
|
||||||
|
644,2.539
|
||||||
|
645,2.753
|
||||||
|
646,3.215
|
||||||
|
647,2.636
|
||||||
|
648,2.639
|
||||||
|
649,2.666
|
||||||
|
650,2.392
|
||||||
|
651,2.408
|
||||||
|
652,3.515
|
||||||
|
653,2.687
|
||||||
|
654,2.589
|
||||||
|
655,2.428
|
||||||
|
656,2.375
|
||||||
|
657,2.619
|
||||||
|
658,3.308
|
||||||
|
659,2.664
|
||||||
|
660,2.752
|
||||||
|
661,2.456
|
||||||
|
662,2.365
|
||||||
|
663,2.533
|
||||||
|
664,3.354
|
||||||
|
665,2.812
|
||||||
|
666,2.684
|
||||||
|
667,2.349
|
||||||
|
668,2.441
|
||||||
|
669,2.714
|
||||||
|
670,2.769
|
||||||
|
671,3.368
|
||||||
|
672,2.624
|
||||||
|
673,2.308
|
||||||
|
674,2.365
|
||||||
|
675,2.634
|
||||||
|
676,2.617
|
||||||
|
677,3.350
|
||||||
|
678,2.733
|
||||||
|
679,2.623
|
||||||
|
680,2.462
|
||||||
|
681,2.494
|
||||||
|
682,2.460
|
||||||
|
683,3.463
|
||||||
|
684,2.537
|
||||||
|
685,2.628
|
||||||
|
686,2.674
|
||||||
|
687,2.381
|
||||||
|
688,2.516
|
||||||
|
689,3.586
|
||||||
|
690,2.681
|
||||||
|
691,2.676
|
||||||
|
692,2.289
|
||||||
|
693,2.726
|
||||||
|
694,2.303
|
||||||
|
695,2.934
|
||||||
|
696,3.339
|
||||||
|
697,2.606
|
||||||
|
698,2.187
|
||||||
|
699,2.687
|
||||||
|
700,2.328
|
||||||
|
701,3.062
|
||||||
|
702,2.930
|
||||||
|
703,2.871
|
||||||
|
704,2.313
|
||||||
|
705,2.582
|
||||||
|
706,2.464
|
||||||
|
707,2.521
|
||||||
|
708,3.304
|
||||||
|
709,2.492
|
||||||
|
710,2.723
|
||||||
|
711,2.587
|
||||||
|
712,2.608
|
||||||
|
713,2.574
|
||||||
|
714,4.002
|
||||||
|
715,3.011
|
||||||
|
716,2.227
|
||||||
|
717,2.374
|
||||||
|
718,2.343
|
||||||
|
719,2.541
|
||||||
|
720,3.580
|
||||||
|
721,2.854
|
||||||
|
@@ -0,0 +1,760 @@
|
|||||||
|
frame,ms
|
||||||
|
0,2.428
|
||||||
|
1,2.633
|
||||||
|
2,2.238
|
||||||
|
3,3.606
|
||||||
|
4,2.431
|
||||||
|
5,2.649
|
||||||
|
6,4.050
|
||||||
|
7,2.011
|
||||||
|
8,2.735
|
||||||
|
9,3.390
|
||||||
|
10,2.901
|
||||||
|
11,2.237
|
||||||
|
12,2.686
|
||||||
|
13,2.383
|
||||||
|
14,2.451
|
||||||
|
15,3.412
|
||||||
|
16,2.458
|
||||||
|
17,2.474
|
||||||
|
18,2.588
|
||||||
|
19,2.556
|
||||||
|
20,2.478
|
||||||
|
21,3.150
|
||||||
|
22,2.667
|
||||||
|
23,2.349
|
||||||
|
24,2.568
|
||||||
|
25,2.580
|
||||||
|
26,2.393
|
||||||
|
27,2.575
|
||||||
|
28,3.132
|
||||||
|
29,2.536
|
||||||
|
30,2.508
|
||||||
|
31,2.710
|
||||||
|
32,2.348
|
||||||
|
33,2.537
|
||||||
|
34,2.820
|
||||||
|
35,3.162
|
||||||
|
36,2.163
|
||||||
|
37,2.562
|
||||||
|
38,2.619
|
||||||
|
39,2.323
|
||||||
|
40,2.628
|
||||||
|
41,3.075
|
||||||
|
42,2.512
|
||||||
|
43,2.448
|
||||||
|
44,2.505
|
||||||
|
45,2.454
|
||||||
|
46,2.607
|
||||||
|
47,3.128
|
||||||
|
48,2.476
|
||||||
|
49,2.562
|
||||||
|
50,2.434
|
||||||
|
51,3.385
|
||||||
|
52,2.076
|
||||||
|
53,3.435
|
||||||
|
54,2.672
|
||||||
|
55,2.550
|
||||||
|
56,1.998
|
||||||
|
57,2.583
|
||||||
|
58,2.518
|
||||||
|
59,2.777
|
||||||
|
60,3.920
|
||||||
|
61,2.934
|
||||||
|
62,2.675
|
||||||
|
63,2.320
|
||||||
|
64,2.309
|
||||||
|
65,2.520
|
||||||
|
66,3.947
|
||||||
|
67,2.596
|
||||||
|
68,2.708
|
||||||
|
69,2.291
|
||||||
|
70,2.404
|
||||||
|
71,2.551
|
||||||
|
72,3.715
|
||||||
|
73,2.100
|
||||||
|
74,2.539
|
||||||
|
75,2.682
|
||||||
|
76,2.273
|
||||||
|
77,2.442
|
||||||
|
78,3.952
|
||||||
|
79,2.233
|
||||||
|
80,2.374
|
||||||
|
81,2.686
|
||||||
|
82,2.407
|
||||||
|
83,2.654
|
||||||
|
84,3.613
|
||||||
|
85,2.320
|
||||||
|
86,2.685
|
||||||
|
87,2.744
|
||||||
|
88,2.357
|
||||||
|
89,2.565
|
||||||
|
90,3.756
|
||||||
|
91,2.672
|
||||||
|
92,2.128
|
||||||
|
93,2.583
|
||||||
|
94,2.546
|
||||||
|
95,2.391
|
||||||
|
96,2.935
|
||||||
|
97,3.624
|
||||||
|
98,1.934
|
||||||
|
99,2.509
|
||||||
|
100,2.603
|
||||||
|
101,2.449
|
||||||
|
102,2.802
|
||||||
|
103,3.678
|
||||||
|
104,2.336
|
||||||
|
105,2.509
|
||||||
|
106,2.551
|
||||||
|
107,2.576
|
||||||
|
108,2.997
|
||||||
|
109,3.208
|
||||||
|
110,2.301
|
||||||
|
111,2.359
|
||||||
|
112,2.484
|
||||||
|
113,2.646
|
||||||
|
114,2.801
|
||||||
|
115,3.226
|
||||||
|
116,2.635
|
||||||
|
117,2.325
|
||||||
|
118,2.501
|
||||||
|
119,2.602
|
||||||
|
120,2.564
|
||||||
|
121,3.151
|
||||||
|
122,3.149
|
||||||
|
123,2.235
|
||||||
|
124,2.596
|
||||||
|
125,2.432
|
||||||
|
126,2.665
|
||||||
|
127,2.648
|
||||||
|
128,3.884
|
||||||
|
129,2.087
|
||||||
|
130,2.375
|
||||||
|
131,2.586
|
||||||
|
132,2.734
|
||||||
|
133,2.338
|
||||||
|
134,3.617
|
||||||
|
135,2.418
|
||||||
|
136,2.350
|
||||||
|
137,2.713
|
||||||
|
138,2.758
|
||||||
|
139,2.239
|
||||||
|
140,3.585
|
||||||
|
141,2.565
|
||||||
|
142,2.787
|
||||||
|
143,2.115
|
||||||
|
144,2.435
|
||||||
|
145,2.489
|
||||||
|
146,3.062
|
||||||
|
147,2.958
|
||||||
|
148,2.402
|
||||||
|
149,2.425
|
||||||
|
150,2.516
|
||||||
|
151,2.505
|
||||||
|
152,2.543
|
||||||
|
153,3.690
|
||||||
|
154,2.060
|
||||||
|
155,2.510
|
||||||
|
156,2.428
|
||||||
|
157,2.603
|
||||||
|
158,2.491
|
||||||
|
159,3.178
|
||||||
|
160,2.496
|
||||||
|
161,2.424
|
||||||
|
162,2.495
|
||||||
|
163,2.667
|
||||||
|
164,2.434
|
||||||
|
165,3.040
|
||||||
|
166,2.949
|
||||||
|
167,2.094
|
||||||
|
168,2.510
|
||||||
|
169,2.586
|
||||||
|
170,2.395
|
||||||
|
171,3.004
|
||||||
|
172,3.009
|
||||||
|
173,2.288
|
||||||
|
174,2.548
|
||||||
|
175,2.337
|
||||||
|
176,2.598
|
||||||
|
177,2.498
|
||||||
|
178,3.526
|
||||||
|
179,2.533
|
||||||
|
180,2.134
|
||||||
|
181,2.560
|
||||||
|
182,2.541
|
||||||
|
183,2.436
|
||||||
|
184,2.635
|
||||||
|
185,3.361
|
||||||
|
186,2.261
|
||||||
|
187,2.566
|
||||||
|
188,2.383
|
||||||
|
189,2.529
|
||||||
|
190,2.645
|
||||||
|
191,3.190
|
||||||
|
192,2.523
|
||||||
|
193,2.523
|
||||||
|
194,2.346
|
||||||
|
195,2.865
|
||||||
|
196,2.348
|
||||||
|
197,2.879
|
||||||
|
198,3.657
|
||||||
|
199,1.824
|
||||||
|
200,2.551
|
||||||
|
201,2.449
|
||||||
|
202,2.607
|
||||||
|
203,3.085
|
||||||
|
204,3.163
|
||||||
|
205,2.404
|
||||||
|
206,2.327
|
||||||
|
207,2.553
|
||||||
|
208,2.576
|
||||||
|
209,2.544
|
||||||
|
210,3.193
|
||||||
|
211,2.647
|
||||||
|
212,2.332
|
||||||
|
213,2.544
|
||||||
|
214,2.767
|
||||||
|
215,2.429
|
||||||
|
216,3.103
|
||||||
|
217,2.861
|
||||||
|
218,2.318
|
||||||
|
219,2.552
|
||||||
|
220,2.587
|
||||||
|
221,2.352
|
||||||
|
222,3.128
|
||||||
|
223,2.621
|
||||||
|
224,2.461
|
||||||
|
225,2.422
|
||||||
|
226,2.601
|
||||||
|
227,2.748
|
||||||
|
228,2.545
|
||||||
|
229,3.224
|
||||||
|
230,2.206
|
||||||
|
231,2.459
|
||||||
|
232,2.530
|
||||||
|
233,2.461
|
||||||
|
234,2.570
|
||||||
|
235,3.271
|
||||||
|
236,2.405
|
||||||
|
237,2.424
|
||||||
|
238,2.671
|
||||||
|
239,2.450
|
||||||
|
240,2.644
|
||||||
|
241,2.510
|
||||||
|
242,3.023
|
||||||
|
243,2.461
|
||||||
|
244,2.618
|
||||||
|
245,2.350
|
||||||
|
246,2.551
|
||||||
|
247,2.472
|
||||||
|
248,3.642
|
||||||
|
249,2.576
|
||||||
|
250,2.548
|
||||||
|
251,3.599
|
||||||
|
252,1.992
|
||||||
|
253,2.424
|
||||||
|
254,3.752
|
||||||
|
255,2.241
|
||||||
|
256,2.360
|
||||||
|
257,2.522
|
||||||
|
258,2.584
|
||||||
|
259,2.653
|
||||||
|
260,2.871
|
||||||
|
261,2.827
|
||||||
|
262,2.369
|
||||||
|
263,2.482
|
||||||
|
264,2.599
|
||||||
|
265,2.294
|
||||||
|
266,2.686
|
||||||
|
267,3.428
|
||||||
|
268,2.240
|
||||||
|
269,2.435
|
||||||
|
270,2.468
|
||||||
|
271,2.619
|
||||||
|
272,2.519
|
||||||
|
273,3.247
|
||||||
|
274,2.539
|
||||||
|
275,2.442
|
||||||
|
276,2.518
|
||||||
|
277,2.489
|
||||||
|
278,2.463
|
||||||
|
279,2.839
|
||||||
|
280,2.907
|
||||||
|
281,2.786
|
||||||
|
282,2.211
|
||||||
|
283,2.615
|
||||||
|
284,2.378
|
||||||
|
285,2.671
|
||||||
|
286,3.219
|
||||||
|
287,2.435
|
||||||
|
288,2.509
|
||||||
|
289,2.323
|
||||||
|
290,2.502
|
||||||
|
291,2.526
|
||||||
|
292,3.292
|
||||||
|
293,2.468
|
||||||
|
294,2.526
|
||||||
|
295,2.500
|
||||||
|
296,2.431
|
||||||
|
297,2.481
|
||||||
|
298,2.921
|
||||||
|
299,3.009
|
||||||
|
300,2.415
|
||||||
|
301,2.600
|
||||||
|
302,2.344
|
||||||
|
303,2.533
|
||||||
|
304,2.618
|
||||||
|
305,3.458
|
||||||
|
306,2.455
|
||||||
|
307,2.469
|
||||||
|
308,2.495
|
||||||
|
309,2.568
|
||||||
|
310,2.473
|
||||||
|
311,3.179
|
||||||
|
312,2.694
|
||||||
|
313,2.503
|
||||||
|
314,2.587
|
||||||
|
315,2.317
|
||||||
|
316,2.609
|
||||||
|
317,2.590
|
||||||
|
318,3.211
|
||||||
|
319,2.392
|
||||||
|
320,2.490
|
||||||
|
321,2.515
|
||||||
|
322,2.496
|
||||||
|
323,2.483
|
||||||
|
324,3.157
|
||||||
|
325,2.540
|
||||||
|
326,2.422
|
||||||
|
327,2.574
|
||||||
|
328,2.468
|
||||||
|
329,2.547
|
||||||
|
330,2.788
|
||||||
|
331,3.075
|
||||||
|
332,2.231
|
||||||
|
333,2.537
|
||||||
|
334,2.577
|
||||||
|
335,2.584
|
||||||
|
336,2.473
|
||||||
|
337,3.415
|
||||||
|
338,2.126
|
||||||
|
339,2.506
|
||||||
|
340,2.374
|
||||||
|
341,2.721
|
||||||
|
342,2.418
|
||||||
|
343,3.259
|
||||||
|
344,2.509
|
||||||
|
345,2.519
|
||||||
|
346,2.436
|
||||||
|
347,2.472
|
||||||
|
348,2.504
|
||||||
|
349,2.858
|
||||||
|
350,3.250
|
||||||
|
351,2.161
|
||||||
|
352,2.586
|
||||||
|
353,2.376
|
||||||
|
354,2.651
|
||||||
|
355,2.504
|
||||||
|
356,3.399
|
||||||
|
357,2.353
|
||||||
|
358,2.381
|
||||||
|
359,2.513
|
||||||
|
360,2.633
|
||||||
|
361,2.566
|
||||||
|
362,3.615
|
||||||
|
363,2.593
|
||||||
|
364,2.084
|
||||||
|
365,2.411
|
||||||
|
366,2.653
|
||||||
|
367,2.521
|
||||||
|
368,2.825
|
||||||
|
369,2.891
|
||||||
|
370,2.576
|
||||||
|
371,2.302
|
||||||
|
372,2.582
|
||||||
|
373,2.513
|
||||||
|
374,2.598
|
||||||
|
375,3.790
|
||||||
|
376,2.352
|
||||||
|
377,2.306
|
||||||
|
378,2.434
|
||||||
|
379,2.514
|
||||||
|
380,2.708
|
||||||
|
381,2.978
|
||||||
|
382,2.813
|
||||||
|
383,2.327
|
||||||
|
384,2.502
|
||||||
|
385,2.446
|
||||||
|
386,2.605
|
||||||
|
387,3.033
|
||||||
|
388,3.091
|
||||||
|
389,2.206
|
||||||
|
390,2.648
|
||||||
|
391,2.732
|
||||||
|
392,2.296
|
||||||
|
393,3.406
|
||||||
|
394,2.490
|
||||||
|
395,2.424
|
||||||
|
396,2.443
|
||||||
|
397,2.601
|
||||||
|
398,2.628
|
||||||
|
399,2.477
|
||||||
|
400,3.241
|
||||||
|
401,2.573
|
||||||
|
402,2.422
|
||||||
|
403,2.384
|
||||||
|
404,2.505
|
||||||
|
405,2.575
|
||||||
|
406,2.909
|
||||||
|
407,2.897
|
||||||
|
408,2.486
|
||||||
|
409,2.431
|
||||||
|
410,2.691
|
||||||
|
411,2.342
|
||||||
|
412,2.733
|
||||||
|
413,3.518
|
||||||
|
414,2.391
|
||||||
|
415,2.160
|
||||||
|
416,2.671
|
||||||
|
417,2.505
|
||||||
|
418,2.241
|
||||||
|
419,3.355
|
||||||
|
420,2.775
|
||||||
|
421,2.395
|
||||||
|
422,2.864
|
||||||
|
423,2.290
|
||||||
|
424,2.469
|
||||||
|
425,2.977
|
||||||
|
426,2.759
|
||||||
|
427,2.460
|
||||||
|
428,2.456
|
||||||
|
429,2.497
|
||||||
|
430,2.362
|
||||||
|
431,2.874
|
||||||
|
432,2.812
|
||||||
|
433,2.559
|
||||||
|
434,2.283
|
||||||
|
435,2.670
|
||||||
|
436,2.482
|
||||||
|
437,2.495
|
||||||
|
438,3.118
|
||||||
|
439,3.018
|
||||||
|
440,2.252
|
||||||
|
441,3.222
|
||||||
|
442,2.483
|
||||||
|
443,2.436
|
||||||
|
444,3.209
|
||||||
|
445,3.169
|
||||||
|
446,2.455
|
||||||
|
447,2.432
|
||||||
|
448,2.464
|
||||||
|
449,2.500
|
||||||
|
450,2.967
|
||||||
|
451,2.958
|
||||||
|
452,2.390
|
||||||
|
453,2.494
|
||||||
|
454,2.523
|
||||||
|
455,2.473
|
||||||
|
456,2.516
|
||||||
|
457,3.527
|
||||||
|
458,2.262
|
||||||
|
459,2.377
|
||||||
|
460,2.840
|
||||||
|
461,2.135
|
||||||
|
462,2.520
|
||||||
|
463,3.285
|
||||||
|
464,2.940
|
||||||
|
465,2.256
|
||||||
|
466,2.496
|
||||||
|
467,2.705
|
||||||
|
468,2.395
|
||||||
|
469,3.031
|
||||||
|
470,3.104
|
||||||
|
471,2.411
|
||||||
|
472,2.630
|
||||||
|
473,2.468
|
||||||
|
474,2.416
|
||||||
|
475,2.559
|
||||||
|
476,2.732
|
||||||
|
477,2.441
|
||||||
|
478,2.624
|
||||||
|
479,2.536
|
||||||
|
480,2.458
|
||||||
|
481,2.516
|
||||||
|
482,2.507
|
||||||
|
483,2.606
|
||||||
|
484,2.616
|
||||||
|
485,2.881
|
||||||
|
486,2.358
|
||||||
|
487,2.469
|
||||||
|
488,2.513
|
||||||
|
489,3.250
|
||||||
|
490,2.606
|
||||||
|
491,2.545
|
||||||
|
492,2.407
|
||||||
|
493,2.437
|
||||||
|
494,2.663
|
||||||
|
495,3.346
|
||||||
|
496,2.349
|
||||||
|
497,2.481
|
||||||
|
498,2.613
|
||||||
|
499,2.483
|
||||||
|
500,2.417
|
||||||
|
501,2.923
|
||||||
|
502,3.059
|
||||||
|
503,2.483
|
||||||
|
504,2.373
|
||||||
|
505,2.525
|
||||||
|
506,2.530
|
||||||
|
507,2.431
|
||||||
|
508,2.917
|
||||||
|
509,2.559
|
||||||
|
510,2.623
|
||||||
|
511,3.172
|
||||||
|
512,2.304
|
||||||
|
513,2.331
|
||||||
|
514,3.287
|
||||||
|
515,2.544
|
||||||
|
516,2.429
|
||||||
|
517,2.690
|
||||||
|
518,2.464
|
||||||
|
519,2.406
|
||||||
|
520,2.804
|
||||||
|
521,2.899
|
||||||
|
522,2.461
|
||||||
|
523,2.536
|
||||||
|
524,2.414
|
||||||
|
525,2.380
|
||||||
|
526,2.616
|
||||||
|
527,3.236
|
||||||
|
528,2.499
|
||||||
|
529,2.558
|
||||||
|
530,2.584
|
||||||
|
531,2.309
|
||||||
|
532,2.447
|
||||||
|
533,3.039
|
||||||
|
534,3.133
|
||||||
|
535,2.170
|
||||||
|
536,2.583
|
||||||
|
537,2.505
|
||||||
|
538,2.666
|
||||||
|
539,2.567
|
||||||
|
540,3.307
|
||||||
|
541,2.177
|
||||||
|
542,2.495
|
||||||
|
543,2.441
|
||||||
|
544,2.638
|
||||||
|
545,2.521
|
||||||
|
546,3.527
|
||||||
|
547,2.460
|
||||||
|
548,2.362
|
||||||
|
549,2.520
|
||||||
|
550,2.439
|
||||||
|
551,2.572
|
||||||
|
552,3.087
|
||||||
|
553,2.707
|
||||||
|
554,2.475
|
||||||
|
555,2.283
|
||||||
|
556,2.604
|
||||||
|
557,2.529
|
||||||
|
558,3.094
|
||||||
|
559,3.051
|
||||||
|
560,2.085
|
||||||
|
561,2.365
|
||||||
|
562,2.711
|
||||||
|
563,2.351
|
||||||
|
564,2.572
|
||||||
|
565,2.979
|
||||||
|
566,2.805
|
||||||
|
567,2.373
|
||||||
|
568,2.744
|
||||||
|
569,2.340
|
||||||
|
570,2.285
|
||||||
|
571,2.791
|
||||||
|
572,3.447
|
||||||
|
573,2.208
|
||||||
|
574,2.518
|
||||||
|
575,2.448
|
||||||
|
576,3.917
|
||||||
|
577,1.540
|
||||||
|
578,2.923
|
||||||
|
579,2.632
|
||||||
|
580,2.404
|
||||||
|
581,2.582
|
||||||
|
582,2.508
|
||||||
|
583,2.413
|
||||||
|
584,3.602
|
||||||
|
585,2.342
|
||||||
|
586,2.482
|
||||||
|
587,2.584
|
||||||
|
588,3.062
|
||||||
|
589,2.070
|
||||||
|
590,2.726
|
||||||
|
591,2.937
|
||||||
|
592,2.385
|
||||||
|
593,2.734
|
||||||
|
594,2.188
|
||||||
|
595,2.582
|
||||||
|
596,2.487
|
||||||
|
597,3.339
|
||||||
|
598,2.535
|
||||||
|
599,2.414
|
||||||
|
600,2.459
|
||||||
|
601,2.510
|
||||||
|
602,2.547
|
||||||
|
603,3.414
|
||||||
|
604,2.314
|
||||||
|
605,2.399
|
||||||
|
606,2.550
|
||||||
|
607,2.541
|
||||||
|
608,2.355
|
||||||
|
609,2.709
|
||||||
|
610,3.067
|
||||||
|
611,2.502
|
||||||
|
612,2.467
|
||||||
|
613,2.899
|
||||||
|
614,2.177
|
||||||
|
615,2.719
|
||||||
|
616,3.049
|
||||||
|
617,2.673
|
||||||
|
618,2.259
|
||||||
|
619,2.566
|
||||||
|
620,2.383
|
||||||
|
621,2.420
|
||||||
|
622,3.318
|
||||||
|
623,2.807
|
||||||
|
624,2.348
|
||||||
|
625,2.595
|
||||||
|
626,2.433
|
||||||
|
627,2.569
|
||||||
|
628,2.620
|
||||||
|
629,2.652
|
||||||
|
630,3.140
|
||||||
|
631,2.945
|
||||||
|
632,2.571
|
||||||
|
633,2.546
|
||||||
|
634,2.428
|
||||||
|
635,3.436
|
||||||
|
636,2.393
|
||||||
|
637,2.491
|
||||||
|
638,2.511
|
||||||
|
639,2.485
|
||||||
|
640,2.603
|
||||||
|
641,3.363
|
||||||
|
642,2.442
|
||||||
|
643,2.344
|
||||||
|
644,2.462
|
||||||
|
645,2.508
|
||||||
|
646,2.617
|
||||||
|
647,2.909
|
||||||
|
648,2.824
|
||||||
|
649,2.528
|
||||||
|
650,2.424
|
||||||
|
651,2.511
|
||||||
|
652,2.517
|
||||||
|
653,2.583
|
||||||
|
654,3.331
|
||||||
|
655,2.436
|
||||||
|
656,2.455
|
||||||
|
657,2.380
|
||||||
|
658,2.570
|
||||||
|
659,2.582
|
||||||
|
660,2.789
|
||||||
|
661,2.917
|
||||||
|
662,2.526
|
||||||
|
663,2.538
|
||||||
|
664,2.447
|
||||||
|
665,2.423
|
||||||
|
666,2.695
|
||||||
|
667,3.143
|
||||||
|
668,2.616
|
||||||
|
669,2.126
|
||||||
|
670,2.596
|
||||||
|
671,2.464
|
||||||
|
672,3.092
|
||||||
|
673,2.681
|
||||||
|
674,2.641
|
||||||
|
675,2.311
|
||||||
|
676,2.551
|
||||||
|
677,2.551
|
||||||
|
678,2.837
|
||||||
|
679,2.532
|
||||||
|
680,3.006
|
||||||
|
681,2.289
|
||||||
|
682,2.521
|
||||||
|
683,2.556
|
||||||
|
684,2.593
|
||||||
|
685,2.552
|
||||||
|
686,3.173
|
||||||
|
687,2.415
|
||||||
|
688,2.429
|
||||||
|
689,2.733
|
||||||
|
690,2.286
|
||||||
|
691,2.476
|
||||||
|
692,3.256
|
||||||
|
693,2.897
|
||||||
|
694,2.528
|
||||||
|
695,2.377
|
||||||
|
696,2.518
|
||||||
|
697,2.504
|
||||||
|
698,3.074
|
||||||
|
699,2.814
|
||||||
|
700,2.433
|
||||||
|
701,2.338
|
||||||
|
702,2.476
|
||||||
|
703,2.458
|
||||||
|
704,3.141
|
||||||
|
705,2.551
|
||||||
|
706,2.717
|
||||||
|
707,2.300
|
||||||
|
708,2.527
|
||||||
|
709,2.446
|
||||||
|
710,2.469
|
||||||
|
711,2.866
|
||||||
|
712,2.776
|
||||||
|
713,2.507
|
||||||
|
714,2.457
|
||||||
|
715,2.520
|
||||||
|
716,2.450
|
||||||
|
717,2.568
|
||||||
|
718,3.192
|
||||||
|
719,2.471
|
||||||
|
720,2.790
|
||||||
|
721,2.337
|
||||||
|
722,2.548
|
||||||
|
723,2.435
|
||||||
|
724,3.313
|
||||||
|
725,2.274
|
||||||
|
726,2.461
|
||||||
|
727,2.451
|
||||||
|
728,2.556
|
||||||
|
729,2.546
|
||||||
|
730,2.869
|
||||||
|
731,3.308
|
||||||
|
732,2.293
|
||||||
|
733,2.428
|
||||||
|
734,2.686
|
||||||
|
735,2.562
|
||||||
|
736,2.523
|
||||||
|
737,3.309
|
||||||
|
738,2.311
|
||||||
|
739,2.498
|
||||||
|
740,2.485
|
||||||
|
741,2.568
|
||||||
|
742,2.392
|
||||||
|
743,3.260
|
||||||
|
744,2.534
|
||||||
|
745,2.550
|
||||||
|
746,2.355
|
||||||
|
747,2.768
|
||||||
|
748,2.319
|
||||||
|
749,3.039
|
||||||
|
750,2.721
|
||||||
|
751,2.490
|
||||||
|
752,2.378
|
||||||
|
753,2.539
|
||||||
|
754,2.823
|
||||||
|
755,2.480
|
||||||
|
756,3.533
|
||||||
|
757,2.285
|
||||||
|
758,2.365
|
||||||
|
+158
-19
@@ -13,7 +13,19 @@ Record results in the table at the end of this file, with the date, the exact bu
|
|||||||
3. **Licensing.** Every new asset has provenance in `THIRD_PARTY_NOTICES.md`, or is recorded as unresolved and kept out of the build.
|
3. **Licensing.** Every new asset has provenance in `THIRD_PARTY_NOTICES.md`, or is recorded as unresolved and kept out of the build.
|
||||||
4. **Version discipline.** Patch releases contain fixes, optimisation, docs, or tuning only — no new scope.
|
4. **Version discipline.** Patch releases contain fixes, optimisation, docs, or tuning only — no new scope.
|
||||||
|
|
||||||
## Performance check
|
## `0.1.0` checks
|
||||||
|
|
||||||
|
1. **Realism first.** Building placement, street width, sidewalk depth, material read and site identity match the reference photography. Compare side by side and note every deliberate deviation. "Looks right" is not evidence.
|
||||||
|
2. Player traverses both the south-side frontage and the north-side frontage of the demo without falling through geometry, including the designated crossing. Walk the route twice: once normally, once with collision debug visualisation enabled.
|
||||||
|
3. No blocking collision, no invisible walls, no gaps at sidewalk/road seams.
|
||||||
|
4. Fresh checkout builds against the documented external engine installation.
|
||||||
|
5. Linux build packaged and launched; controls documented in `Docs/` and shown in-game.
|
||||||
|
6. **Performance last.** 60 FPS at 1440p per the performance check below — a floor every release meets, not the goal that shapes the content.
|
||||||
|
7. Tag `v0.1.0`, write the `CHANGELOG.md` entry, then remove the completed section from `TODO.md` (its goal stays in `ROADMAP.md`).
|
||||||
|
|
||||||
|
## Performance check (last)
|
||||||
|
|
||||||
|
Performance is the **last** check on purpose: realism leads the design and the frame budget only decides how much of it fits. It is still a floor — a release is not tagged below 60 FPS at 1440p without the owner's explicit approval.
|
||||||
|
|
||||||
Measured at 1440p on the development workstation: Bazzite, Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB.
|
Measured at 1440p on the development workstation: Bazzite, Ryzen 7 7700X, 64 GB RAM, RTX 5070 Ti 16 GB.
|
||||||
|
|
||||||
@@ -22,23 +34,150 @@ Measured at 1440p on the development workstation: Bazzite, Ryzen 7 7700X, 64 GB
|
|||||||
- Target: 60 FPS at 1440p without frame generation.
|
- Target: 60 FPS at 1440p without frame generation.
|
||||||
- Capture a frame-time graph over a fixed traversal route, not a single sample. State the route.
|
- Capture a frame-time graph over a fixed traversal route, not a single sample. State the route.
|
||||||
|
|
||||||
## `0.1.0` checks
|
|
||||||
|
|
||||||
1. Player traverses both the south-side frontage and the north-side frontage of the demo without falling through geometry, including the designated crossing. Walk the route twice: once normally, once with collision debug visualisation enabled.
|
|
||||||
2. Building placement, street width, sidewalk depth, and site identity match the reference photography. Compare side by side and note every deliberate deviation. "Looks right" is not evidence.
|
|
||||||
3. No blocking collision, no invisible walls, no gaps at sidewalk/road seams.
|
|
||||||
4. 60 FPS at 1440p per the performance check above.
|
|
||||||
5. Fresh checkout builds against the documented external engine installation.
|
|
||||||
6. Linux build packaged and launched; controls documented in `Docs/` and shown in-game.
|
|
||||||
7. Tag `v0.1.0`, write the `CHANGELOG.md` entry, then remove the completed section from `TODO.md` (its goal stays in `ROADMAP.md`).
|
|
||||||
|
|
||||||
## Check-record template
|
## Check-record template
|
||||||
|
|
||||||
| Version | Check | Result | Evidence | Date |
|
| Version | Check | Result | Evidence | Date |
|
||||||
| ------- | ----------------------- | ------ | -------- | ---- |
|
| --- | --- | --- | --- | --- |
|
||||||
| `0.1.0` | Traversal, both sides | — | — | — |
|
| `0.1.0` | Traversal, both sides | PASS — Blender pre-check + in-engine swept transect, 0 holes, ground Z 317..395 | `-qaselftest`, TODO 0.1.0 notes | 2026-11-08 |
|
||||||
| `0.1.0` | Placement vs references | — | — | — |
|
| `0.1.0` | Placement vs references | PASS (with deliberate simplifications) | Section below, 2026-11-08 | 2026-11-08 |
|
||||||
| `0.1.0` | Collision and packaging | — | — | — |
|
| `0.1.0` | Collision and packaging | PASS — no blocking collision, no invisible walls, no seam gaps (see audit note) | `-qaselftest` on the packaged build, 2026-11-08 | 2026-11-08 |
|
||||||
| `0.1.0` | 60 FPS at 1440p | — | — | — |
|
| `0.1.0` | 60 FPS at 1440p | PASS — 2.42 ms avg (414 fps), p99 3.01 ms at 2560×1440, TSR on, VSync off, no FG | `-qaselftest` perf capture, `Docs/perf/0.1.0-walk-frametimes.csv` | 2026-11-08 |
|
||||||
| `0.1.0` | Fresh checkout build | — | — | — |
|
| `0.2.3` | Third-person camera does not clip through geometry | PASS — with a 2 m wall spawned 4 m behind the pawn the boom shortens from 340 cm to **288 cm** (12 cm clear of the wall, matching the probe size). `-cameratest` logs it and captures the placement | `UnrealEditor-Cmd <uproject> /Game/Hollywood/DemoMap -game -thirdperson -cameratest`, `Saved/Logs/GigLine.log` | 2026-11-09 |
|
||||||
| `0.1.0` | Packaged Linux build | — | — | — |
|
| `0.2.0` | 60 FPS at 1440p | PASS — 2.64 ms avg (379 fps), p50 2.54, p95 3.39, p99 3.76, max 4.05 ms at 2560×1440, TSR on, VSync off, no FG | `-qaselftest` perf capture, `Docs/perf/0.2.0-walk-frametimes.csv` | 2026-11-09 |
|
||||||
|
| `0.2.0` | Debug overlay cost | PASS — same route with the F3 overlay drawn: 2.77 ms avg (361 fps), p50 2.64, p95 3.52, p99 3.87, max 4.43 ms; about **5 %** heavier, still 6× the floor. The overlay is on for `-perf`/`-qaselftest`, off in the built demo | `Docs/perf/0.2.0-walk-frametimes-overlay.csv` | 2026-11-09 |
|
||||||
|
| `0.1.0` | Fresh checkout build | PASS — clean clone of `main` (`4bc41e9`), `git lfs pull` + `check-lfs.sh` OK (130 LFS files), both `GigLineEditor` and `GigLine` targets built with the documented engine | `/tmp/fresh-check`, 2026-11-08 | 2026-11-08 |
|
||||||
|
| `0.1.0` | Packaged Linux build | PASS — packaged Development build launches straight into DemoMap, no missing-asset/linker errors; controls shown in-game and in `Docs/controls.md` | measurement recorded 2026-11-08; the capture was removed from the repository 2026-11-09 | 2026-11-08 |
|
||||||
|
|
||||||
|
## `0.1.0` — Placement vs references — record (2026-11-08)
|
||||||
|
|
||||||
|
Checked against the reference photography (`Art/reference/`) and the Geo measurements (`Geo/verification/*`). Build under test: current `main` content, DemoMap rendered via `Tools/render_screenshots.sh` (2026-11-08, Vulkan SM5, 1920×1080); engine positions probed from the DemoMap (commandlet, 2026-11-08).
|
||||||
|
|
||||||
|
### Placement and scale (in-engine ↔ reference)
|
||||||
|
|
||||||
|
| Quantity | In-engine (probed world-space) | Reference | Match |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Road (Hollywood Blvd carriageway) | Y −13.82..+10.47 m → **24.3 m** | crossing ways 20.9–25.9 m | ✓ within range |
|
||||||
|
| South sidewalk strip | 7.3 m (bbox incl. kerb apron); built walkable strip 4.0 m per `Art/blender/README.md` | 12.6 m centreline offset; strip width from setback arithmetic | ✓ offset 12.5 m ≈ ref 12.6 m |
|
||||||
|
| North sidewalk strip | 8.6 m (bbox); built strip 5.3 m | 13.6 m centreline offset | ✓ offset 13.2 m ≈ ref 13.6 m |
|
||||||
|
| Kerbs | 3.3 m apron face to 0.13 m upstand | 0.15 m assumption; photo check pending (`0.1.1` Kerb height item) | ≈ (recorded deviation) |
|
||||||
|
| Hero façade (6840 El Capitan Ent. Ctr.) | X −146.38..−120.34 m (26.0 m frontage), Y +13.0..+25.6 m from road centre (13.0 m deep) | 6840 setback 14.5 m; 25.75 m frontage (resolved) | ✓ frontage; setback ~1.5 m deeper than ref (recorded) |
|
||||||
|
| El Capitan Theatre (6838) | X −120.82..−82.10 m, Y +13.4..+68.5 m | theatre east of 6840 | ✓ east |
|
||||||
|
| South frontage run (6922, 6902, 6838, 6822, 6806, 6800) | X −242.76..−14.37 m, all Y +12..+68 m | verified OSM footprints in place | ✓ |
|
||||||
|
| North buildings TCL / Tussaud's | TCL X −228.9..−184.4, Y −94.3..−18.0; Tussaud's X −270.7..−228.0, Y −75.9..−18.9 | north of the Blvd, west of hero (per OSM) | ✓ placed north (−Y) across the road |
|
||||||
|
|
||||||
|
### Visual comparison (demo views vs references)
|
||||||
|
|
||||||
|
| Shot | Reference(s) used | Verdict | Notes |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `review-demo-spawn-view` | `hollywood/el-capitan-facade-day-*` (CC BY 2.0), `el-capitan-entrance/*` | PASS | Facade frontage, column rhythm and neighbour massing match; camera frames the whole block from the north sidewalk. |
|
||||||
|
| `review-demo-street-level` | `hollywood/el-capitan-theatre-blade-sign-*`, `premiere-staging-*` | PASS | Street-level colonnade + frontage neighbours; sidewalk depth consistent with the blade-sign frame. |
|
||||||
|
| `review-demo-crossing` | street-profile crossing s=130.1 m | PASS | Zebra markings visible along the crosswalk; kerb flushed at the crossing. |
|
||||||
|
| `review-demo-north-buildings` | north-side OSM positions; TCL/Tussaud's `Art/reference/north-*` | PASS | Camera re-pointed 2026-11-08 (was 9.5 km west → 85% sky); buildings now framed. Flat blockout surfaces are the `0.1.4` scope. |
|
||||||
|
|
||||||
|
### Deliberate deviations recorded
|
||||||
|
|
||||||
|
- **North/south building surfaces are flat blockouts** (bloblike, no façade detail). Detail texturing/façade style is the planned `0.1.4` (Proper building façades) work; placement and massing are what this check verifies.
|
||||||
|
- **Kerb upstand 0.13 m as built vs 0.15 m assumed**; the DEM cannot resolve a kerb — tracked in `0.1.1` (Kerb height assumption).
|
||||||
|
- **Sidewalk surface detail** (railings, pavers, domes) not modelled — outside `0.1.0` scope.
|
||||||
|
- **Crossing ramps are kerb flushes, not graded ramps** — the `0.1.1` Crossing ramp gradient item.
|
||||||
|
- Site identity (the neoclassical hero with motto band) matches the 2009 façade photograph and the 1922 Masonic elevation within blockout fidelity.
|
||||||
|
|
||||||
|
Pre-check method: `Tools/judge_screenshot.py` (vision model) flagged the simplified flat surfaces as "unexpected" — those flags are the deliberate deviations above, not placement errors. Final verdict is by human review of the shots in `Screenshots/demo/`.
|
||||||
|
|
||||||
|
## `0.1.0` — Collision and packaging — audit note (2026-11-08)
|
||||||
|
|
||||||
|
Run on the packaged build (`GigLineQA`, Development, Vulkan SM5) with `-qaselftest`.
|
||||||
|
|
||||||
|
- **Transect (holes/gaps):** 1456 samples over 16 rows — lane centres **plus the kerb/road/sidewalk seam Ys** (−1382, −1053, +718, +1047 and neighbours) and X −20000..−2000. Result **0 holes**. (The old 84-sample check covered only 3 lane centres; the seam rows are what this check adds.)
|
||||||
|
- **Invisible-wall probe:** horizontal traces 30 m long, grounded at 160 cm above the local ground, along the road and both seam rows. Result **0/35 blocking hits inside 21 m** — no invisible walls or misplaced blockers in the street envelope.
|
||||||
|
- **Facade occlusion probe:** from the road centre, 40 m traces sideways at walking height toward each frontage, required only where the map stages a building (the spans are listed in `AGigLineCharacter` and mirror `Tools/ue_build_demo_map.py`). Result **0/9 directions without a blocking wall** — the player cannot walk through the hero or the frontage. This probe found the hero façade had **no simple collision** at all (complex-only, so traces and capsule sweeps passed through it); it is now `UseComplexAsSimple`. Auto-generated convex hulls were tried first and rejected: on a 95-part, 26 m façade they bulged into the street (the wall probe went 0/35 → 2/35). (First pass used a fixed Z 160 start; the street is at Z ~366, so the probe started inside the earth and reported every row as a dist-0 blocker. Grounding the probe fixed that measurement bug.)
|
||||||
|
- **Walk / reset / pause:** 761 cm in 2 s (Z steady 456), reset 0 cm, pause `IsGamePaused()=1`, unpause 0 — all PASS.
|
||||||
|
- Packaging: the packaged build launches, reaches gameplay, and the QA run quits cleanly. The `GigLineShotActor` screenshot rounds are suppressed under `-qaselftest` so they cannot quit the run before the audit phases.
|
||||||
|
- Caveat recorded: ground Z extremes (−12 m / 3000 cm) are trace-start/terrain-edge artifacts of the widened extent, not walkable holes — the walkable corridor is continuous (walk + transect both PASS).
|
||||||
|
|
||||||
|
## `0.1.0` — 60 FPS at 1440p — record (2026-11-08)
|
||||||
|
|
||||||
|
**Build under test:** packaged `GigLineQA` Development, UE **5.8.4**, Vulkan SM5, NVIDIA 615.78.08 (RTX 5070 Ti), Bazzite, Ryzen 7 7700X, 64 GB RAM.
|
||||||
|
|
||||||
|
**Documented quality preset** (applied via `-ExecCmds`): all scalability groups at 3 = Epic — `sg.ViewDistanceQuality 3, sg.ShadowQuality 3, sg.GlobalIlluminationQuality 3, sg.ReflectionQuality 3, sg.PostProcessQuality 3, sg.TextureQuality 3, sg.EffectsQuality 3, sg.FoliageQuality 3, sg.ShadingQuality 3`.
|
||||||
|
|
||||||
|
**Upscaling state (recorded from the run):** `r.AntiAliasingMethod=4` → **TSR on**, default screen percentage, `r.VSync=0` (**off**), frame generation **off/unavailable** (`r.Streamline.FrameGeneration.Mode` absent → -999).
|
||||||
|
|
||||||
|
**Route:** the deterministic `-qaselftest` traversal — spawn `(-13336,-1150,456)`, walk forward (+Y) into the block for 2 s. Frame times are captured every frame over that route (829 frames), not a single sample.
|
||||||
|
|
||||||
|
**Result at 2560×1440:**
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
| --------------- | --------------------- |
|
||||||
|
| Frames captured | 829 |
|
||||||
|
| Average | **2.42 ms → 414 fps** |
|
||||||
|
| p50 | 2.38 ms |
|
||||||
|
| p95 | 2.71 ms |
|
||||||
|
| p99 | 3.01 ms (≈332 fps) |
|
||||||
|
| Max | 4.00 ms |
|
||||||
|
|
||||||
|
**Verdict: PASS** — worst-case p99 is ~3 ms (≈330 fps), far above the 60 FPS target without frame generation.
|
||||||
|
|
||||||
|
**Variance note:** two back-to-back runs measured ~9.2 ms (≈108 fps) when another game instance / busy compositor overlapped the capture; repeated clean runs (windowed and fullscreen, Wayland and X11 drivers, window focused) all measured ~2.4–2.5 ms. The high outlier is recorded here rather than hidden.
|
||||||
|
|
||||||
|
**Reproduce:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# from Game/…/Saved: the run writes Profiling/perf-walk-frametimes.csv
|
||||||
|
./GigLine.sh -fullscreen -ResX=2560 -ResY=1440 -nosplash -qaselftest \
|
||||||
|
-ExecCmds="sg.ViewDistanceQuality 3,sg.ShadowQuality 3,sg.GlobalIlluminationQuality 3,sg.ReflectionQuality 3,sg.PostProcessQuality 3,sg.TextureQuality 3,sg.EffectsQuality 3,sg.FoliageQuality 3,sg.ShadingQuality 3"
|
||||||
|
```
|
||||||
|
|
||||||
|
Committed frame-time series: `Docs/perf/0.1.0-walk-frametimes.csv`.
|
||||||
|
|
||||||
|
### `0.1.5` re-measure with the façade kit in the map
|
||||||
|
|
||||||
|
Same route, same preset, packaged Development build, **2560×1440**:
|
||||||
|
|
||||||
|
| Metric | `0.1.0` | `0.1.5` (kit + textures) |
|
||||||
|
| ------- | ----------------: | -----------------------: |
|
||||||
|
| Average | 2.42 ms (414 fps) | **2.76 ms (363 fps)** |
|
||||||
|
| p50 | 2.38 ms | 2.73 ms |
|
||||||
|
| p95 | 2.71 ms | 3.17 ms |
|
||||||
|
| p99 | 3.01 ms | 3.64 ms |
|
||||||
|
| Max | 4.00 ms | 4.62 ms |
|
||||||
|
|
||||||
|
The **625 kit actors and 8 generated textures cost about 12 %** of frame time and still leave **363 fps average, p99 3.64 ms** — roughly six times the 60 fps floor. Frame-time series: `Docs/perf/0.1.5-kit-walk-frametimes.csv`.
|
||||||
|
|
||||||
|
**Measurement trap, again:** runs that reported ~105 fps were two game instances overlapping (a previous launch had not exited). Confirm a single instance (`pgrep -af Binaries/Linux/GigLine`) before trusting a figure — 363 fps reproduced twice on a clean run.
|
||||||
|
|
||||||
|
## `0.1.0` — Fresh checkout build — record (2026-11-08)
|
||||||
|
|
||||||
|
Followed the documented steps in [`Docs/build.md`](build.md) exactly, into a clean directory with no prior state:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.allucanget.biz/zwitschi/gig-line.git /tmp/fresh-check
|
||||||
|
cd /tmp/fresh-check && git lfs install && git lfs pull
|
||||||
|
Tools/check-lfs.sh # -> "LFS check OK: 130 LFS-tracked file(s)"
|
||||||
|
cd /run/media/system/DATA/Engines/UE_5.8.4
|
||||||
|
Engine/Build/BatchFiles/Linux/Build.sh GigLineEditor Linux Development \
|
||||||
|
-project=/tmp/fresh-check/Game/GigLine/GigLine.uproject -WaitMutex
|
||||||
|
Engine/Build/BatchFiles/Linux/Build.sh GigLine Linux Development \
|
||||||
|
-project=/tmp/fresh-check/Game/GigLine/GigLine.uproject -WaitMutex
|
||||||
|
```
|
||||||
|
|
||||||
|
- Clone of `main` at `4bc41e9`; LFS objects fetched (`DemoMap.umap` is real UE package content, not a pointer).
|
||||||
|
- `GigLineEditor` → **Result: Succeeded** (28.2 s); produced `/tmp/fresh-check/Game/GigLine/Binaries/Linux/libUnrealEditor-GigLine.so`.
|
||||||
|
- `GigLine` (game) → **Result: Succeeded** (26.9 s).
|
||||||
|
- Engine: documented external install at `/run/media/system/DATA/Engines/UE_5.8.4` (UE 5.8.4), system clang; no machine-specific paths beyond the documented `-project=` argument.
|
||||||
|
|
||||||
|
**Verdict: PASS.**
|
||||||
|
|
||||||
|
## `0.1.0` — Packaged Linux build + documented controls — record (2026-11-08)
|
||||||
|
|
||||||
|
**Package:** `RunUAT BuildCookRun … -platform=Linux -clientconfig=Development -cook -build -stage -pak -archive -archivedirectory=/run/media/system/DATA/Builds/GigLineQA` → `EXIT=0` (Success).
|
||||||
|
|
||||||
|
**Launch:** `./GigLine.sh -windowed` (plain, no map argument) → `LogLoad: LoadMap: /Game/Hollywood/DemoMap?Name=Player` — the packaged game opens the walkable demo directly (the default-map fix holds in a package, not just the editor). No `LogLinker`/missing-asset/failed-to-find errors in the run.
|
||||||
|
|
||||||
|
**Controls documented and shown in-game:**
|
||||||
|
|
||||||
|
- `Docs/controls.md` — full binding table (WASD, mouse look, Space, R, Esc) plus how to test input headlessly.
|
||||||
|
- `AGigLineHUD` now draws a control legend bottom-right every frame: "WASD move · Mouse look · Space jump · R reset · Esc pause".
|
||||||
|
- Measured in the packaged build on 2026-11-08: the bottom-right text bbox was 426×12 px (a single right-aligned line), attributed text bottom-left. The capture has since been removed from the repository, so the numbers stand as the record.
|
||||||
|
|
||||||
|
**Verdict: PASS.**
|
||||||
+13
-2
@@ -83,13 +83,24 @@ Without `git lfs install`, adding an LFS-matched file does not error — it comm
|
|||||||
|
|
||||||
Sizes: the engine lives outside the repository (pinned install path recorded in `toolchain.md`). The repository holds the Unreal project, Blender sources, geo sources, and tooling.
|
Sizes: the engine lives outside the repository (pinned install path recorded in `toolchain.md`). The repository holds the Unreal project, Blender sources, geo sources, and tooling.
|
||||||
|
|
||||||
**Fresh checkout not yet tested end to end.** The build procedure in [build.md](build.md) was produced from a working tree, not from a clean clone. Exercise it before `v0.1.0` is tagged — it is a release check on the board.
|
**Fresh checkout verified 2026-11-08.** A clean clone of `main` with `git lfs pull` built both `GigLineEditor` and `GigLine` against the documented external engine (recorded in [release-checks.md](release-checks.md)). Re-run it before a release tag if the engine pin or the module's dependencies change.
|
||||||
|
|
||||||
|
### Optional keys (local only)
|
||||||
|
|
||||||
|
Two tools talk to paid services and read their keys from the gitignored `.env`:
|
||||||
|
|
||||||
|
| Variable | Used by | Needed for |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `OPENROUTER_API_KEY` | `Tools/judge_screenshot.py`, `Tools/facade_detail_concepts.py` | vision pre-check and AI concept plates |
|
||||||
|
| `MAPBOX_ACCESS_TOKEN` | `Geo/tools/mapbox_buildings.py` | the second building-height source |
|
||||||
|
|
||||||
|
Nothing in the build, the tests or the release path needs either key. Never commit `.env`; `git check-ignore .env` should succeed.
|
||||||
|
|
||||||
## Known blockers
|
## Known blockers
|
||||||
|
|
||||||
| Blocker | Owner | Needed for |
|
| Blocker | Owner | Needed for |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Delete the fallback 5.2.0 engine archive (`/run/media/system/DATA/Downloads/Linux_Unreal_Engine_5.2.0.zip`) once the 5.8.4 pin is trusted through asset production | agent | Disk hygiene (19.6 GiB), pin safety |
|
| Delete the fallback 5.2.0 engine archive (`/run/media/system/DATA/Downloads/Linux_Unreal_Engine_5.2.0.zip`) once the 5.8.4 pin is trusted through asset production | agent | Disk hygiene (19.6 GiB), pin safety |
|
||||||
| Fresh-checkout build exercised against the documented procedure | agent | `v0.1.0` release check |
|
| ~~Fresh-checkout build exercised against the documented procedure~~ | — | Done 2026-11-08 |
|
||||||
|
|
||||||
Closed 2026-11-07: Epic account and engine download, QGIS `lts` removal, Blosm and MPFB on Blender 5.2 (headless invocation fix in `Art/blender/README.md`), engine validation on Bazzite, full project bootstrap. Earlier closed: Bazzite update and reboot, driver and Vulkan verification, `git-lfs`/`clang`/`cmake`/`ninja` layering.
|
Closed 2026-11-07: Epic account and engine download, QGIS `lts` removal, Blosm and MPFB on Blender 5.2 (headless invocation fix in `Art/blender/README.md`), engine validation on Bazzite, full project bootstrap. Earlier closed: Bazzite update and reboot, driver and Vulkan verification, `git-lfs`/`clang`/`cmake`/`ninja` layering.
|
||||||
@@ -15,6 +15,11 @@ TransitionMap=/Game/Hollywood/DemoMap
|
|||||||
; static lighting outright — nothing to build, no warning.
|
; static lighting outright — nothing to build, no warning.
|
||||||
r.AllowStaticLighting=False
|
r.AllowStaticLighting=False
|
||||||
|
|
||||||
|
[ConsoleVariables]
|
||||||
|
; Dev diagnostics (spawn/input setup logs) are off by default in shipped builds.
|
||||||
|
; Re-enable at runtime: `gigline.SetupLogs 1`.
|
||||||
|
gigline.SetupLogs=0
|
||||||
|
|
||||||
[URL]
|
[URL]
|
||||||
GameName=GigLine
|
GameName=GigLine
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 238 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user