Compare commits
61
Commits
v0.1.6
..
98eae6f3e9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98eae6f3e9 | ||
|
|
15cc6cbdd0 | ||
|
|
bb12ce8c33 | ||
|
|
046e2c8b9e | ||
|
|
cb94438e0d | ||
|
|
bb8ae3eb4b | ||
|
|
a17e982561 | ||
|
|
b50afa4bcd | ||
|
|
021aa56121 | ||
|
|
1cddfbfc68 | ||
|
|
627737062b | ||
|
|
5dd53ac30b | ||
|
|
4f3ed20e49 | ||
|
|
2e0421480c | ||
|
|
02cadd4964 | ||
|
|
a72bf85b2e | ||
|
|
73b5bd6cd1 | ||
|
|
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 |
No files matched your search
@@ -141,7 +141,7 @@ Keep the tools standard-library-only where practical; if a third-party import is
|
||||
|
||||
## 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.
|
||||
[`Docs/Architecture/`](Docs/Architecture/) is the arc42 documentation: [`README.md`](Docs/Architecture/README.md) provides the overview and links to twelve numbered section files; `about-arc42.md` records the template attribution. **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:
|
||||
|
||||
@@ -160,7 +160,7 @@ 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.
|
||||
- **Keep the index current.** `Docs/Architecture/README.md` links to the canonical section pages; update it when the structure or section list changes.
|
||||
- **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.
|
||||
|
||||
@@ -210,7 +210,7 @@ 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/`).
|
||||
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`: 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 point is that the review happens in the file; a path alone is not a review. 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.
|
||||
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`.
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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.
+116
@@ -8,6 +8,122 @@ Format: [Keep a Changelog](https://keepachangelog.com/) style, versions follow [
|
||||
|
||||
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.
|
||||
|
||||
@@ -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 |
|
||||
| `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: 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 |
|
||||
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
||||
| `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
|
||||
|
||||
@@ -55,6 +57,9 @@ Python scripts in `Tools/` drive the content pipeline:
|
||||
|
||||
| Script group | Purpose |
|
||||
| --- | --- |
|
||||
| `export_*`, `hero_facade_build` | Blender headless export (FBX) |
|
||||
| `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) |
|
||||
|
||||
@@ -63,3 +63,11 @@
|
||||
- **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.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Gig Line Architecture Documentation
|
||||
description: Architecture documentation for the Gig Line Linux-first Unreal Engine 5 demo around 6840 Hollywood Blvd.
|
||||
status: v0.1.0
|
||||
date: 2026-11-08
|
||||
---
|
||||
|
||||
Gig Line is a Linux-first Unreal Engine 5 walking and driving demo around 6840 Hollywood Boulevard and the El Capitan Entertainment Centre. The architecture prioritises visual realism and geographically faithful placement while maintaining a fully walkable scene, reproducible asset pipeline, documented provenance, and a 60 FPS floor at 1440p.
|
||||
|
||||
This directory contains the canonical arc42 documentation. Each section is maintained independently; update the relevant page in the same change as its implementation. Project work and future scope remain in [TODO.md](../../TODO.md) and [ROADMAP.md](../../ROADMAP.md).
|
||||
|
||||
## Sections
|
||||
|
||||
1. [Introduction and Goals](01_introduction_and_goals.md)
|
||||
2. [Architecture Constraints](02_architecture_constraints.md)
|
||||
3. [Context and Scope](03_context_and_scope.md)
|
||||
4. [Solution Strategy](04_solution_strategy.md)
|
||||
5. [Building Block View](05_building_block_view.md)
|
||||
6. [Runtime View](06_runtime_view.md)
|
||||
7. [Deployment View](07_deployment_view.md)
|
||||
8. [Cross-cutting Concepts](08_concepts.md)
|
||||
9. [Architecture Decisions](09_architecture_decisions.md)
|
||||
10. [Quality Requirements](10_quality_requirements.md)
|
||||
11. [Risks and Technical Debt](11_technical_risks.md)
|
||||
12. [Glossary](12_glossary.md)
|
||||
|
||||
See also [About arc42](about-arc42.md).
|
||||
@@ -1,557 +0,0 @@
|
||||
---
|
||||
title: Gig Line Architecture Documentation
|
||||
description: Architecture documentation for the Gig Line Linux-first Unreal Engine 5 demo around 6840 Hollywood Blvd.
|
||||
status: v0.1.0
|
||||
date: 2026-11-08
|
||||
---
|
||||
|
||||
# Introduction and Goals
|
||||
|
||||
Gig Line is a Linux-first Unreal Engine 5 game that reconstructs a walkable (and eventually drivable) stretch of Hollywood Boulevard around 6840 Hollywood Blvd / El Capitan Entertainment Centre. The initial release (`0.1.0`) delivers a first-person walking demo of the south-side block between Highland Avenue and Orange Drive, plus north-side buildings within 50 m of the frontage.
|
||||
|
||||
## Requirements Overview
|
||||
|
||||
| ID | Description |
|
||||
| --- | --- |
|
||||
| F-1 | Walk both sides of Hollywood Blvd in the demo area without falling through geometry |
|
||||
| F-2 | First-person movement (WASD + mouse look), jump, reset (R), pause (Escape) |
|
||||
| F-3 | Fixed daytime lighting and atmosphere (sun, sky, fog, exposure) |
|
||||
| F-5 | Designated street crossing with zebra markings at signalised crossings |
|
||||
| F-6 | Building façades recognisable against reference photography |
|
||||
| F-7 | Terrain, road, and sidewalk follow real-world DEM elevation |
|
||||
| F-8 | 60 FPS at 1440p on the documented workstation and quality preset |
|
||||
|
||||
Full requirements and progress are in [TODO.md](../../TODO.md); version direction is in [ROADMAP.md](../../ROADMAP.md).
|
||||
|
||||
## Quality Goals
|
||||
|
||||
| Priority | Quality Goal | Scenario |
|
||||
| --- | --- | --- |
|
||||
| 1 | **Visual realism** | Renders read as the reference photographs: façade identity, proportion, material and light — judged side by side, shot against photo |
|
||||
| 2 | **Geographic fidelity** | Building placement and street scale match the measured data and the photographs |
|
||||
| 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 |
|
||||
| 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
|
||||
|
||||
| Role | Contact | Expectations |
|
||||
| --- | --- | --- |
|
||||
| Owner / Director | zwitschi | Sets scope, approves screenshots, cuts release tags |
|
||||
| AI coding agents | multiple sessions | Read `AGENTS.md`, `TODO.md`, `ROADMAP.md`, and this document for architecture constraints; never commit directly to `main` |
|
||||
| Players | end users | Walk the demo at 60 FPS without falling through the world; see a recognisable Hollywood block |
|
||||
|
||||
# Architecture Constraints
|
||||
|
||||
## Technical Constraints
|
||||
|
||||
| Constraint | Explanation |
|
||||
| --- | --- |
|
||||
| Engine: Unreal 5.8.4 | Pinned; no bundled Linux clang — uses system clang 23.1.4. Game targets use `BuildSettingsVersion.V7`. |
|
||||
| Platform: Linux first | Developed and tested on Bazzite Linux (Fedora 45 base). Windows builds ship but are secondary. |
|
||||
| GPU: RTX 5070 Ti 16 GB | Dev workstation target. Vulkan RHI; open kernel module driver 615.78.08. |
|
||||
| No static lighting | `r.AllowStaticLighting=False`. The demo is a fixed daytime scene lit entirely dynamically to avoid "LIGHTING NEEDS TO BE REBUILT" warnings. |
|
||||
| Blender→UE via FBX | Flat diffuse colours do not survive FBX→Unreal import. All materials are authored in UE. |
|
||||
| Terrain collision | UE 5.8 exposes `CollisionTraceFlag` (not `bUseComplexAsSimpleCollision`); Python cannot set it. Must use C++ helper `UGigLineAssetTools::SetComplexCollisionAsSimple`. |
|
||||
| Coordinate convention | South = +Y, north = −Y (ground truth = street mesh orientation). 1 m in Blender = 100 cm in Unreal. |
|
||||
|
||||
## Organisational Constraints
|
||||
|
||||
| Constraint | Explanation |
|
||||
| --- | --- |
|
||||
| Squash-merge to `main` | Every PR is squash-merged for a linear history. No direct commits to `main` except integration merges. |
|
||||
| Visual review required | Any change affecting appearance must produce screenshots for human approval before being marked done. |
|
||||
| Asset provenance | Every committed asset must have verified licence and redistribution permission recorded in `THIRD_PARTY_NOTICES.md`. |
|
||||
| Reference photography | Local only, gitignored, never committed. Used for façade work under fair-use / internal-development rationale. |
|
||||
| LFS for binaries | `.uasset`, `.umap`, `.blend` tracked with Git LFS; `Binaries/`, `Intermediate/`, `Saved/` are gitignored. |
|
||||
|
||||
## Conventions
|
||||
|
||||
| Convention | Explanation |
|
||||
| --- | --- |
|
||||
| Semantic versioning | `MAJOR.MINOR.PATCH`. `0.x` documents breaking changes. `1.0.0` = agreed game scope. |
|
||||
| Task tracking in `TODO.md` | Single central task list. `- [ ]` open, `- [-]` or `- [~]` in progress, `- [x]` done, `- [A]` active, `- [D]` deferred. |
|
||||
| Headless Blender | All Blender work driven by `bpy` scripts in `Tools/`, not MCP. Blender skills are method guides only. |
|
||||
| Named export presets | `ue_metric_v1` for static meshes, `ue_character_v1` for skeletal. Every exporter calls the metre→centimetre conversion. |
|
||||
|
||||
# Context and Scope
|
||||
|
||||
## Business Context
|
||||
|
||||
The system is a self-contained single-player game. It has no server backend, no multiplayer, and no live service dependencies. Its communication partners are:
|
||||
|
||||
| Partner | Inbound | Outbound |
|
||||
| --- | --- | --- |
|
||||
| Player (keyboard/mouse) | WASD, mouse, R (reset), Escape (pause), Space (jump) | Rendered 3D scene + HUD |
|
||||
| OSM data | Extracted building footprints, street geometry, elevation | — |
|
||||
| Filesystem | Engine content (`.uasset`, `.umap`), Blender sources (`.blend`), DEM GeoTIFF | Saved maps, screenshots, packaged build |
|
||||
|
||||
## Technical Context
|
||||
|
||||
| Channel | Protocol / Format | Purpose |
|
||||
| --- | --- | --- |
|
||||
| Keyboard + mouse | Enhanced Input (IA\_\*, IMC_Default) | First-person movement, look, jump, reset, pause |
|
||||
| Vulkan RHI | GPU rendering | Scene display at 60 FPS / 1440p |
|
||||
| FBX | Autodesk FBX (binary) | Blender→Unreal mesh and skeleton transfer |
|
||||
| GeoTIFF | 3DEP 1 m DEM | Terrain heightfield source |
|
||||
| OSM XML | Overpass API extract | Building footprint and street layout source |
|
||||
| Git / LFS | HTTPS to Gitea remote | Source control, binary asset storage |
|
||||
|
||||
# Solution Strategy
|
||||
|
||||
## Technology decisions
|
||||
|
||||
- **Unreal Engine 5.8.4** for rendering, World Partition, physics (Chaos), and the Enhanced Input system. Chosen for its Linux support, open C++ source, and real-time rendering quality.
|
||||
|
||||
- **Blender 5.2 LTS** for all 3D modelling, UV work, and collision mesh authoring. Driven headlessly via `bpy` Python scripts, not MCP.
|
||||
|
||||
- **QGIS 4.2.3** for geographic data cleanup, coordinate conversion (EPSG:26911), and DEM preparation.
|
||||
|
||||
- **Blosm 2.7.28** for OSM building and street blockouts inside Blender (layout data only — not authoritative façade, height, or pavement detail).
|
||||
|
||||
- **MPFB 2.0.18** for human base meshes and baked materials (NPCs in `0.2.0+`).
|
||||
|
||||
## Top-level decomposition
|
||||
|
||||
The system is a single Unreal game module (`GigLine`) with no plugins beyond `EnhancedInput`. Content is organised by domain under `/Game/Hollywood/`:
|
||||
|
||||
- `Site/` — terrain, road, sidewalks, kerbs, crossing markings, site materials
|
||||
|
||||
- `ElCapitan/` — hero façade mesh and materials
|
||||
|
||||
- `Frontage/` — south-side block building meshes
|
||||
|
||||
- `North/` — north-side building meshes
|
||||
|
||||
- `Input/` — Enhanced Input actions and mapping context
|
||||
|
||||
All modelling and geographic processing live outside the game project in `Art/`, `Geo/`, and `Tools/`. The `Game/` directory contains only engine-ready content and C++ source.
|
||||
|
||||
## Quality achievement
|
||||
|
||||
- **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.
|
||||
|
||||
- **Fidelity**: geographic data verified before modelling (footprints, bounds, DEM); building placement checked against street mesh, never in isolation; reference photography drives façade work.
|
||||
|
||||
- **Reproducibility**: pinned toolchain in `Docs/toolchain.md`, named export presets, `Tools/check-lfs.sh` gate, fresh-checkout build procedure in `Docs/build.md`.
|
||||
|
||||
# Building Block View
|
||||
|
||||
## Whitebox Overall System
|
||||
|
||||
The system decomposes into five top-level building blocks:
|
||||
|
||||
| **Name** | **Responsibility** |
|
||||
| --- | --- |
|
||||
| Gameplay | Player pawn, movement, camera, input bindings, HUD, game mode |
|
||||
| Site | Terrain, road, sidewalks, kerbs, crossing markings, site-level collision |
|
||||
| Façades | Hero façade (El Capitan), south block frontage, north-side buildings |
|
||||
| Art Pipeline | Blender models, geographic data, export scripts, import scripts |
|
||||
| QA & Review | Screenshot pipeline, self-test harness, visual review workflow |
|
||||
|
||||
### Gameplay
|
||||
|
||||
C++ classes in `Game/GigLine/Source/GigLine/`:
|
||||
|
||||
| Class | Responsibility | Key detail |
|
||||
| --- | --- | --- |
|
||||
| `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` |
|
||||
| `AGigLineHUD` | HUD text overlay | `DrawText` every frame, bottom-left |
|
||||
| `AGigLineNPCPerson` | NPC prefab (future) | Capsule + visible MPFB body, feet on Z 0 |
|
||||
| `AGigLineShotActor` | Screenshot camera walker | Drives cameras in `-game` mode, `FScreenshotRequest`, quits |
|
||||
| `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`.
|
||||
|
||||
### Site
|
||||
|
||||
Static meshes and materials in `/Game/Hollywood/Site/`:
|
||||
|
||||
| Asset | Role |
|
||||
| --- | --- |
|
||||
| `Terrain_DEM` | Ground heightfield (complex-as-simple collision) |
|
||||
| `Road_Hollywood` | Carriageway surface (block-all collision) |
|
||||
| `Sidewalk_North`, `Sidewalk_South` | Pedestrian surfaces (block-all collision) |
|
||||
| `Kerb_North`, `Kerb_South` | Kerb edges |
|
||||
| `Crossing_Markings` | Zebra markings at signalised crossing |
|
||||
| `M_Asphalt`, `M_Concrete`, `M_KerbConcrete`, `M_Ground`, `M_RoadPaint`, `M_Stucco`, `M_FacadeStone` | Procedural materials (world-space-noise blend + roughness) |
|
||||
|
||||
### Façades
|
||||
|
||||
| Asset | Role |
|
||||
| --- | --- |
|
||||
| `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_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
|
||||
|
||||
Python scripts in `Tools/` drive the content pipeline:
|
||||
|
||||
| Script group | Purpose |
|
||||
| --- | --- |
|
||||
| `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_create_input_assets` | Enhanced Input actions + mapping context |
|
||||
| `render_screenshots.sh` | Screenshot capture pipeline |
|
||||
| `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).
|
||||
|
||||
### QA & Review
|
||||
|
||||
- `AGigLineShotActor` walks fixed cameras in `-game` mode, captures PNGs, and quits.
|
||||
|
||||
- `-qaselftest` switch on `AGigLineCharacter` runs a core-ticker harness: walk 2 s, reset, pause/unpause, ground transect — all PASS/FAIL logged.
|
||||
|
||||
- `Screenshots/` holds committed PNGs and `README.md` approval table.
|
||||
|
||||
## Level 2
|
||||
|
||||
### White Box Gameplay — Input Flow
|
||||
|
||||
1. `AGigLineCharacter::SetupPlayerInputComponent` binds `IA_*` actions to `MoveForward`, `MoveBack`, `MoveStrafe`, `MoveLeft`, `Look`, `StartJump`/`StopJump`, `ResetToStart`, `TogglePause`.
|
||||
|
||||
2. Movement delegates to `ApplyMove(Forward, Strafe)` → `AddMovementInput`.
|
||||
|
||||
3. Look applies yaw/pitch scaled by `LookSensitivity` (Y invertable via `bInvertLookY`).
|
||||
|
||||
4. `ResetToStart` teleports to `StartLocation` (captured on first grounded frame), clears velocity, resets control rotation.
|
||||
|
||||
5. `TogglePause` toggles `APlayerController::SetPause`, swaps input mode between `FInputModeGameOnly` and `FInputModeUIOnly`, shows/hides mouse cursor.
|
||||
|
||||
### White Box Site — Collision Model
|
||||
|
||||
- Every site mesh (road, sidewalks, kerbs, crossing) is `STATIC` with `BlockAll` collision.
|
||||
|
||||
- `Terrain_DEM` uses `CTF_UseComplexAsSimple` (forced by `UGigLineAssetTools` at build time, saved on the asset).
|
||||
|
||||
- The terrain corridor is carved to half-width 10.7 m around the road centreline so the player can walk the carriageway and both sidewalks.
|
||||
|
||||
- Ground Z: north sidewalk 395, road 366, south sidewalk 317 (3.94 m fall along the block, matching the DEM).
|
||||
|
||||
# Runtime View
|
||||
|
||||
## Walk the block
|
||||
|
||||
1. Player launches game → `AGigLineGameModeBase` spawns `AGigLineCharacter` at `PlayerStart` `(-13336, -1150, 600)`.
|
||||
|
||||
2. Character falls 144 cm to road surface (Z 456) and begins walking. `StartLocation` captured on first grounded frame.
|
||||
|
||||
3. Player holds W → `IA_Move` fires → `ApplyMove(1, 0)` → `AddMovementInput(ForwardVector, 1)` → capsule moves at 450 cm/s.
|
||||
|
||||
4. Mouse move → `IA_Look` fires → yaw/pitch applied to controller rotation → camera follows (attached to capsule at 160 cm eye height).
|
||||
|
||||
5. Player presses R → `ResetToStart` → teleport to `StartLocation`/`StartRotation`, `StopMovementImmediately`, reset control rotation.
|
||||
|
||||
6. Player presses Escape → `TogglePause` → `SetPause(true)`, switch to `FInputModeUIOnly`, show cursor. World timers stop; core tickers continue.
|
||||
|
||||
7. Player presses Escape again → `TogglePause` → `SetPause(false)`, switch to `FInputModeGameOnly`, hide cursor.
|
||||
|
||||
## Screenshot capture
|
||||
|
||||
1. `Tools/render_screenshots.sh` compiles editor, builds `ReviewMap` from `Tools/ue_build_review_map.py`, launches game in `-game` mode.
|
||||
|
||||
2. `AGigLineShotActor` iterates the camera list, sets view, calls `HighResShot 1280x720`, waits for capture.
|
||||
|
||||
3. On last camera, requests engine quit. PNGs are copied to `Screenshots/` and committed.
|
||||
|
||||
## QA self-test (`-qaselftest`)
|
||||
|
||||
1. Core ticker starts at `BeginPlay` (not a world timer — world timers freeze on pause).
|
||||
|
||||
2. 1.0 s: begin driving forward input.
|
||||
|
||||
3. 3.0 s: stop, measure displacement (> 200 cm = PASS).
|
||||
|
||||
4. 3.5 s: call `ResetToStart`.
|
||||
|
||||
5. 4.0 s: measure distance from spawn (< 100 cm = PASS).
|
||||
|
||||
6. 4.5 s: call `TogglePause`, check `IsGamePaused()` (= true = PASS).
|
||||
|
||||
7. 5.5 s: call `TogglePause`, check `IsGamePaused()` (= false = PASS).
|
||||
|
||||
8. 6.0 s: swept ground transect across three lanes (Y −1400, −167, +1000), X −14900 to −9420 at 200 cm spacing. 84 samples, 0 holes = PASS.
|
||||
|
||||
9. 7.0 s: final verdict logged.
|
||||
|
||||
## Build and import pipeline
|
||||
|
||||
1. Blender headless (`Tools/export_*.py`) reads `.blend` files, applies metre→centimetre conversion, exports FBX with `ue_metric_v1` preset.
|
||||
|
||||
2. Unreal headless (`Tools/ue_import_*.py`) imports FBX via Interchange, places meshes at geographic coordinates, sets collision profiles.
|
||||
|
||||
3. `Tools/ue_build_demo_map.py` assembles `DemoMap`: creates/repositions actors, sets lighting, saves map and assets.
|
||||
|
||||
# Deployment View
|
||||
|
||||
## Infrastructure Level 1 — Development Workstation
|
||||
|
||||
| Node | Specification |
|
||||
| --- | --- |
|
||||
| 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) |
|
||||
| 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/GigLineQA/Linux` (packaged Development build, ~1.1 GiB; outside the repository) |
|
||||
|
||||
Motivation
|
||||
Single-machine development. No build farm, no CI pipeline yet. The engine, toolchain, and GPU are all on the same host.
|
||||
|
||||
Quality and Performance Features
|
||||
|
||||
- Vulkan RHI on RTX 5070 Ti, open kernel module driver 615.78.08.
|
||||
|
||||
- System clang 23.1.4 (no bundled engine clang) compiles game code.
|
||||
|
||||
- Build time: ~90 s incremental, ~5 min clean for the editor target.
|
||||
|
||||
Mapping of Building Blocks to Infrastructure
|
||||
|
||||
| Building Block | Infrastructure Element |
|
||||
| --- | --- |
|
||||
| Gameplay (C++) | Dev workstation — compiled to `libUnrealEditor-GigLine.so`, loaded by engine |
|
||||
| Site + Façades (UE content) | Dev workstation — `.uasset`/`.umap` in `Game/GigLine/Content/` |
|
||||
| Art Pipeline (Python/Blender) | Dev workstation — headless Blender 5.2 Flatpak, Python 3.14.8 |
|
||||
| QA & Review | Dev workstation — game run in `-game` mode, PNGs to `Screenshots/` |
|
||||
| Git remote | `git.allucanget.biz` — Gitea instance, LFS-enabled |
|
||||
|
||||
## Infrastructure Level 2 — Packaged Build
|
||||
|
||||
| Element | Detail |
|
||||
| --- | --- |
|
||||
| Linux packaged build | Development config, ~1.1 GiB. Contains engine binaries, game module, cooked content, no editor. |
|
||||
| Run command | `./GigLine.sh -windowed -ResX=2560 -ResY=1440` |
|
||||
|
||||
No server infrastructure. The game is a standalone executable.
|
||||
|
||||
# Cross-cutting Concepts
|
||||
|
||||
## Coordinate system and scale
|
||||
|
||||
- **Source CRS**: EPSG:26911 (UTM zone 11N). Local origin recorded in `Geo/`.
|
||||
|
||||
- **Blender**: metres. East → +X, north → +Y (Blender convention).
|
||||
|
||||
- **Unreal**: centimetres. East → +X, north → **−Y** (confirmed from street mesh: `Sidewalk_North` Y −1912..−1053, `Sidewalk_South` Y +718..+1447).
|
||||
|
||||
- **Conversion**: every exporter calls the metre→centimetre function. Import presets (`ue_metric_v1`, `ue_character_v1`) are named and repeatable.
|
||||
|
||||
Rule: place a building only against a neighbour or street mesh, never in isolation.
|
||||
|
||||
## Collision model
|
||||
|
||||
- Site meshes (road, sidewalks, kerbs, crossing): `STATIC` mobility, `BlockAll` collision profile.
|
||||
|
||||
- Terrain: `STATIC`, `CTF_UseComplexAsSimple` (forced by `UGigLineAssetTools` at build time, saved on the asset — the flag lives on the `UStaticMesh`/`UBodySetup`, not the map).
|
||||
|
||||
- Buildings: `STATIC`, simple collision (convex hull from mesh).
|
||||
|
||||
- Rule: the collision flag must be saved on the asset. Saving only the `.umap` silently reverts it.
|
||||
|
||||
## Lighting
|
||||
|
||||
- Dynamic-only: `r.AllowStaticLighting=False`. All lights are `MOVABLE`.
|
||||
|
||||
- Fixed daytime rig: directional light (sun, −62° pitch), sky light, exponential height fog, post-process volume with fixed exposure.
|
||||
|
||||
- Rationale: avoids "LIGHTING NEEDS TO BE REBUILT" warnings; no bake step; the scene never changes time of day.
|
||||
|
||||
## Materials
|
||||
|
||||
- All materials authored in Unreal, not carried from Blender (FBX import loses diffuse colours).
|
||||
|
||||
- World-space-noise blend nodes for cheap procedural variation (asphalt grain, concrete speckle, stucco roughness).
|
||||
|
||||
- Instance parameters where tunable (e.g. wetness, ageing).
|
||||
|
||||
## Geographic data provenance
|
||||
|
||||
- OSM extract is layout data only — not authoritative for façade, height, or pavement detail.
|
||||
|
||||
- DEM from 3DEP 1 m; elevation verified against cross-sections in `Geo/verification/`.
|
||||
|
||||
- Reference photography (local, gitignored) drives manual façade work.
|
||||
|
||||
## QA harness
|
||||
|
||||
- `-qaselftest`: core ticker (not world timer) so pause cannot freeze the test that proves pause works.
|
||||
|
||||
- `GigLine SIM` / `GigLine GROUND`: TEMP diagnostic logging, to be removed before release tag.
|
||||
|
||||
- Screenshot approval: human must tick `Screenshots/README.md` before visual work is marked done.
|
||||
|
||||
# Architecture Decisions
|
||||
|
||||
## ADR-1: Dynamic-only lighting for the demo
|
||||
|
||||
- **Context**: The demo is a fixed daytime scene. Stationary lights demand a lighting build and produce "LIGHTING NEEDS TO BE REBUILT" warnings.
|
||||
|
||||
- **Decision**: `r.AllowStaticLighting=False`, all lights `MOVABLE`.
|
||||
|
||||
- **Consequences**: No bake step, no warning, simpler iteration. Slightly higher GPU cost per frame (no baked shadows) — acceptable for the demo scope.
|
||||
|
||||
## ADR-2: Materials authored in Unreal, not imported from Blender
|
||||
|
||||
- **Context**: FBX→Unreal import maps all Blender diffuse colours to white. Flat colour materials do not survive the pipeline.
|
||||
|
||||
- **Decision**: Build all materials (asphalt, concrete, stucco, façade stone, road paint) directly in Unreal with procedural nodes.
|
||||
|
||||
- **Consequences**: Materials cannot be previewed in Blender look-dev. Must round-trip to Unreal for visual check. But: full PBR control, world-space noise, no import surprise.
|
||||
|
||||
## ADR-3: Complex-as-simple collision on terrain via C++ helper
|
||||
|
||||
- **Context**: UE 5.8 removed `bUseComplexAsSimpleCollision`. Python cannot set `CollisionTraceFlag` on `StaticMesh`/`BodySetup` at all. The Interchange default is bbox-only simple collision, which placed an invisible lid 8 m above the street.
|
||||
|
||||
- **Decision**: `UGigLineAssetTools::SetComplexCollisionAsSimple` (C++) forces `CTF_UseComplexAsSimple` and saves the asset.
|
||||
|
||||
- **Consequences**: One C++ helper class. The flag must be saved on the asset (not just the map). No Python workaround exists.
|
||||
|
||||
## ADR-4: Reset captures StartLocation on first grounded frame
|
||||
|
||||
- **Context**: `BeginPlay` captures `StartLocation` at the PlayerStart, which is above grade (Z 600) so the capsule does not spawn embedded. Every reset dropped the player 1.4 m back into the air.
|
||||
|
||||
- **Decision**: Repeating 0.25 s timer captures `StartLocation` once the character reports `IsMovingOnGround()`, then clears itself.
|
||||
|
||||
- **Consequences**: Reset is correct. A one-shot timer at 2 s is wrong (fires after walking begins, records mid-stride position).
|
||||
|
||||
## ADR-5: Core ticker for QA self-test, not world timer
|
||||
|
||||
- **Context**: Pausing the game stops world timers. A timer-driven test freezes exactly when it proves pause works.
|
||||
|
||||
- **Decision**: `FTSTicker::GetCoreTicker()` drives the `-qaselftest` harness.
|
||||
|
||||
- **Consequences**: Test runs even while paused. Must be enabled explicitly (`-qaselftest`), never in normal play.
|
||||
|
||||
## ADR-6: South = +Y, north = −Y in Unreal
|
||||
|
||||
- **Context**: The street mesh established this convention: `Sidewalk_North` has Y range −1912..−1053, `Sidewalk_South` has +718..+1447.
|
||||
|
||||
- **Decision**: Adopt it project-wide. Never place a building by assumption; always verify against a street mesh or neighbour.
|
||||
|
||||
- **Consequences**: Matches Blender’s north→+Y after the Y-flip in the `ue_metric_v1` export preset.
|
||||
|
||||
## ADR-7: Headless Blender via bpy scripts, not MCP
|
||||
|
||||
- **Context**: Blender skill packs assume an MCP server; the project does not run one.
|
||||
|
||||
- **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.
|
||||
|
||||
# Quality Requirements
|
||||
|
||||
## 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.
|
||||
|
||||
## Quality Requirements Overview
|
||||
|
||||
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 |
|
||||
| --- | --- | --- |
|
||||
| 1 | Realism / Fidelity | Façade identity, proportion, material and lighting read like the reference photographs when compared side by side |
|
||||
| 2 | Realism / Fidelity | Building placement matches the measured footprints and the photographs (within ~1 m) |
|
||||
| 2 | Realism / Fidelity | Street scale (lane width, sidewalk width) within ~10 cm of the measured profile |
|
||||
| 3 | Reliability / Terrain | Zero raycast holes across sidewalks and carriageway (84-sample transect) |
|
||||
| 3 | Usability | WASD + mouse look, jump, reset (R), pause (Escape) — no tutorial needed |
|
||||
| 4 | Maintainability | Fresh checkout builds with the documented engine installation |
|
||||
| 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
|
||||
|
||||
| ID | Source/Stimulus | Response | Metric |
|
||||
| --- | --- | --- | --- |
|
||||
| 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 | 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 walks both sides of the demo | No fall-through, character stays at ground Z | 0 raycast holes in 84-sample transect |
|
||||
| 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 R | Character teleports to spawn | < 100 cm from `StartLocation` |
|
||||
| QS-6 | Player presses Escape | Game pauses, cursor appears | `IsGamePaused()` = true |
|
||||
| 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
|
||||
|
||||
| ID | Risk / Debt | Priority | Mitigation |
|
||||
| --- | --- | --- | --- |
|
||||
| R-1 | Terrain bbox proxy misdiagnosed as fall-through — already fixed, but the root-cause path (Interchange defaults to simple collision) could recur on reimport | High | `UGigLineAssetTools` runs in the build script; always reassert complex-as-simple after any reimport. Documented in `MEMORY.md` and ADR-3. |
|
||||
| R-2 | Blosm 3Dsimple on Blender 5.2 — worked around, not resolved; `3Drealistic` mode untested | Medium | Pin Blosm 2.7.28 and Blender 5.2 LTS; test realistic mode before depending on it. |
|
||||
| R-3 | Kerb height is an assumption (DEM does not resolve it) | Medium | Record the assumption in `Geo/verification/`; measure from reference photography if possible; mark as unresolved until verified. |
|
||||
| R-5 | `GigLine SIM` / `GigLine GROUND` TEMP diagnostic logging still in `GigLineCharacter.cpp` | Medium | Strip behind a cvar or remove entirely before the `v0.1.0` release tag. |
|
||||
| TD-1 | Materials are Unreal-only — no Blender preview round-trip | Low | Accepted (ADR-2). Look-dev happens in UE; screenshot review catches issues. |
|
||||
| TD-2 | No CI pipeline — all builds and QA are manual on the dev workstation | Low | Acceptable for `0.x`. CI is a `0.3.0+` concern. |
|
||||
|
||||
# Glossary
|
||||
|
||||
| Term | Definition |
|
||||
| --- | --- |
|
||||
| Blosm | Blender add-on (2.7.28) that imports OSM data as 3D building and street blockouts. Used for layout only — not authoritative for façade or height. |
|
||||
| PIE | Play In Editor — an Unreal Editor feature that runs the current map as a live game session inside the editor window, with full game code, input, and physics, without packaging a build. Used for interactive verification (walk, reset, pause) before the scripted QA self-test. |
|
||||
| Complex-as-simple collision | `CTF_UseComplexAsSimple`: Unreal collision mode where the render mesh triangles are used as the collision surface, instead of a simplified proxy. Required for terrain so the player walks on the actual ground shape. |
|
||||
| DEM | Digital Elevation Model. 3DEP 1 m resolution GeoTIFF covering the demo bounds. Source of terrain heightfield. |
|
||||
| El Capitan | El Capitan Entertainment Centre, 6838 Hollywood Blvd. The hero building of the demo. |
|
||||
| Enhanced Input | Unreal’s modern input system (UE 5+). Uses Input Actions (`IA_*`) and Input Mapping Contexts (`IMC_*`) instead of legacy axis/action bindings. |
|
||||
| EPSG:26911 | UTM zone 11N, the projected CRS used for the demo area. Local origin recorded in `Geo/`. |
|
||||
| Hero façade | The detailed, reference-calibrated model of the El Capitan building frontage. |
|
||||
| MPFB | MakeHuman Plugin for Blender (2.0.18). Generates parametric human base meshes with rigs and baked materials. |
|
||||
| PlayerStart | Unreal actor that defines where the player pawn spawns. Positioned above grade so the capsule does not embed in the floor on spawn. |
|
||||
| QA self-test | The `-qaselftest` command-line switch that runs an automated behaviour check (walk, reset, pause, ground transect) via a core ticker. |
|
||||
| Site | The terrain, road, sidewalks, kerbs, and crossing markings — the ground-level infrastructure of the demo area. |
|
||||
| Squash merge | Git merge strategy that compresses all branch commits into one commit on `main`, keeping a linear history. |
|
||||
| Swept transect | A QA technique that raycasts vertically at regular intervals along a path (e.g. every 200 cm along both sidewalks and the carriageway) and counts holes (misses). Zero holes = the block is fully walkable. |
|
||||
| UE | Unreal Engine — Epic Games' real-time 3D creation platform (version 5.8.4 in this project). Comprises the Unreal Editor (including PIE, content browser, viewport, blueprint editor), a C++ game framework, and runtime systems for rendering (Vulkan RHI on Linux), physics (Chaos), and input (Enhanced Input). The game project is `GigLine.uproject`; game code is a single C++ module in `Game/GigLine/Source/GigLine/`. |
|
||||
| World Partition | Unreal's world composition system for large open-world levels. Not yet used in `0.1.0` but planned for `0.3.0+` driving routes. |
|
||||
| Y convention | In Unreal, south = +Y, north = −Y (confirmed from street mesh orientation). In Blender, north = +Y; the `ue_metric_v1` export preset flips Y. |
|
||||
|
||||
---
|
||||
|
||||
**About arc42**
|
||||
|
||||
<div data-wrapper="1" role="lead">
|
||||
|
||||
arc42, the template for documentation of software and system architecture.
|
||||
|
||||
</div>
|
||||
|
||||
Template Version 0.1.0. initial architecture documentation, 2026-11-08
|
||||
|
||||
Created, maintained and © by Dr. Peter Hruschka, Dr. Gernot Starke and contributors. See <https://arc42.org>.
|
||||
|
||||
Adapted for the Gig Line project (Linux-first walking/driving demo around 6840 Hollywood Blvd).
|
||||
+28
-1
@@ -1,4 +1,4 @@
|
||||
# Controls (`0.1.0` walkable demo)
|
||||
# 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.
|
||||
|
||||
@@ -12,6 +12,8 @@ Keyboard and mouse. The same list is shown in-game, bottom-right of the frame (`
|
||||
| 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
|
||||
|
||||
@@ -19,6 +21,31 @@ Keyboard and mouse. The same list is shown in-game, bottom-right of the frame (`
|
||||
- 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.:
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
|
@@ -42,8 +42,11 @@ Measured at 1440p on the development workstation: Bazzite, Ryzen 7 7700X, 64 GB
|
||||
| `0.1.0` | Placement vs references | PASS (with deliberate simplifications) | Section below, 2026-11-08 | 2026-11-08 |
|
||||
| `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 | 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.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.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` | `Docs/perf/0.1.0-packaged-hud-controls.png`, 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)
|
||||
|
||||
@@ -175,6 +178,6 @@ Engine/Build/BatchFiles/Linux/Build.sh GigLine Linux Development \
|
||||
|
||||
- `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".
|
||||
- Verified in the packaged capture: the bottom-right text bbox is 426×12 px (a single right-aligned line), attributed text bottom-left. Screenshot: `Docs/perf/0.1.0-packaged-hud-controls.png`.
|
||||
- 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.**
|
||||
@@ -1,80 +0,0 @@
|
||||
# `0.1.4` façade review — signoff
|
||||
|
||||
Four demo-map captures from the `facades-0.1.4` branch, after the module kit, the textured materials and the theatre marquee went in. **All seven items signed off 2026-11-09** (owner review of the local renders).
|
||||
|
||||
Reference photographs to compare against: `Art/reference/hollywood/` and `Art/reference/el-capitan-*` (local, not committed). Regenerate the set with `Tools/render_screenshots.sh --verify`; measure it with `python3 Tools/visual_loop.py --compare --iteration 5`.
|
||||
|
||||
## Signoff
|
||||
|
||||
- [x] **1. Block from the north sidewalk** — hero between its neighbours, sidewalk and road read correctly
|
||||
- [x] **2. Street level** — colonnade, shopfronts and window rhythm hold up at eye height
|
||||
- [x] **3. Crossing** — zebra bars, kerb line and the frontage behind
|
||||
- [x] **4. North buildings** — TCL and Tussaud's framed across the boulevard
|
||||
- [x] **5. Materials** — stone reads as coursed stone, glazing as glass, not flat colour
|
||||
- [x] **6. Theatre trim** — marquee and blade sign proportions believable at street level
|
||||
- [x] **7. Approve** `v0.1.4` (kit + materials + theatre trim); remaining geometry moves to the next version
|
||||
|
||||
## 1. Block from the north sidewalk
|
||||
|
||||

|
||||
|
||||
Expected: the neoclassical hero façade between its neighbours, both sidewalks and the road in the foreground. _Metric: 0.68 similarity, edges 0.28× reference._
|
||||
|
||||
## 2. Street level
|
||||
|
||||

|
||||
|
||||
Expected: the hero colonnade with adjacent frontage buildings either side, shopfronts at pavement level, 4.96 m bay rhythm. _Metric: 0.33, edges 0.27×._
|
||||
|
||||
## 3. The designated crossing
|
||||
|
||||

|
||||
|
||||
Expected: continental zebra bars on the asphalt at s=130 m, south frontage and colonnade behind. _Metric: 0.42, edges 0.34×._
|
||||
|
||||
## 4. North-side buildings
|
||||
|
||||

|
||||
|
||||
Expected: TCL Chinese Theatre and Madame Tussaud's across Hollywood Blvd, full height in frame. _Metric: 0.34, edges 0.14×._
|
||||
|
||||
---
|
||||
|
||||
## Appendix — what was checked, and what was broken
|
||||
|
||||
### Verified
|
||||
|
||||
- **Behaviour**, packaged build, `-qaselftest`: walk 761 cm in 2 s (Z steady 456), reset 0 cm, 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 (`walk 246 cm`, `pause FAIL`), an immediate re-run passed — re-run before believing a single FAIL.
|
||||
- **Placement**, probed from the live map against `Geo/verification/2026-11-06-el-capitan-block.md`: 6922 −24276…−17700, 6902 −17749…−14591, **hero −14644…−12028 between them**, theatre −12082…−8210, 6822 / 6806 / 6800 −7854…−1437, TCL −22889…−18442, Tussaud's −27071…−22799. Blockout affine residual **0.0 cm**.
|
||||
- **Budgets**: hero 148 parts / 3 044 tris · kit 16 meshes × 12 tris · 625 kit actors ≈ 7 500 tris · 8 × 512² textures (196 KB) · 67 tool tests pass.
|
||||
- **Topology**: every kit piece manifold, no loose geometry.
|
||||
|
||||
### Defects found this cycle
|
||||
|
||||
Every one of these rendered convincingly; the placement ones were caught by coordinate probes, not by looking.
|
||||
|
||||
| Sev | Defect | Root cause |
|
||||
| --- | --- | --- |
|
||||
| Blocker | Frontage shifted ≈119 m X / 2.4 m Y, hero outside its gap | Blockout regenerated without `--origin` |
|
||||
| Blocker | Kit placed ~12 km from its buildings | Used mesh-local bbox; actors carry the offset |
|
||||
| Blocker | Marquee on the far side of the boulevard | Blender +Y is Unreal −Y |
|
||||
| Major | Marquee canopy 5 cm above the pavement | Absolute Z; pavement is 4.56 m above datum |
|
||||
| Major | Window bays invisible, inside the solid wall | Piece modelled entirely at +Y |
|
||||
| Major | Glazing wasn't glass | Grey `M_Kit_*` from the FBX import, never overridden |
|
||||
| Major | Hero windows floated 1.44 m in front of the wall | Wrong Y in the builder |
|
||||
| Major | Parapet medallions were discs on the coping | Built with the Z-axis cylinder helper |
|
||||
| Major | Hero had no usable collision | Complex-only; traces use simple |
|
||||
| Minor | "No smoothing group information" on every import | `mesh_smooth_type="OFF"` in six exporters |
|
||||
| Minor | `save_map()` returned False silently | LFS `.umap` read-only, importer never chmod'd |
|
||||
| Minor | North-buildings import silently no-op | Missing `import sys` |
|
||||
| Minor | Kit folder held 24 assets (8 orphan materials) | No stale-asset sweep |
|
||||
| Minor | Edge-density metric counted PIL's border ring | `FIND_EDGES` leaves a 128 ring |
|
||||
| Minor | QA wall probe grazed the theatre wall | Scan row 1 cm from the building line |
|
||||
|
||||
### Limitations worth knowing
|
||||
|
||||
- Kit pieces are boxes; dentil spacing, abacus and plinth dimensions are recorded assumptions, not measurements.
|
||||
- Textures are generated, not authored — no decals, signage text or weathering.
|
||||
- The vision pre-check stays advisory: it has rejected shots the owner approved.
|
||||
- The low edge ratios in the metrics are partly structural — a wide block view against a tight façade crop always scores low. Weigh the images, not the scores.
|
||||
- Performance has not been re-measured since `0.1.0`; the 625 kit actors are unmeasured (tracked in `TODO.md` under `0.1.5`).
|
||||
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.
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 210 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user