Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d1140c117 | ||
|
|
b96dd739b8 |
No files matched your search
@@ -0,0 +1,53 @@
|
||||
# VoxelForge — read-only design review: per-block bit flags (masks) to skip work
|
||||
|
||||
You are reviewing an idea against real code. **Do not edit, create or delete any file, and do not build or run
|
||||
anything.** Read code and reason. Be thorough; mark each claim as [CODE] (with file:line), [MEASURED] (from a report),
|
||||
or [INFERENCE].
|
||||
|
||||
## Context
|
||||
|
||||
VoxelForge Core (`Standalone/Core`) generates a density field: negative = solid, positive = air, 25 cm voxels, 32³ tiles,
|
||||
LOD0–8 clipmap, marching cubes. The production mesher for the standalone path is in `Standalone/Source/...`, and Core is
|
||||
also compiled into Unreal. Same seed must give the same world on every machine and worker count; byte-identity with
|
||||
older versions is NOT required.
|
||||
|
||||
Branch `assembler/world` (HEAD `7022d02`'s parent line, currently `4041d4b`) has the smooth inter-strate tunnels.
|
||||
Readiness target: LOD0–2 near terrain in ~1 s on arrival. Measured today: SW ~0.7–0.8 s, VS ~0.9 s, FI/TN ~1.0 s
|
||||
headless. In Linux UE, start→LOD0–2 is ~2.2–2.5 s. At 30 m/s in UE, near coverage is ~40%.
|
||||
|
||||
Reports to consult: `Standalone/Research/WorldAssemblerM3/Linux1*/REPORT.md`, especially:
|
||||
- L77/L87/L117, cost census;
|
||||
- L124, shape gate and per-strate timings;
|
||||
- L125/L126/L128, tunnel prepare: per-segment work, 67–73% pair overlap, support up to 7.9 m;
|
||||
- L128, where an exact one-owner slab scheme halved pairs but got slower because of per-sample ownership tests.
|
||||
|
||||
Tile skipping already exists at tile level: box verdicts / classify, where all-solid or all-air tiles are skipped.
|
||||
|
||||
## The idea (from the owner)
|
||||
|
||||
Keep bit flags per block (1 bit per voxel, or per small brick of e.g. 4³ or 8³ voxels): for example "certainly deep
|
||||
solid", "certainly deep air", "near a surface", "touched by a tunnel", "already evaluated". Use them to skip work in
|
||||
generation and meshing, and possibly elsewhere (collision, streaming, edits, AI/nav, lighting).
|
||||
|
||||
## Questions
|
||||
|
||||
1. Where does time actually go per tile today, and which of that work a mask could skip? Cover density fill,
|
||||
classification, mesher (marching cubes, normals/gradients, skirts, seam refinement), passage prepare, and composition.
|
||||
Use measured census numbers where they exist.
|
||||
2. Which flags are sound? A flag must be a proof, never a guess. A mask "certainly solid" must be derived from a
|
||||
conservative bound (the bound must be the supremum of what the evaluator produces), or the mesher will delete
|
||||
surfaces. Which bounds already exist in the code (box verdicts, interval bounds) that a brick-level mask could reuse?
|
||||
Name the existing hazards. For example, `Identity` means `Sdf >= T`, and `ClassifyTile` proving below-TerrainZ solid
|
||||
would delete 3D caves.
|
||||
3. Granularity: per-voxel bits vs per-brick (4³/8³) vs per-column. What does each cost to build, versus what it
|
||||
saves? Consider SIMD and cache behaviour. Marching cubes needs only cells whose corner signs differ, and gradients
|
||||
need a halo.
|
||||
4. "Already evaluated" or "checked" flags: where would they be correct (memoisation of identical queries), and where
|
||||
would they be wrong (nearest-of-many queries like the tunnel segments)? Is there repeated identical evaluation today,
|
||||
for example halo samples shared between neighbouring tiles, or skirt/seam re-queries?
|
||||
5. Other uses: player edits (diff layer), collision-only server tiles, streaming priority, nav. Which would a mask
|
||||
genuinely help, given the multiplayer rule (replicate seed + layout + diff, never geometry)?
|
||||
6. Recommendation: the one or two mask designs most likely to pay off, with the expected gain (a range, marked
|
||||
inference), the measurement that would prove or kill each, and the risks. Keep it short.
|
||||
|
||||
Write plain Markdown, at most ~1,200 words.
|
||||
@@ -0,0 +1,83 @@
|
||||
[INFERENCE] **Improve the existing brick-proof system; don’t add a general “checked voxel” mask.** The promising savings are avoided field/composition work and passage preparation, rather than marching-cubes classification.
|
||||
|
||||
References below abbreviate these files: [M = production mesher](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp), [S = ShapeWorldInternal.h](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h), [C = VoxelForgeCore.cpp](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp), [O = VoxelDensityOpStack.cpp](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelDensityOpStack.cpp). L-numbers identify `Standalone/Research/WorldAssemblerM3/LinuxN/REPORT.md`.
|
||||
|
||||
[INFERENCE] Evidence limitation: Linux128 is absent from this checkout. Its supplied 7.9 m support and slower one-owner result remain unverified here. The reports below span different revisions; their percentages must not be presented as today’s census.
|
||||
|
||||
**1. Where time goes**
|
||||
|
||||
[MEASURED] L77’s exclusive FI/TN LOD0–2 worker account:
|
||||
|
||||
| Work | FI | TN |
|
||||
|---|---:|---:|
|
||||
| Total worker CPU/view | 23.02 s | 21.50 s |
|
||||
| Passage composition | 65.9% | 65.4% |
|
||||
| Support | 14.2% | 13.5% |
|
||||
| Base field | 3.2% | 3.3% |
|
||||
| Bands / dispatch | 2.3% / 3.7% | 2.6% / 3.6% |
|
||||
| MC / skirts / refinement, excluding field work | 1.6% / 0.1% / 7.5% | 1.2% / 0.2% / 8.6% |
|
||||
|
||||
[MEASURED] Grid fill occupied 19.058/17.377 worker-seconds, **overlapping** those phase categories. L117’s later census found support zero; its smooth-tunnel regression concentrated about 95% of added tile CPU in passage-feature tiles. Cell classification stayed flat; gradients became cheaper. Thus L77 identifies historical leverage, not current percentages.
|
||||
|
||||
[MEASURED] L125 preparation averaged 514/130/4.1 ms worker work at LOD0/1/2. LOD0 evaluated 3.11–8.49 million segment/sample pairs with 67–72% overlap, although the exact band occupied only 5–7% of grid samples. L126 reduced floor-profile calls 20–23% without useful readiness improvement.
|
||||
|
||||
[CODE] Brick skipping already exists: configurable block verdicts, required-sample masks, and active-block gradient halos (M:646,1053). MC already rejects cells without sign crossings before interpolation/gradients (M:2186). Gradient memoisation exists (M:1956). Skirts issue separate density queries (M:2491); refinement has its own stage (C:2975).
|
||||
|
||||
[INFERENCE] A pre-evaluation proof can save density, composition, and subsequent MC work. A sign mask constructed after density evaluation saves only downstream scanning. Classification itself costs work; no isolated current classification percentage is established by these reports.
|
||||
|
||||
[MEASURED] L124’s shape gate alone took 179–226 ms, with no near-tile admissions before completion. L87 additionally measured a 107–153 ms far-parent gate and no headless collision wait. Tile masks cannot directly remove these gates or explain the supplied UE/headless gap.
|
||||
|
||||
**2. Sound flags and hazards**
|
||||
|
||||
[INFERENCE] For final density \(D\), solid requires an upper bound covering the evaluator’s supremum, \(U<0\); air requires a valid lower bound \(L\ge0\). “Deep” requires an explicit margin. Unknown must stay unknown. A crossing proves an MC-active cell; uniform sampled signs do not prove an entire continuous volume surface-free.
|
||||
|
||||
[CODE] Reusable proofs include:
|
||||
|
||||
- S:5428: halo-expanded box classification.
|
||||
- S:5974: exact surface-column extrema over the MC lattice.
|
||||
- S:6019: floating-island density intervals.
|
||||
- S:5197,6032: native cave intervals.
|
||||
- S:5949: stamp interval composition with outward numerical padding.
|
||||
- O:6998: operation-specific inactivity from SDF lower bounds.
|
||||
|
||||
[CODE] These proofs have guards: passage overlap returns unknown (S:5687); unsupported stamp composition returns unknown (S:5655); stratum crossings are rejected (S:5900). The mesher distinguishes uniform candidates from `bSkipSafe` certificates (M:715,756), and otherwise validates candidates against actual samples (M:1838).
|
||||
|
||||
[CODE] For gated modifiers, `Identity` can mean `Sdf >= T`, not `abs(Sdf) >= T` (O:1496,6998). Noise bounds cannot assume nominal `[-1,1]`: FBM and unclamped cellular bounds are explicitly discussed at O:848,301.
|
||||
|
||||
[INFERENCE] Additional hazards: confusing internal SDF with final density; certifying base terrain before caves, tunnels, shells, stamps or edits; using lattice proofs for off-grid queries; ignoring rounding or gradient halos. A below-`TerrainZ` solid rule applied to 3D caves deletes caves. “Touched by tunnel” should mean conservative candidate overlap; only **proven untouched** authorizes omission.
|
||||
|
||||
**3. Granularity**
|
||||
|
||||
[INFERENCE] Storage per flag for 32³ cells:
|
||||
|
||||
| Granularity | Storage | Construction/tradeoff |
|
||||
|---|---:|---|
|
||||
| Per cell | 4 KiB | 32,768 decisions; expensive unless derived during necessary work |
|
||||
| 4³ bricks | 64 B | 512 proofs; tighter boundaries, more proof/halo overhead |
|
||||
| 8³ bricks | 8 B | 64 proofs; cheaper, more mixed bricks |
|
||||
| XY columns | 128 B | 1,024 decisions; useful mainly for heightfield-specific proofs |
|
||||
|
||||
[INFERENCE] These exclude corner/halo samples, metadata and additional flags. A column bit cannot represent multiple cave intervals. Brick runs preserve contiguous X sampling and SIMD better than scattered per-sample branches; bit packing alone does not establish a speedup.
|
||||
|
||||
[CODE] The existing implementation uses byte arrays and preserves exact samples around active bricks (M:1053–1083). Replacing densities with arbitrary same-sign constants near active cells would corrupt interpolated positions or normals.
|
||||
|
||||
**4. “Already evaluated”**
|
||||
|
||||
[CODE] Passage preparation precedes meshing (C:2747). Its valid sentinel is initialization, not completion: subsequent segments update floor selection, shell minima and round-distance winners, with deterministic tie-breaking (S:11520,11615,11688).
|
||||
|
||||
[INFERENCE] Therefore first-visitor wins is invalid. Memoisation is valid only for identical queries against identical seed/layout/evaluator/edit revision and query semantics; cache the value, not just a bit.
|
||||
|
||||
[MEASURED] L77 counted 8.6–8.9% halo points, without measuring duplicate coordinates. L125 verified 4,900 shared samples across four neighbour pairs and still recorded substantial off-grid skirt/midpoint fallbacks.
|
||||
|
||||
[CODE] Shared-grid reuse and gradient validity caches already exist (M:1031,1956). [INFERENCE] Skirt/seam queries are reuse candidates only when coordinates and semantics actually match; “same voxel” is insufficient.
|
||||
|
||||
**5. Other uses**
|
||||
|
||||
[INFERENCE] Edit-dirty bricks can localize regeneration, with invalidation expanded through normals, seams and collision dependencies. Collision-only servers can skip certified empty regions, but still need boundary geometry. Streaming can prioritize potentially occupied bricks; nav and lighting need clearance/connectivity or visibility data beyond occupancy. Keep masks derived locally from replicated seed + layout + diff, versioned with that state.
|
||||
|
||||
**6. Recommendation**
|
||||
|
||||
- [INFERENCE] **Tune existing 4³/8³ certificates**, caching proofs and emitting contiguous required-sample runs. Plausible incremental near-ready saving: **0–5%**, with regressions possible. Measure proof time, samples avoided, halo expansion, total worker CPU and UE readiness.
|
||||
- [INFERENCE] **Pass required-region information into passage preparation**, rejecting whole segment/brick regions conservatively. Plausible near-ready saving: **0–10%**, highly uncertain because passage overlap currently vetoes proofs. Kill it if pair reduction fails to reduce preparation and end-to-end time.
|
||||
|
||||
[INFERENCE] Both require seam/off-grid validation, adversarial bound checks, edit invalidation tests, and cross-machine/worker determinism. Preserve canonical tie-breaking; old-version byte identity need not constrain a sound redesign.
|
||||
@@ -1,13 +0,0 @@
|
||||
# L128 slab ownership
|
||||
|
||||
Base `4041d4b`; branch `wip/l128-slab-ownership`; core version 226. Source stamp: `8682a9a088f0f02357b3b9722cda9b18a5ebce9886a13cba2d114bc0655d8c70`.
|
||||
|
||||
Each route body uses half-open frame-plane slabs, so a boundary sample belongs to one segment. The required support is `S = r + max(4.0 + 0.21 + 0.125, 0.75 + 0.21) + 0.05 m`: bore radius plus the larger sweep/relief/corner or shell/relief reach, with a 5 cm audit margin. The largest body support is 7.885 m; the 4.5 m mouth profile reaches 8.885 m and is assigned to transition slabs. Local uniqueness requires curvature radius `R > S` (`κS < 1`). For equal adjacent chord lengths `L` and turn `θ`, this is `L / (2 sin(θ/2)) > S`. Nonlocal mutually-normal centerline pairs must be farther apart than the sum of their supports. Intersections between different passages remain a deterministic field union.
|
||||
|
||||
All three owner-world routes pass the body curvature and self-separation checks; no route control points changed. Minimum body curvature radii are 11.565 m (0–1), 14.042 m (1–2), and 8.869 m (2–3), giving at least 0.984 m margin over body support. Route 0–1's 8 tight mouth joints and 5 nonlocal mouth pairs use transitions. The prepared/off-grid query paths share ownership. The audit tested 33,813 support samples: zero missing or duplicate owners, and both negative controls were detected.
|
||||
|
||||
The slab projection supplies `s` to the continuous floor profile `h(s)`; round-distance does not choose floor height. Across 459 floor roots at nine stations, the largest adjacent root step was 1.765 mm and the largest absolute station offset was 7.884 mm. Seam audit: 4,900 shared samples, zero mismatches. Fast suite passed (264 checks, 5 diagnostic); walkability passed. Clang and GCC W1/W8/W12 hashes matched across all three datasets. The 23 L125 captures are in `captures/L128/` (19 pass; 4 low-contrast with geometry visible).
|
||||
|
||||
**Performance bar failed.** Five interleaved runs per group across all four strates and W8/W12 put LOD0–2 readiness 14.8–28.0% behind L109 and 8.0–20.6% behind `4041d4b`. The five-run 30 m/s UE median also failed versus `4041d4b`: near coverage 31.46% vs 40.22%, moving far holes 5.66% vs 3.46%, p99 tick 12.42 ms vs 10.80 ms, and worst tick 14.35 ms vs 13.27 ms. L128 is not ready.
|
||||
|
||||
Linux UE host build succeeded (27/27 actions, `-NoUBA -MaxParallelActions=4`); Unreal ran without `prlimit`. No commit made. Detailed logs are under `Saved/Linux/l128/`.
|
||||
@@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run five UE 30 m/s movement trials and compare with the L127 4041d4b baseline."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import statistics
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
RESEARCH = ROOT / "Standalone/Research/WorldAssemblerM3"
|
||||
OUT = ROOT / "Saved/Linux/l128/ue"
|
||||
HOST = Path("/home/jahni/VFHost")
|
||||
EDITOR = Path("/home/jahni/UnrealEngine/Engine/Binaries/Linux/UnrealEditor-Cmd")
|
||||
MOVEMENT_PATH = RESEARCH / "Linux121/RunL121Movement.py"
|
||||
BASELINE_PATH = ROOT / "Saved/Linux/l127/ue/movement-pairs-summary.json"
|
||||
|
||||
|
||||
def load_movement_module():
|
||||
spec = importlib.util.spec_from_file_location("l128_movement", MOVEMENT_PATH)
|
||||
if spec is None or spec.loader is None:
|
||||
raise RuntimeError(f"cannot load UE movement runner: {MOVEMENT_PATH}")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not BASELINE_PATH.is_file():
|
||||
raise SystemExit(f"missing 4041d4b movement baseline: {BASELINE_PATH}")
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
module = load_movement_module()
|
||||
module.HOST = HOST
|
||||
module.EDITOR = EDITOR
|
||||
module.OUT = OUT / "movement"
|
||||
module.HOST_SAVED = HOST / "Saved/Linux/l128/host"
|
||||
module.HOST_OUT = HOST / "Plugins/VoxelForge/Saved/Linux/l128/movement"
|
||||
module.RUN_TIMEOUT_S = 1740
|
||||
module.HOST_OUT.mkdir(parents=True, exist_ok=True)
|
||||
os.environ["XDG_CONFIG_HOME"] = str(OUT / "config")
|
||||
|
||||
rows = []
|
||||
for repetition in range(1, 6):
|
||||
row = module.run_unreal("L128", repetition)
|
||||
events = module.parse_events(ROOT / row["trace"])
|
||||
row["supplemental_far_applies_total"] = sum(
|
||||
int(event.get("supplemental_far_applies", 0))
|
||||
for event in events if event.get("type") == "apply_frame")
|
||||
row["supplemental_far_applies_moving"] = sum(
|
||||
int(event.get("supplemental_far_applies", 0))
|
||||
for event in events if event.get("type") == "apply_frame"
|
||||
and float(event.get("speed_cm_s", 0.0)) >= 50.0)
|
||||
if row.get("effective_tile_slots") != 8 or row["supplemental_far_applies_moving"] <= 0:
|
||||
raise SystemExit(f"movement run missed the configured apply lane: {row}")
|
||||
rows.append(row)
|
||||
(OUT / "movement-runs-partial.json").write_text(
|
||||
json.dumps(rows, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
||||
print("[L128UEMovement] " + json.dumps({
|
||||
key: row[key] for key in (
|
||||
"condition", "repetition", "near_ready_moving_mean_pct",
|
||||
"far_holes_moving_mean_pct", "game_thread_tick_p99_ms",
|
||||
"game_thread_tick_max_ms", "supplemental_far_applies_moving",
|
||||
"wall_s", "trace")}, sort_keys=True), flush=True)
|
||||
|
||||
baseline_doc = json.loads(BASELINE_PATH.read_text(encoding="utf-8"))
|
||||
baseline_rows = [row for row in baseline_doc["runs"]
|
||||
if row["condition"] == "merge"]
|
||||
if len(baseline_rows) != 5:
|
||||
raise SystemExit(f"expected five 4041d4b baseline runs, got {len(baseline_rows)}")
|
||||
metrics = ("near_ready_moving_mean_pct", "far_holes_moving_mean_pct",
|
||||
"game_thread_tick_p99_ms", "game_thread_tick_max_ms")
|
||||
baseline = {metric: statistics.median(row[metric] for row in baseline_rows)
|
||||
for metric in metrics}
|
||||
candidate = {metric: statistics.median(row[metric] for row in rows)
|
||||
for metric in metrics}
|
||||
build_log = (ROOT / "Saved/Linux/l128/build-clang.log").read_text(
|
||||
encoding="utf-8", errors="replace")
|
||||
stamp_match = re.search(r"^Source stamp: (\S+)$", build_log, re.M)
|
||||
if stamp_match is None:
|
||||
raise SystemExit("missing L128 Clang source stamp")
|
||||
summary = {
|
||||
"baseline": {"commit": "4041d4b", "runs": len(baseline_rows),
|
||||
"metrics": baseline},
|
||||
"candidate": {"source_stamp": stamp_match.group(1),
|
||||
"runs": len(rows), "metrics": candidate},
|
||||
"candidate_vs_4041d4b_delta": {
|
||||
metric: candidate[metric] - baseline[metric] for metric in metrics},
|
||||
"bar_pass": candidate["near_ready_moving_mean_pct"]
|
||||
> baseline["near_ready_moving_mean_pct"]
|
||||
and all(candidate[metric] <= baseline[metric] for metric in (
|
||||
"far_holes_moving_mean_pct", "game_thread_tick_p99_ms",
|
||||
"game_thread_tick_max_ms")),
|
||||
}
|
||||
(OUT / "movement-summary.json").write_text(
|
||||
json.dumps({"runs": rows, "summary": summary}, indent=2, sort_keys=True) + "\n",
|
||||
encoding="utf-8")
|
||||
print("[L128UEMovementSummary] " + json.dumps(summary, sort_keys=True), flush=True)
|
||||
if not summary["bar_pass"]:
|
||||
raise SystemExit("L128 UE movement medians missed the 4041d4b coverage/tick bar")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 104 KiB |
@@ -0,0 +1,294 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
struct FSegment
|
||||
{
|
||||
int passage=0,index=0;
|
||||
std::array<double,3> a{},b{};
|
||||
double radiusA=0.0,radiusB=0.0;
|
||||
};
|
||||
struct FTile
|
||||
{
|
||||
int strate=0,x=0,y=0,z=0,lod=0;
|
||||
std::uint64_t baselineFeatures=0,baselineCandidates=0,baselinePairs=0;
|
||||
};
|
||||
struct FTotals
|
||||
{
|
||||
std::uint64_t tiles=0,featureTiles=0,proofTiles=0,groups=0,segments=0;
|
||||
std::uint64_t pairs=0,contributingPairs=0,touched=0,support=0;
|
||||
std::uint64_t overlapPairs=0,crossPassageOverlap=0;
|
||||
std::uint64_t baselineFeatureTiles=0,baselineFeatures=0,baselineCandidates=0;
|
||||
std::uint64_t baselinePairs=0;
|
||||
};
|
||||
|
||||
static bool Intersects(const std::array<double,3>& amin,
|
||||
const std::array<double,3>& amax,const std::array<double,3>& bmin,
|
||||
const std::array<double,3>& bmax)
|
||||
{
|
||||
for(int axis=0;axis<3;++axis)
|
||||
if(amax[axis]<bmin[axis]||amin[axis]>bmax[axis])return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int GridFirst(double bound,const double gridMin[3],double spacing,int axis)
|
||||
{
|
||||
const auto boundSub=static_cast<std::int64_t>(std::floor(bound*1024.0));
|
||||
const auto gridMinSub=static_cast<std::int64_t>(std::llround(gridMin[axis]*1024.0));
|
||||
const auto stepSub=static_cast<std::int64_t>(std::llround(spacing*1024.0));
|
||||
const auto numerator=boundSub-gridMinSub;
|
||||
auto quotient=numerator/stepSub;
|
||||
if(numerator%stepSub>0)++quotient;
|
||||
return static_cast<int>(quotient);
|
||||
}
|
||||
|
||||
static int GridLast(double bound,const double gridMin[3],double spacing,int axis)
|
||||
{
|
||||
const auto boundSub=static_cast<std::int64_t>(std::ceil(bound*1024.0));
|
||||
const auto gridMinSub=static_cast<std::int64_t>(std::llround(gridMin[axis]*1024.0));
|
||||
const auto stepSub=static_cast<std::int64_t>(std::llround(spacing*1024.0));
|
||||
const auto numerator=boundSub-gridMinSub;
|
||||
auto quotient=numerator/stepSub;
|
||||
if(numerator%stepSub<0)--quotient;
|
||||
return static_cast<int>(quotient);
|
||||
}
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
if(argc!=3)
|
||||
{
|
||||
std::cerr<<"usage: CountReachCandidates <input.tsv> <output.csv>\n";
|
||||
return 2;
|
||||
}
|
||||
std::ifstream input(argv[1]);
|
||||
if(!input){std::cerr<<"cannot open input\n";return 2;}
|
||||
std::vector<std::vector<FSegment>> passages(3);
|
||||
std::vector<FTile> tiles;
|
||||
std::string line;
|
||||
while(std::getline(input,line))
|
||||
{
|
||||
std::istringstream row(line);
|
||||
char kind=0;row>>kind;
|
||||
if(kind=='S')
|
||||
{
|
||||
FSegment s;row>>s.passage>>s.index
|
||||
>>s.a[0]>>s.a[1]>>s.a[2]>>s.b[0]>>s.b[1]>>s.b[2]
|
||||
>>s.radiusA>>s.radiusB;
|
||||
if(!row||s.passage<0||s.passage>=static_cast<int>(passages.size()))
|
||||
{std::cerr<<"bad segment row\n";return 2;}
|
||||
passages[static_cast<std::size_t>(s.passage)].push_back(s);
|
||||
}
|
||||
else if(kind=='T')
|
||||
{
|
||||
FTile t;row>>t.strate>>t.x>>t.y>>t.z>>t.lod
|
||||
>>t.baselineFeatures>>t.baselineCandidates>>t.baselinePairs;
|
||||
if(!row){std::cerr<<"bad tile row\n";return 2;}
|
||||
tiles.push_back(t);
|
||||
}
|
||||
else if(kind!='#'&&kind!='\0')
|
||||
{std::cerr<<"unknown row\n";return 2;}
|
||||
}
|
||||
for(auto& p:passages)
|
||||
std::sort(p.begin(),p.end(),[](const auto& a,const auto& b)
|
||||
{return a.index<b.index;});
|
||||
|
||||
std::ofstream output(argv[2]);
|
||||
if(!output){std::cerr<<"cannot open output\n";return 2;}
|
||||
output<<"reach_m,bounds_mode,strate,lod,tiles,feature_tiles,proof_tiles,feature_groups,segment_pairs,contributing_pairs,touched_samples,round_support_samples,overlap_pairs,cross_passage_overlaps,baseline_feature_tiles,baseline_features,baseline_candidates,baseline_pairs\n";
|
||||
constexpr std::array<double,4> reaches={4.0,3.0,2.0,1.5};
|
||||
const std::array<std::pair<const char*,double>,2> boundsModes={{{"v225_core_voxel_units",0.25},
|
||||
{"physical_metres",1.0}}};
|
||||
constexpr double coreVoxelMetres=0.25;
|
||||
constexpr double marginMetres=0.01;
|
||||
for(const auto& [boundsMode,boundsScale]:boundsModes)
|
||||
for(const double reach:reaches)
|
||||
{
|
||||
const double requiredReach=std::max(reach+0.21+0.125,0.75+0.21);
|
||||
std::map<std::pair<int,int>,FTotals> totals;
|
||||
for(const auto& tile:tiles)
|
||||
{
|
||||
const int stepVoxels=1<<tile.lod;
|
||||
const double spacing=stepVoxels*coreVoxelMetres;
|
||||
const int dim=32+3;
|
||||
const double tileOrigin[3]={tile.x*32.0*spacing,tile.y*32.0*spacing,
|
||||
tile.z*32.0*spacing};
|
||||
const double gridMin[3]={tileOrigin[0]-spacing,tileOrigin[1]-spacing,
|
||||
tileOrigin[2]-spacing};
|
||||
const double gridMax[3]={gridMin[0]+(dim-1)*spacing,
|
||||
gridMin[1]+(dim-1)*spacing,gridMin[2]+(dim-1)*spacing};
|
||||
const std::array<double,3> queryMin={gridMin[0],gridMin[1],gridMin[2]};
|
||||
const std::array<double,3> queryMax={gridMax[0],gridMax[1],gridMax[2]};
|
||||
const std::array<double,3> proofMin={tileOrigin[0],tileOrigin[1],tileOrigin[2]};
|
||||
const std::array<double,3> proofMax={tileOrigin[0]+32.0*spacing,
|
||||
tileOrigin[1]+32.0*spacing,tileOrigin[2]+32.0*spacing};
|
||||
|
||||
const std::size_t sampleCount=static_cast<std::size_t>(dim)*dim*dim;
|
||||
std::vector<std::vector<std::uint8_t>> touchedMasks(passages.size(),
|
||||
std::vector<std::uint8_t>(sampleCount,0));
|
||||
std::vector<std::vector<std::uint8_t>> supportMasks(passages.size(),
|
||||
std::vector<std::uint8_t>(sampleCount,0));
|
||||
std::vector<std::uint8_t> unionMask(sampleCount,0);
|
||||
FTotals local;
|
||||
bool anyFeature=false,anyProof=false;
|
||||
|
||||
for(std::size_t p=0;p<passages.size();++p)
|
||||
{
|
||||
const auto& segments=passages[p];
|
||||
const std::size_t groupCount=(segments.size()+4)/5;
|
||||
for(std::size_t group=0;group<groupCount;++group)
|
||||
{
|
||||
const std::size_t begin=group*5,end=std::min(begin+5,segments.size());
|
||||
std::array<double,3> routeMin={
|
||||
std::numeric_limits<double>::infinity(),
|
||||
std::numeric_limits<double>::infinity(),
|
||||
std::numeric_limits<double>::infinity()};
|
||||
std::array<double,3> routeMax={
|
||||
-std::numeric_limits<double>::infinity(),
|
||||
-std::numeric_limits<double>::infinity(),
|
||||
-std::numeric_limits<double>::infinity()};
|
||||
double maxRadius=0.0;
|
||||
for(std::size_t i=begin;i<end;++i)
|
||||
{
|
||||
const auto& s=segments[i];
|
||||
maxRadius=std::max({maxRadius,s.radiusA,s.radiusB});
|
||||
for(int axis=0;axis<3;++axis)
|
||||
{
|
||||
routeMin[axis]=std::min({routeMin[axis],s.a[axis],s.b[axis]});
|
||||
routeMax[axis]=std::max({routeMax[axis],s.a[axis],s.b[axis]});
|
||||
}
|
||||
}
|
||||
// The v225 implementation divides positions and radii by Q
|
||||
// (Core voxels), then adds its *_Metres constants directly.
|
||||
// Reproduce that code-unit behavior here for the baseline check.
|
||||
const double featureExtent=maxRadius
|
||||
+(requiredReach+marginMetres)*boundsScale;
|
||||
for(int axis=0;axis<3;++axis)
|
||||
{routeMin[axis]-=featureExtent;routeMax[axis]+=featureExtent;}
|
||||
if(!Intersects(routeMin,routeMax,queryMin,queryMax))continue;
|
||||
anyFeature=true;++local.groups;
|
||||
|
||||
for(std::size_t i=begin;i<end;++i)
|
||||
{
|
||||
const auto& s=segments[i];
|
||||
const double extent=std::max(s.radiusA,s.radiusB)
|
||||
+(requiredReach+marginMetres)*boundsScale;
|
||||
std::array<double,3> low{},high{};
|
||||
int first[3]{},last[3]{};
|
||||
bool valid=true;
|
||||
for(int axis=0;axis<3;++axis)
|
||||
{
|
||||
low[axis]=std::min(s.a[axis],s.b[axis])-extent;
|
||||
high[axis]=std::max(s.a[axis],s.b[axis])+extent;
|
||||
first[axis]=std::max(0,GridFirst(low[axis],gridMin,spacing,axis));
|
||||
last[axis]=std::min(dim-1,GridLast(high[axis],gridMin,spacing,axis));
|
||||
valid=valid&&first[axis]<=last[axis];
|
||||
}
|
||||
// Proof bounds are per segment and include the same conservative
|
||||
// reach; they test the full tile box without the sample halo.
|
||||
if(Intersects(low,high,proofMin,proofMax))anyProof=true;
|
||||
if(!valid)continue;
|
||||
++local.segments;
|
||||
for(int axis=0;axis<3;++axis)
|
||||
{
|
||||
const auto subLo=static_cast<std::int64_t>(std::floor(low[axis]*1024.0));
|
||||
const auto subHi=static_cast<std::int64_t>(std::ceil(high[axis]*1024.0));
|
||||
const auto gridLo=static_cast<std::int64_t>(std::llround(gridMin[axis]*1024.0));
|
||||
const auto subStep=static_cast<std::int64_t>(std::llround(spacing*1024.0));
|
||||
const auto expectedFirst=std::max<std::int64_t>(0,
|
||||
(subLo-gridLo+subStep-1)/subStep);
|
||||
const auto expectedLast=std::min<std::int64_t>(dim-1,
|
||||
(subHi-gridLo)/subStep);
|
||||
first[axis]=static_cast<int>(expectedFirst);
|
||||
last[axis]=static_cast<int>(expectedLast);
|
||||
}
|
||||
if(first[0]>last[0]||first[1]>last[1]||first[2]>last[2])continue;
|
||||
const std::uint64_t nx=static_cast<std::uint64_t>(last[0]-first[0]+1);
|
||||
const std::uint64_t ny=static_cast<std::uint64_t>(last[1]-first[1]+1);
|
||||
const std::uint64_t nz=static_cast<std::uint64_t>(last[2]-first[2]+1);
|
||||
local.pairs+=nx*ny*nz;
|
||||
|
||||
for(int gz=first[2];gz<=last[2];++gz)
|
||||
for(int gy=first[1];gy<=last[1];++gy)
|
||||
for(int gx=first[0];gx<=last[0];++gx)
|
||||
{
|
||||
const double q[3]={gridMin[0]+gx*spacing,
|
||||
gridMin[1]+gy*spacing,gridMin[2]+gz*spacing};
|
||||
const double dx=s.b[0]-s.a[0],dy=s.b[1]-s.a[1],dz=s.b[2]-s.a[2];
|
||||
const double lengthSq=dx*dx+dy*dy+dz*dz;
|
||||
if(!(lengthSq>0.0))continue;
|
||||
const double projection=(q[0]-s.a[0])*dx+(q[1]-s.a[1])*dy
|
||||
+(q[2]-s.a[2])*dz;
|
||||
const double t=std::clamp(projection/lengthSq,0.0,1.0);
|
||||
const double ex=q[0]-(s.a[0]+t*dx);
|
||||
const double ey=q[1]-(s.a[1]+t*dy);
|
||||
const double ez=q[2]-(s.a[2]+t*dz);
|
||||
const double radius=s.radiusA+t*(s.radiusB-s.radiusA);
|
||||
const double distance=std::sqrt(ex*ex+ey*ey+ez*ez)-radius;
|
||||
const double oneSubvoxel=1.0/1024.0;
|
||||
if(distance<reach+oneSubvoxel)
|
||||
{
|
||||
++local.contributingPairs;
|
||||
const std::size_t index=(static_cast<std::size_t>(gz)*dim+gy)*dim+gx;
|
||||
touchedMasks[p][index]=1;
|
||||
unionMask[index]=1;
|
||||
if(distance<=reach)supportMasks[p][index]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
local.tiles=1;
|
||||
local.featureTiles=anyFeature?1:0;
|
||||
local.proofTiles=anyProof?1:0;
|
||||
local.baselineFeatureTiles=tile.baselineFeatures?1:0;
|
||||
local.baselineFeatures=tile.baselineFeatures;
|
||||
local.baselineCandidates=tile.baselineCandidates;
|
||||
local.baselinePairs=tile.baselinePairs;
|
||||
for(const auto& mask:touchedMasks)
|
||||
local.touched+=static_cast<std::uint64_t>(
|
||||
std::count(mask.begin(),mask.end(),static_cast<std::uint8_t>(1)));
|
||||
for(std::size_t p=0;p<passages.size();++p)
|
||||
{
|
||||
const auto& mask=supportMasks[p];
|
||||
local.support+=static_cast<std::uint64_t>(
|
||||
std::count(mask.begin(),mask.end(),static_cast<std::uint8_t>(1)));
|
||||
}
|
||||
const std::uint64_t unique=static_cast<std::uint64_t>(
|
||||
std::count(unionMask.begin(),unionMask.end(),static_cast<std::uint8_t>(1)));
|
||||
local.crossPassageOverlap=local.touched-unique;
|
||||
local.overlapPairs=local.contributingPairs-local.touched;
|
||||
auto& total=totals[{tile.strate,tile.lod}];
|
||||
total.tiles+=local.tiles;total.featureTiles+=local.featureTiles;
|
||||
total.proofTiles+=local.proofTiles;total.groups+=local.groups;
|
||||
total.segments+=local.segments;total.pairs+=local.pairs;
|
||||
total.contributingPairs+=local.contributingPairs;total.touched+=local.touched;
|
||||
total.support+=local.support;total.overlapPairs+=local.overlapPairs;
|
||||
total.crossPassageOverlap+=local.crossPassageOverlap;
|
||||
total.baselineFeatureTiles+=local.baselineFeatureTiles;
|
||||
total.baselineFeatures+=local.baselineFeatures;
|
||||
total.baselineCandidates+=local.baselineCandidates;
|
||||
total.baselinePairs+=local.baselinePairs;
|
||||
}
|
||||
for(const auto& [key,t]:totals)
|
||||
output<<std::fixed<<std::setprecision(2)<<reach<<','<<boundsMode<<','
|
||||
<<key.first<<','<<key.second
|
||||
<<','<<t.tiles<<','<<t.featureTiles<<','<<t.proofTiles<<','<<t.groups
|
||||
<<','<<t.pairs<<','<<t.contributingPairs<<','<<t.touched<<','<<t.support
|
||||
<<','<<t.overlapPairs<<','<<t.crossPassageOverlap<<','
|
||||
<<t.baselineFeatureTiles<<','<<t.baselineFeatures<<','
|
||||
<<t.baselineCandidates<<','<<t.baselinePairs<<'\n';
|
||||
std::cerr<<"[L129Precount] reach_m="<<reach<<" required_reach_m="<<requiredReach
|
||||
<<" grouped_rows="<<totals.size()<<"\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Count reach-bound work from the saved v225 layout and L125 tile profiles."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
HERE = Path(__file__).resolve().parent
|
||||
OUT = ROOT / "Saved/Linux/l129/precount"
|
||||
LAYOUT = ROOT / "Saved/Linux/l125/hashes/owner4-surface-world-w8-clang.layout.json"
|
||||
BASELINE_LOGS = [ROOT / f"Saved/Linux/l125/counts/s{s}-w8-profile1.log" for s in range(4)]
|
||||
CORE_VOXEL_METRES = 0.25
|
||||
SUBVOXELS_PER_METRE = 1024.0
|
||||
PROFILE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
|
||||
TILE_KEY = re.compile(r"\((-?\d+),(-?\d+),(-?\d+),lod(\d+)\)")
|
||||
|
||||
|
||||
def knot_span(a: list[float], b: list[float], units_per_metre: float) -> float:
|
||||
dx, dy = (b[0] - a[0]) / units_per_metre, (b[1] - a[1]) / units_per_metre
|
||||
return max(1.0e-6, math.sqrt(math.sqrt(dx * dx + dy * dy)))
|
||||
|
||||
|
||||
def evaluate_raw(controls: list[list[float]], span: int, t: float,
|
||||
units_per_metre: float) -> list[float]:
|
||||
p1, p2 = controls[span], controls[span + 1]
|
||||
p0, p3 = controls[max(0, span - 1)], controls[min(span + 2, len(controls) - 1)]
|
||||
dt0, dt1, dt2 = (knot_span(p0, p1, units_per_metre),
|
||||
knot_span(p1, p2, units_per_metre),
|
||||
knot_span(p2, p3, units_per_metre))
|
||||
t2, t3 = t * t, t * t * t
|
||||
result = [0.0, 0.0, 0.0, 0.0]
|
||||
for axis in (0, 1, 3):
|
||||
m1 = dt1 * ((p1[axis] - p0[axis]) / dt0
|
||||
- (p2[axis] - p0[axis]) / (dt0 + dt1)
|
||||
+ (p2[axis] - p1[axis]) / dt1)
|
||||
m2 = dt1 * ((p2[axis] - p1[axis]) / dt1
|
||||
- (p3[axis] - p1[axis]) / (dt1 + dt2)
|
||||
+ (p3[axis] - p2[axis]) / dt2)
|
||||
result[axis] = ((2.0 * t3 - 3.0 * t2 + 1.0) * p1[axis]
|
||||
+ (-2.0 * t3 + 3.0 * t2) * p2[axis]
|
||||
+ (t3 - 2.0 * t2 + t) * m1
|
||||
+ (t3 - t2) * m2)
|
||||
result[2] = p1[2] + (p2[2] - p1[2]) * t
|
||||
result[3] = min(max(result[3], min(p1[3], p2[3])), max(p1[3], p2[3]))
|
||||
return result
|
||||
|
||||
|
||||
def build_raw_segments(controls: list[list[float]], units_per_metre: float,
|
||||
spacing_metres: float = 8.0,
|
||||
chord_error_metres: float = 0.1) -> list[dict]:
|
||||
result: list[dict] = []
|
||||
along_metres = 0.0
|
||||
for span in range(len(controls) - 1):
|
||||
horizontal_arc = [0.0] * 33
|
||||
previous = evaluate_raw(controls, span, 0.0, units_per_metre)
|
||||
for step in range(1, 33):
|
||||
current = evaluate_raw(controls, span, step / 32.0, units_per_metre)
|
||||
dx = (current[0] - previous[0]) / units_per_metre
|
||||
dy = (current[1] - previous[1]) / units_per_metre
|
||||
horizontal_arc[step] = horizontal_arc[step - 1] + math.hypot(dx, dy)
|
||||
previous = current
|
||||
span_length = horizontal_arc[-1]
|
||||
base_count = max(1, math.ceil(span_length / spacing_metres))
|
||||
|
||||
def parameter_at_arc(target: float) -> float:
|
||||
upper = 1
|
||||
while upper < len(horizontal_arc) and horizontal_arc[upper] < target:
|
||||
upper += 1
|
||||
upper = min(upper, 32)
|
||||
lower = upper - 1
|
||||
arc_span = horizontal_arc[upper] - horizontal_arc[lower]
|
||||
arc_t = ((target - horizontal_arc[lower]) / arc_span
|
||||
if arc_span > 1.0e-12 else 0.0)
|
||||
return (lower + min(max(arc_t, 0.0), 1.0)) / 32.0
|
||||
|
||||
parameters = [0.0]
|
||||
|
||||
def append_adaptive(t_a: float, t_b: float, a: list[float], b: list[float],
|
||||
depth: int) -> None:
|
||||
fractions = (0.25, 0.5, 0.75)
|
||||
maximum_error, polyline_length = 0.0, 0.0
|
||||
previous_point = a
|
||||
for fraction in fractions:
|
||||
current = evaluate_raw(controls, span, t_a + (t_b - t_a) * fraction,
|
||||
units_per_metre)
|
||||
dx = (current[0] - (a[0] + (b[0] - a[0]) * fraction)) / units_per_metre
|
||||
dy = (current[1] - (a[1] + (b[1] - a[1]) * fraction)) / units_per_metre
|
||||
dr = (current[3] - (a[3] + (b[3] - a[3]) * fraction)) / units_per_metre
|
||||
maximum_error = max(maximum_error, math.sqrt(dx * dx + dy * dy + dr * dr))
|
||||
sx = (current[0] - previous_point[0]) / units_per_metre
|
||||
sy = (current[1] - previous_point[1]) / units_per_metre
|
||||
polyline_length += math.hypot(sx, sy)
|
||||
previous_point = current
|
||||
sx = (b[0] - previous_point[0]) / units_per_metre
|
||||
sy = (b[1] - previous_point[1]) / units_per_metre
|
||||
polyline_length += math.hypot(sx, sy)
|
||||
split = ((polyline_length > spacing_metres * (1.0 + 1.0e-9)
|
||||
or maximum_error > chord_error_metres) and depth < 12)
|
||||
if split:
|
||||
t_mid = (t_a + t_b) * 0.5
|
||||
middle = evaluate_raw(controls, span, t_mid, units_per_metre)
|
||||
append_adaptive(t_a, t_mid, a, middle, depth + 1)
|
||||
append_adaptive(t_mid, t_b, middle, b, depth + 1)
|
||||
else:
|
||||
parameters.append(t_b)
|
||||
|
||||
for segment in range(1, base_count + 1):
|
||||
target_a = span_length * (segment - 1) / base_count
|
||||
target_b = span_length * segment / base_count
|
||||
t_a, t_b = parameter_at_arc(target_a), parameter_at_arc(target_b)
|
||||
append_adaptive(t_a, t_b,
|
||||
evaluate_raw(controls, span, t_a, units_per_metre),
|
||||
evaluate_raw(controls, span, t_b, units_per_metre), 0)
|
||||
|
||||
points = [evaluate_raw(controls, span, t, units_per_metre) for t in parameters]
|
||||
sampled_arc = [0.0] * len(points)
|
||||
for index in range(1, len(points)):
|
||||
dx = (points[index][0] - points[index - 1][0]) / units_per_metre
|
||||
dy = (points[index][1] - points[index - 1][1]) / units_per_metre
|
||||
sampled_arc[index] = sampled_arc[index - 1] + math.hypot(dx, dy)
|
||||
sampled_span_length = sampled_arc[-1]
|
||||
for index, point in enumerate(points):
|
||||
progress = (sampled_arc[index] / sampled_span_length
|
||||
if sampled_span_length > 1.0e-12 else parameters[index])
|
||||
point[2] = controls[span][2] + (controls[span + 1][2] - controls[span][2]) * progress
|
||||
|
||||
for index in range(1, len(points)):
|
||||
dx = (points[index][0] - points[index - 1][0]) / units_per_metre
|
||||
dy = (points[index][1] - points[index - 1][1]) / units_per_metre
|
||||
dz = (points[index][2] - points[index - 1][2]) / units_per_metre
|
||||
length = math.sqrt(dx * dx + dy * dy + dz * dz)
|
||||
progress_a = (sampled_arc[index - 1] / sampled_span_length
|
||||
if sampled_span_length > 1.0e-12 else parameters[index - 1])
|
||||
progress_b = (sampled_arc[index] / sampled_span_length
|
||||
if sampled_span_length > 1.0e-12 else parameters[index])
|
||||
floor_a = controls[span][2] - controls[span][3]
|
||||
floor_b = controls[span + 1][2] - controls[span + 1][3]
|
||||
result.append({"a": points[index - 1], "b": points[index],
|
||||
"along": along_metres, "length": length, "span": span,
|
||||
"floor_a": floor_a + (floor_b - floor_a) * progress_a,
|
||||
"floor_b": floor_a + (floor_b - floor_a) * progress_b})
|
||||
along_metres += length
|
||||
return result
|
||||
|
||||
|
||||
def closest_route_height(route: list[list[float]], x: float, y: float) -> tuple[float, float]:
|
||||
best_height, best_distance_sq = 0.0, float("inf")
|
||||
for a, b in zip(route, route[1:]):
|
||||
dx, dy = b[0] - a[0], b[1] - a[1]
|
||||
length_sq = dx * dx + dy * dy
|
||||
t = min(max(((x - a[0]) * dx + (y - a[1]) * dy) / length_sq, 0.0), 1.0) \
|
||||
if length_sq > 1.0e-12 else 0.0
|
||||
px, py = a[0] + t * dx, a[1] + t * dy
|
||||
distance_sq = (x - px) ** 2 + (y - py) ** 2
|
||||
if distance_sq < best_distance_sq:
|
||||
best_distance_sq = distance_sq
|
||||
best_height = a[2] + (b[2] - a[2]) * t
|
||||
return best_height, best_distance_sq
|
||||
|
||||
|
||||
def prepared_segments(layout: dict) -> list[list[dict]]:
|
||||
qpm = SUBVOXELS_PER_METRE
|
||||
strata = {item["strate_index"]: item for item in layout["strates"]}
|
||||
all_passages: list[list[dict]] = []
|
||||
for passage in layout["passages"]:
|
||||
controls_q = [[float(value) for value in point["position_q"]]
|
||||
+ [float(point["radius_q"])] for point in passage["control_points"]]
|
||||
controls = [point.copy() for point in controls_q]
|
||||
upper_mouth = [value / qpm for value in passage["upper_mouth_q"]]
|
||||
upper_depth = max(0.0, (controls[0][2] / qpm) - upper_mouth[2] + 1.13)
|
||||
upper_stratum = strata.get(passage["upper_strate_index"], {})
|
||||
if upper_stratum.get("generator_kind") == "FloatingIslands":
|
||||
route = []
|
||||
for anchor in upper_stratum.get("anchors", []):
|
||||
if anchor.get("kind") == "route_point" and len(anchor.get("values", [])) >= 3:
|
||||
route.append([value / qpm for value in anchor["values"][:3]])
|
||||
if route:
|
||||
route_height, distance_sq = closest_route_height(
|
||||
route, controls[0][0] / qpm, controls[0][1] / qpm)
|
||||
if distance_sq <= (controls[0][3] / qpm + 2.0) ** 2:
|
||||
upper_depth = max(upper_depth,
|
||||
controls[0][2] / qpm - route_height + 1.13)
|
||||
controls[0][3] = max(controls[0][3], upper_depth * qpm)
|
||||
|
||||
lower_mouth = [value for value in passage["lower_mouth_q"]]
|
||||
player_center_q = round(1.13 * qpm)
|
||||
route_end = len(controls) - 1
|
||||
for index in range(1, len(controls_q)):
|
||||
p = controls_q[index]
|
||||
if (int(p[0]) == lower_mouth[0] and int(p[1]) == lower_mouth[1]
|
||||
and int(p[2] - p[3] + player_center_q) == lower_mouth[2]):
|
||||
route_end = index
|
||||
|
||||
raw = build_raw_segments(controls, qpm)
|
||||
total_path = 0.0
|
||||
for segment in raw:
|
||||
if segment["span"] + 1 == route_end:
|
||||
total_path = segment["along"] + segment["length"]
|
||||
radii = [(0.0, controls[0][3] / qpm)]
|
||||
for segment in raw:
|
||||
if segment["span"] < route_end:
|
||||
radii.append((segment["along"] + segment["length"],
|
||||
segment["b"][3] / qpm))
|
||||
body_radii = [radius for along, radius in radii
|
||||
if along >= 10.0 and total_path - along >= 10.0]
|
||||
minimum_body = min(body_radii) if body_radii else min(radius for _, radius in radii)
|
||||
floor_depth = max(0.5, minimum_body - 0.23)
|
||||
|
||||
prepared = []
|
||||
for segment in raw:
|
||||
route_segment = segment["span"] < route_end
|
||||
along_b = segment["along"] + segment["length"]
|
||||
|
||||
def effective_z(raw_z: float, radius: float, planned_floor: float,
|
||||
along: float) -> float:
|
||||
raw_z /= qpm
|
||||
radius /= qpm
|
||||
planned_floor /= qpm
|
||||
local_depth = min(floor_depth, max(0.0, radius - 0.23))
|
||||
if route_segment or abs(along - total_path) <= 1.0e-9:
|
||||
return planned_floor + local_depth
|
||||
route_depth = max(0.0, radius - 0.23)
|
||||
return raw_z - route_depth + local_depth
|
||||
|
||||
a = [segment["a"][0] / qpm, segment["a"][1] / qpm,
|
||||
effective_z(segment["a"][2], segment["a"][3],
|
||||
segment["floor_a"], segment["along"])]
|
||||
b = [segment["b"][0] / qpm, segment["b"][1] / qpm,
|
||||
effective_z(segment["b"][2], segment["b"][3],
|
||||
segment["floor_b"], along_b)]
|
||||
prepared.append({"a": a, "b": b, "radius_a": segment["a"][3] / qpm,
|
||||
"radius_b": segment["b"][3] / qpm})
|
||||
all_passages.append(prepared)
|
||||
return all_passages
|
||||
|
||||
|
||||
def profile_tiles() -> list[tuple[int, int, int, int, int, int, int, int]]:
|
||||
result = []
|
||||
for strate, path in enumerate(BASELINE_LOGS):
|
||||
if not path.is_file():
|
||||
raise SystemExit(f"missing baseline profile: {path}")
|
||||
seen = set()
|
||||
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
|
||||
if not line.startswith("[PassageComposerTile] "):
|
||||
continue
|
||||
row = dict(PROFILE.findall(line))
|
||||
match = TILE_KEY.search(row.get("key", ""))
|
||||
if not match:
|
||||
continue
|
||||
x, y, z, lod = map(int, match.groups())
|
||||
if lod > 2:
|
||||
continue
|
||||
key = (x, y, z, lod)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
result.append((strate, x, y, z, lod, int(row.get("features", 0)),
|
||||
int(row.get("route_candidates", 0)),
|
||||
int(row.get("sweep_pairs", 0))))
|
||||
return result
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not LAYOUT.is_file():
|
||||
raise SystemExit(f"missing resolved layout: {LAYOUT}")
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
|
||||
passages = prepared_segments(layout)
|
||||
tiles = profile_tiles()
|
||||
input_path = OUT / "reach-input.tsv"
|
||||
with input_path.open("w", encoding="utf-8") as output:
|
||||
for passage_index, segments in enumerate(passages):
|
||||
for segment_index, segment in enumerate(segments):
|
||||
values = [*segment["a"], *segment["b"],
|
||||
segment["radius_a"], segment["radius_b"]]
|
||||
output.write("S {} {} {}\n".format(passage_index, segment_index,
|
||||
" ".join(f"{value:.15g}" for value in values)))
|
||||
for tile in tiles:
|
||||
output.write("T {}\n".format(" ".join(str(value) for value in tile)))
|
||||
|
||||
binary = OUT / "CountReachCandidates"
|
||||
compile_log = OUT / "compile.log"
|
||||
with compile_log.open("w", encoding="utf-8") as log:
|
||||
built = subprocess.run(["g++", "-std=c++20", "-O3", "-DNDEBUG",
|
||||
str(HERE / "CountReachCandidates.cpp"), "-o", str(binary)],
|
||||
cwd=ROOT, stdout=log, stderr=subprocess.STDOUT,
|
||||
check=False)
|
||||
if built.returncode:
|
||||
raise SystemExit(f"counter compile failed: {compile_log}")
|
||||
result_path = OUT / "results.csv"
|
||||
run_log = OUT / "counter.log"
|
||||
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||
str(binary), str(input_path), str(result_path)]
|
||||
with run_log.open("w", encoding="utf-8") as log:
|
||||
result = subprocess.run(command, cwd=ROOT, stdout=log, stderr=subprocess.STDOUT,
|
||||
check=False, timeout=1740)
|
||||
if result.returncode:
|
||||
raise SystemExit(f"counter failed: {run_log}; exit={result.returncode}")
|
||||
print(f"[L129Precount] segments={[len(x) for x in passages]} "
|
||||
f"profile_tiles={len(tiles)} input={input_path.relative_to(ROOT)} "
|
||||
f"results={result_path.relative_to(ROOT)}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,54 @@
|
||||
# L129 — tunnel reach
|
||||
|
||||
**Decision: no-go for performance.** The 2 m candidate passed the geometry checks, but it was slower than both timing references and failed every UE movement comparison. The count pass also found a units mismatch in v225's reach bounds, so the requested physical reach cannot be cut cheaply against the source as it stands.
|
||||
|
||||
## What the reach includes
|
||||
|
||||
The 4.0 m term is the signed-distance influence cutoff outside the bore. The bound adds 0.21 m for wall relief and reserves 0.125 m for the 0.50 m smooth corner (`width/6` is about 0.083 m). The plain shell is 0.75 m thick, so its minimum reach with relief is 0.96 m. The larger term wins: `r + max(R + 0.21 + 0.125, 0.75 + 0.21) + 0.05 m`. At `R=4 m` and the maximum `r=3.5 m`, that is 7.885 m.
|
||||
|
||||
The mouth blend is 5 m **along the route**, not an added radial reach. The open-air half-pipe's side wall is 1 m high; its rounded crest uses the same reach. L129 leaves the 0.75 m shell rule, smooth floor `h(s)`, rounded crest, and grade limit unchanged. The highest audited grade was 10.695°.
|
||||
|
||||
## Counts before the build
|
||||
|
||||
Counts cover the four owner strata at LOD0–2, with 993 route segments. “Pairs” are route-segment/sample checks; “support” is unique per-passage samples inside the distance cutoff. The v225 model's 29.87M pairs is close to the measured source profile's 29.41M.
|
||||
|
||||
| Reach and bounds | Pairs (M) | Support samples (M) | Overlap pairs (M) | Feature / proof-active tiles |
|
||||
|---|---:|---:|---:|---:|
|
||||
| v225 as coded, nominal 4 m | 29.87 | 8.57 | 20.90 | 721 / 677 |
|
||||
| 4 m, physical bounds | 124.97 | 11.72 | 46.64 | 826 / 791 |
|
||||
| 3 m, physical bounds | 87.06 | 8.84 | 30.42 | 787 / 764 |
|
||||
| 2 m, physical bounds | 56.86 | 6.32 | 18.48 | 755 / 729 |
|
||||
| 1.5 m, physical bounds | 44.74 | 5.21 | 13.93 | 743 / 718 |
|
||||
|
||||
Against a correctly bounded 4 m model, 2 m removes 54.5% of pairs and 60.4% of overlap pairs; 71 feature tiles and 62 proof-active tiles become free. Against the v225-as-coded count model, however, physical 2 m adds 90.3% of raw pairs and leaves 34 more feature tiles and 52 more proof-active tiles. Physical 1.5 m still adds 49.8% of pairs and leaves 22 more feature tiles and 41 more proof-active tiles. So the smaller reach does **not** unlock proofs or tile skips versus the shipped source.
|
||||
|
||||
The cause is in `BuildPassageSpatialIndices`: positions are converted to core voxels before the reach is added, but v225 adds the metre value directly. At 0.25 m per core voxel, the nominal 4.335 m bound is only 1.084 m per axis; the sweep cutoff itself remains 4 m. L129 converts the smaller physical bounds to core voxels. That makes its broadphase boxes larger than v225's, even though its actual influence cutoff is smaller. The extra segment/sample checks erase the predicted saving. The 2 m setting was selected from the pre-build counts and is the only reach fully timed.
|
||||
|
||||
## Timing and quality
|
||||
|
||||
Five interleaved L80 runs per W8/W12 cell were completed on a quiet machine (load 0.71, CPU idle 97.3%). L125 is the `b96dd73` source. Every near-ready cell and every whole-view cell was slower than L109 and b96dd73:
|
||||
|
||||
| Stratum / workers | Near vs L109 / base | Whole view vs L109 / base |
|
||||
|---|---:|---:|
|
||||
| S0 W8 | +11.1% / +9.3% | +7.5% / +7.2% |
|
||||
| S0 W12 | +11.2% / +6.6% | +5.5% / +3.3% |
|
||||
| S1 W8 | +16.7% / +7.8% | +8.7% / +5.3% |
|
||||
| S1 W12 | +17.9% / +9.9% | +9.5% / +5.6% |
|
||||
| S2 W8 | +12.8% / +8.4% | +5.3% / +5.2% |
|
||||
| S2 W12 | +17.1% / +9.1% | +10.3% / +5.7% |
|
||||
| S3 W8 | +13.4% / +4.9% | +6.3% / +2.8% |
|
||||
| S3 W12 | +18.2% / +6.9% | +8.9% / +4.2% |
|
||||
|
||||
Five UE runs at 30 m/s also missed the b96dd73 gate: near coverage 38.05% vs 40.22% (−2.17 points), far holes 4.03% vs 3.46% (+0.58 points), tick p99 11.54 vs 10.80 ms (+0.74 ms), and worst tick 14.12 vs 13.27 ms (+0.85 ms). The Linux UE host build passed after timing with `-NoUBA -MaxParallelActions=4`; Unreal was not run under `prlimit`.
|
||||
|
||||
Fast verification passed (259 checks; 5 historical diagnostics), walkability passed at 21,425/21,425, all three passage grades stayed below 15°, and the seam audit passed 4 joins / 4,900 samples with no mismatches. Clang and GCC hashes matched for W1/W8/W12 across all three tested owner layouts (18 cases). Evaluator version 226 and three canonical owner hash baselines were added.
|
||||
|
||||
The 23 L125 pose captures and six paired mouth close-ups are verified. All before/after PNGs are pixel-identical; these views show no visible change. The floor probe peaked at 7.9 mm, above a strict “few millimetres” reading.
|
||||
|
||||
## Captures and records
|
||||
|
||||
- [L125 poses: before / L129 comparison](captures/COMPARE.html)
|
||||
- [Mouth close-ups: before / L129 comparison](captures/L129-mouth/COMPARE.html)
|
||||
- [L80 timing results](../../../../Saved/Linux/l129/timing/summary.json)
|
||||
- [UE movement results](../../../../Saved/Linux/l129/movement/summary.json)
|
||||
- [Pre-build count results](../../../../Saved/Linux/l129/precount/results.csv)
|
||||
@@ -1,27 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Render the exact 23 L125 camera views with the L128 slab-ownership candidate."""
|
||||
"""Render the 23 L125 camera poses with the L129 candidate."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
RESEARCH = Path(__file__).resolve().parent
|
||||
CAPTURES = RESEARCH / "captures"
|
||||
SAVED = ROOT / "Saved/Linux/l128/captures"
|
||||
SAVED = ROOT / "Saved/Linux/l129/captures"
|
||||
BASELINE_INDEX = (ROOT / "Standalone/Research/WorldAssemblerM3/Linux125"
|
||||
/ "captures/L125/capture-index.json")
|
||||
LAYOUT = ROOT / "Saved/Linux/l128/hashes/owner4-surface-world-w12-clang.layout.json"
|
||||
CLANG = ROOT / os.environ.get("L128_CAPTURE_CLANG",
|
||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19")
|
||||
RENDERER = ROOT / os.environ.get("L128_CAPTURE_RENDERER",
|
||||
"Saved/Linux/l128/bin/VoxelForgeOffscreenCapture-clang19")
|
||||
LAYOUT = ROOT / "Saved/Linux/l129/hashes/owner4-surface-world-w12-clang.layout.json"
|
||||
CLANG = ROOT / os.environ.get("L129_CAPTURE_CLANG",
|
||||
"Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang")
|
||||
RENDERER = ROOT / os.environ.get("L129_CAPTURE_RENDERER",
|
||||
"Saved/Linux/l129/bin/VoxelForgeOffscreenCapture-l129-clang")
|
||||
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
|
||||
|
||||
SPEC = importlib.util.spec_from_file_location("l113_capture_helpers", HELPER_PATH)
|
||||
@@ -32,21 +29,21 @@ SPEC.loader.exec_module(HELPERS)
|
||||
HELPERS.RESEARCH = RESEARCH
|
||||
HELPERS.CAPTURES = CAPTURES
|
||||
HELPERS.SAVED = SAVED
|
||||
HELPERS.BINARIES = {"L128": CLANG}
|
||||
HELPERS.RENDERERS = {"L128": RENDERER}
|
||||
HELPERS.BINARIES = {"L129": CLANG}
|
||||
HELPERS.RENDERERS = {"L129": RENDERER}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if any(not path.is_file() for path in (BASELINE_INDEX, LAYOUT, CLANG, RENDERER)):
|
||||
raise SystemExit("missing L125 camera set, L128 layout, or capture binary")
|
||||
raise SystemExit("missing L125 camera set, L129 layout, or capture binary")
|
||||
baseline = json.loads(BASELINE_INDEX.read_text(encoding="utf-8"))
|
||||
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
|
||||
rows = []
|
||||
CAPTURES.mkdir(parents=True, exist_ok=True)
|
||||
SAVED.mkdir(parents=True, exist_ok=True)
|
||||
for view in baseline["captures"]:
|
||||
row = HELPERS.capture("L128", view, layout)
|
||||
row["variant"] = "L128-slab-ownership-v226"
|
||||
row = HELPERS.capture("L129", view, layout)
|
||||
row["variant"] = "L129-v226"
|
||||
if view["kind"] == "rock-floor-close":
|
||||
scene = ROOT / row["scene"]
|
||||
anchor = HELPERS.nearest_surface_anchor(scene, view["target"], margin_m=5.0,
|
||||
@@ -63,22 +60,21 @@ def main() -> int:
|
||||
or row["drawn_triangles"] <= 0
|
||||
or row["pixel_quality_status"] not in
|
||||
("pass", "low_contrast_geometry_visible")):
|
||||
raise RuntimeError(f"L128 floor close-up failed at {view['name']}")
|
||||
raise RuntimeError(f"L129 floor close-up failed at {view['name']}")
|
||||
rows.append(row)
|
||||
if len(rows) != len(baseline["captures"]) or len(rows) != 23:
|
||||
raise RuntimeError(f"expected all 23 L125 views, captured {len(rows)}")
|
||||
index = CAPTURES / "L128" / "capture-index.json"
|
||||
index = CAPTURES / "L129" / "capture-index.json"
|
||||
index.parent.mkdir(parents=True, exist_ok=True)
|
||||
index.write_text(json.dumps({"captures": rows}, indent=2) + "\n",
|
||||
encoding="utf-8")
|
||||
encoding="utf-8")
|
||||
|
||||
html = ["<!doctype html><meta charset='utf-8'>",
|
||||
"<title>L125 / L128 tunnel capture comparison</title>",
|
||||
"<title>L125 / L129 tunnel capture comparison</title>",
|
||||
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
|
||||
"section{margin:28px 0}h2{font-size:18px}div{display:grid;"
|
||||
"grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}"
|
||||
"p{color:#bbb}</style>",
|
||||
"<h1>L125 / L128 slab ownership: identical views</h1>"]
|
||||
"p{color:#bbb}</style>", "<h1>L125 / L129 v226: identical views</h1>"]
|
||||
old_by_name = {Path(row["capture"]).name: row for row in baseline["captures"]}
|
||||
for row in rows:
|
||||
name = Path(row["capture"]).name
|
||||
@@ -88,14 +84,13 @@ def main() -> int:
|
||||
new_path = os.path.relpath(RESEARCH / row["capture"], CAPTURES)
|
||||
html.extend(["<section>", f"<h2>{row['passage']} — {row['station']}</h2>",
|
||||
f"<p>{row['kind']} · L125 {old['pixel_quality_status']} · "
|
||||
f"L128 {row['pixel_quality_status']}</p>", "<div>",
|
||||
f"L129 {row['pixel_quality_status']}</p>", "<div>",
|
||||
f"<figure><figcaption>L125</figcaption><img src='{old_path}'></figure>",
|
||||
f"<figure><figcaption>L128 slab ownership</figcaption><img src='{new_path}'></figure>",
|
||||
f"<figure><figcaption>L129 v226</figcaption><img src='{new_path}'></figure>",
|
||||
"</div>", "</section>"])
|
||||
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n",
|
||||
encoding="utf-8")
|
||||
print(f"[L128Captures] rendered={len(rows)} views index={index.relative_to(ROOT)}",
|
||||
flush=True)
|
||||
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n", encoding="utf-8")
|
||||
print(f"[L129Captures] rendered={len(rows)} views index={index.relative_to(ROOT)}",
|
||||
flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
OUT = ROOT / os.environ.get("L128_PROBE_DIR", "Saved/Linux/l128/floor-probe")
|
||||
BINARY = ROOT / os.environ.get("L128_PROBE_BINARY",
|
||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19")
|
||||
OUT = ROOT / os.environ.get("L129_PROBE_DIR", "Saved/Linux/l129/density-probe")
|
||||
BINARY = ROOT / os.environ.get("L129_PROBE_BINARY",
|
||||
"Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang")
|
||||
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||
SLOPE = re.compile(
|
||||
r"^\[L115DensitySlopeSample\] passage=(\S+) station=(\S+) s_m=([\d.]+) "
|
||||
@@ -53,20 +53,13 @@ def main() -> int:
|
||||
"planned_floor_m", "root_floor_m", "offset_m"))
|
||||
writer.writeheader()
|
||||
for (passage, station), samples in sorted(groups.items()):
|
||||
samples.sort(key=lambda sample: sample["route_s_m"])
|
||||
for sample in samples:
|
||||
writer.writerow({"passage": passage, "station": station, **sample})
|
||||
finite = [sample["offset_m"] for sample in samples
|
||||
if math.isfinite(sample["offset_m"])]
|
||||
adjacent_steps = [abs(right["offset_m"] - left["offset_m"])
|
||||
for left, right in zip(samples, samples[1:])
|
||||
if math.isfinite(left["offset_m"])
|
||||
and math.isfinite(right["offset_m"])]
|
||||
summary.append({"passage": passage, "station": station,
|
||||
"samples": len(samples), "finite_roots": len(finite),
|
||||
"max_abs_offset_m": max(map(abs, finite)) if finite else None,
|
||||
"max_adjacent_root_step_m": max(adjacent_steps)
|
||||
if adjacent_steps else None,
|
||||
"median_abs_offset_m": statistics.median(map(abs, finite))
|
||||
if finite else None,
|
||||
"p95_abs_offset_m": sorted(map(abs, finite))[
|
||||
@@ -74,12 +67,9 @@ def main() -> int:
|
||||
if finite else None})
|
||||
if not summary or any(item["samples"] != 51 for item in summary):
|
||||
raise RuntimeError("density profile is missing 51-sample route stations")
|
||||
worst_step = max(item["max_adjacent_root_step_m"] or 0.0 for item in summary)
|
||||
if worst_step > 0.003:
|
||||
raise RuntimeError(f"floor root jumps by {worst_step:.6f} m between 0.1 m probes")
|
||||
(OUT / "zero-crossing-summary.json").write_text(
|
||||
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
|
||||
print(f"[L128DensityProbe] exit={result.returncode} stations={len(summary)} "
|
||||
print(f"[L129DensityProbe] exit={result.returncode} stations={len(summary)} "
|
||||
f"log={log.relative_to(ROOT)}", flush=True)
|
||||
return result.returncode
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check Clang/GCC W1/W8/W12 hash determinism for L128."""
|
||||
"""Check Clang/GCC W1/W8/W12 hashes and compare the candidate with L119."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -10,16 +10,16 @@ import time
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
OUT = ROOT / os.environ.get("L128_HASH_DIR", "Saved/Linux/l128/hashes")
|
||||
OUT = ROOT / os.environ.get("L129_HASH_DIR", "Saved/Linux/l129/hashes")
|
||||
DATASETS = {
|
||||
"owner4": ROOT / "Standalone/data/owner_world.json",
|
||||
"owner2": ROOT / "Standalone/data/regression/owner_world_2strate_l61.json",
|
||||
}
|
||||
BINARIES = {
|
||||
"clang": ROOT / os.environ.get("L128_HASH_CLANG",
|
||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19"),
|
||||
"gcc": ROOT / os.environ.get("L128_HASH_GCC",
|
||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-l128-gcc"),
|
||||
"clang": ROOT / os.environ.get("L129_HASH_CLANG",
|
||||
"Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang"),
|
||||
"gcc": ROOT / os.environ.get("L129_HASH_GCC",
|
||||
"Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-gcc"),
|
||||
}
|
||||
HASH = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
|
||||
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=(\S+)$", re.M)
|
||||
@@ -53,13 +53,17 @@ def run(dataset: str, recipe: str, workers: int, compiler: str) -> dict:
|
||||
if STAMP.search(output) else None),
|
||||
"elapsed_s": round(time.monotonic() - started, 3),
|
||||
"log": str(log.relative_to(ROOT))}
|
||||
print("[L128HashRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||
print("[L129HashRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||
return row
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if any(not path.is_file() for path in (*DATASETS.values(), *BINARIES.values())):
|
||||
raise SystemExit("missing L128 hash input")
|
||||
raise SystemExit("missing L129 hash input")
|
||||
previous_path = ROOT / "Saved/Linux/l119/hashes/summary.json"
|
||||
previous_doc = json.loads(previous_path.read_text(encoding="utf-8"))
|
||||
previous = {(row["dataset"], row["recipe"], row["workers"], row["compiler"]): row
|
||||
for row in previous_doc["runs"]}
|
||||
rows = []
|
||||
recipes = {"owner4": ("surface-world",),
|
||||
"owner2": ("surface-world", "floating-islands")}
|
||||
@@ -78,8 +82,11 @@ def main() -> int:
|
||||
and row["recipe"] == recipe]
|
||||
reference = group[0]["hashes"]
|
||||
stable = all(row["hashes"] == reference for row in group)
|
||||
old = previous[(dataset, recipe, 12, "clang")]["hashes"]
|
||||
groups[key] = {
|
||||
"all_worker_compiler_hashes_match": stable,
|
||||
"matches_l119_v224": next(row for row in group
|
||||
if row["workers"] == 12 and row["compiler"] == "clang")["hashes"] == old,
|
||||
"source_stamps": sorted({row["source_stamp"] for row in group}),
|
||||
"runs": [{"workers": row["workers"], "compiler": row["compiler"],
|
||||
"log": row["log"]} for row in group],
|
||||
@@ -104,7 +111,7 @@ def main() -> int:
|
||||
baseline = baseline_dir / baseline_name
|
||||
baseline.write_text("\n".join(canonical["hashes"]) + "\n",
|
||||
encoding="utf-8")
|
||||
print("[L128HashSummary] " + json.dumps(groups, sort_keys=True), flush=True)
|
||||
print("[L129HashSummary] " + json.dumps(groups, sort_keys=True), flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Render matching baseline and L129 close views of each tunnel mouth."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
RESEARCH = Path(__file__).resolve().parent
|
||||
CAPTURES = RESEARCH / "captures/L129-mouth"
|
||||
SAVED = ROOT / "Saved/Linux/l129/captures/mouth-closeups"
|
||||
BASE_LAYOUT = ROOT / "Saved/Linux/l125/hashes/owner4-surface-world-w12-clang.layout.json"
|
||||
AFTER_LAYOUT = ROOT / "Saved/Linux/l129/hashes/owner4-surface-world-w12-clang.layout.json"
|
||||
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
|
||||
|
||||
SPEC = importlib.util.spec_from_file_location("l113_capture_helpers", HELPER_PATH)
|
||||
if SPEC is None or SPEC.loader is None:
|
||||
raise SystemExit("cannot load verified capture helpers")
|
||||
HELPERS = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(HELPERS)
|
||||
|
||||
HELPERS.RESEARCH = RESEARCH
|
||||
HELPERS.CAPTURES = CAPTURES
|
||||
HELPERS.SAVED = SAVED
|
||||
HELPERS.BINARIES = {
|
||||
"before": ROOT / "Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang",
|
||||
"after": ROOT / "Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang",
|
||||
}
|
||||
HELPERS.RENDERERS = {
|
||||
"before": ROOT / "Saved/Linux/l125/bin/VoxelForgeOffscreenCapture-l125-clang",
|
||||
"after": ROOT / "Saved/Linux/l129/bin/VoxelForgeOffscreenCapture-l129-clang",
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
required = [BASE_LAYOUT, AFTER_LAYOUT, *HELPERS.BINARIES.values(),
|
||||
*HELPERS.RENDERERS.values()]
|
||||
if any(not path.is_file() for path in required):
|
||||
raise SystemExit("missing baseline/candidate layout or capture binary")
|
||||
before_layout = json.loads(BASE_LAYOUT.read_text(encoding="utf-8"))
|
||||
after_layout = json.loads(AFTER_LAYOUT.read_text(encoding="utf-8"))
|
||||
if before_layout["passages"] != after_layout["passages"]:
|
||||
raise RuntimeError("baseline and candidate passage routes differ")
|
||||
|
||||
views = [view for view in HELPERS.make_views(before_layout, [],
|
||||
use_derived_shape=True, use_spline=True, include_open_air=False)
|
||||
if view["kind"] == "mouth"]
|
||||
if len(views) != 2 * len(before_layout["passages"]):
|
||||
raise RuntimeError("unexpected mouth camera count")
|
||||
|
||||
rows = []
|
||||
CAPTURES.mkdir(parents=True, exist_ok=True)
|
||||
SAVED.mkdir(parents=True, exist_ok=True)
|
||||
for view in views:
|
||||
for variant, layout in (("before", before_layout), ("after", after_layout)):
|
||||
row = HELPERS.capture(variant, view, layout)
|
||||
row["variant"] = "L125-v225" if variant == "before" else "L129-v226"
|
||||
row["view"] = view["name"]
|
||||
image = ROOT / "Standalone/Research/WorldAssemblerM3/Linux129" / row["capture"]
|
||||
row["image_sha256"] = hashlib.sha256(image.read_bytes()).hexdigest()
|
||||
rows.append(row)
|
||||
|
||||
index = CAPTURES / "capture-index.json"
|
||||
index.write_text(json.dumps({"captures": rows}, indent=2) + "\n", encoding="utf-8")
|
||||
old_rows = {row["view"]: row for row in rows if row["variant"] == "L125-v225"}
|
||||
new_rows = {row["view"]: row for row in rows if row["variant"] == "L129-v226"}
|
||||
html = ["<!doctype html><meta charset='utf-8'>",
|
||||
"<title>L125 / L129 mouth close-ups</title>",
|
||||
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
|
||||
"section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}"
|
||||
"img{width:100%;height:auto}p{color:#bbb}</style>",
|
||||
"<h1>L125 v225 / L129 v226 tunnel mouths</h1>"]
|
||||
for name in old_rows:
|
||||
old, new = old_rows[name], new_rows[name]
|
||||
old_path = os.path.relpath(RESEARCH / old["capture"], CAPTURES)
|
||||
new_path = os.path.relpath(RESEARCH / new["capture"], CAPTURES)
|
||||
equality = "pixel-identical" if old["image_sha256"] == new["image_sha256"] else "pixels differ"
|
||||
html.extend(["<section>", f"<h2>{old['passage']} — {old['station']}</h2>",
|
||||
f"<p>{equality}; {old['pixel_quality_status']} / {new['pixel_quality_status']}</p>",
|
||||
"<div>", f"<figure><figcaption>L125 v225</figcaption><img src='{old_path}'></figure>",
|
||||
f"<figure><figcaption>L129 v226</figcaption><img src='{new_path}'></figure>",
|
||||
"</div>", "</section>"])
|
||||
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n", encoding="utf-8")
|
||||
print(f"[L129MouthCaptures] views={len(views)} paired={len(rows)//2} "
|
||||
f"index={index.relative_to(ROOT)}", flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Five interleaved L80 readiness runs for L109, 4041d4b and L128."""
|
||||
"""Five interleaved L80 readiness runs for L109, L125 and L129."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -11,13 +11,13 @@ import time
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
OUT = ROOT / os.environ.get("L128_TIMING_DIR", "Saved/Linux/l128/timing")
|
||||
OUT = ROOT / os.environ.get("L129_TIMING_DIR", "Saved/Linux/l129/timing")
|
||||
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||
BINARIES = {
|
||||
"L109": ROOT / "Saved/Linux/l109/bin-final/VoxelForgeCoreHeadless-l109-clang",
|
||||
"4041d4b": ROOT / "Saved/Linux/l127/bin-clang/VoxelForgeCoreHeadless-l127-clang",
|
||||
"L128": ROOT / os.environ.get("L128_CANDIDATE_BINARY",
|
||||
"Saved/Linux/l128/bin/VoxelForgeCoreHeadless-clang19"),
|
||||
"L125": ROOT / "Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang",
|
||||
"L129": ROOT / os.environ.get("L129_CANDIDATE_BINARY",
|
||||
"Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang"),
|
||||
}
|
||||
CAMERAS = {
|
||||
0: (8.0, 16.0, -372.2626953125),
|
||||
@@ -61,7 +61,7 @@ def run(strate: int, workers: int, version: str, phase: str, replicate: int) ->
|
||||
"whole_view_ready_s": float(pipeline["whole_view_ready"].removesuffix("s")),
|
||||
"whole_tiles": int(pipeline["whole_tiles"].split("/")[0]),
|
||||
"log": str(log.relative_to(ROOT))}
|
||||
print("[L128TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||
print("[L129TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
|
||||
return row
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ def cpu_idle_percent(interval_s: float = 2.0) -> float:
|
||||
|
||||
def main() -> int:
|
||||
if not DATA.is_file() or any(not binary.is_file() for binary in BINARIES.values()):
|
||||
raise SystemExit("missing L109/4041d4b/L128 timing input")
|
||||
raise SystemExit("missing L109/L125/L129 timing input")
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
load_1m, idle_pct = os.getloadavg()[0], cpu_idle_percent()
|
||||
uptime = subprocess.run(["uptime"], cwd=ROOT, text=True,
|
||||
@@ -88,13 +88,13 @@ def main() -> int:
|
||||
(OUT / "machine-load-before.txt").write_text(
|
||||
f"uptime: {uptime}\n1-minute load: {load_1m:.2f}\n"
|
||||
f"2-second CPU idle: {idle_pct:.1f}%\ntop CPU users:\n{top}", encoding="utf-8")
|
||||
print(f"[L128TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle_pct:.1f}%",
|
||||
print(f"[L129TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle_pct:.1f}%",
|
||||
flush=True)
|
||||
if load_1m >= 0.9 or idle_pct < 97.0:
|
||||
raise SystemExit("timing refused: machine is above the quiet-load gate")
|
||||
|
||||
rows = []
|
||||
versions = ("L109", "4041d4b", "L128")
|
||||
versions = ("L109", "L125", "L129")
|
||||
for strate in range(4):
|
||||
for workers in (8, 12):
|
||||
for version in versions:
|
||||
@@ -121,10 +121,10 @@ def main() -> int:
|
||||
medians[version][key] = statistics.median(values)
|
||||
item[f"{version}_{key}_values"] = values
|
||||
item[f"{version}_{key}_median"] = medians[version][key]
|
||||
for comparison in ("L109", "4041d4b"):
|
||||
for comparison in ("L109", "L125"):
|
||||
for key in ("lod02_ready_s", "whole_view_ready_s"):
|
||||
item[f"L128_vs_{comparison}_{key}_delta_pct"] = round(
|
||||
100.0 * (medians["L128"][key] / medians[comparison][key]-1.0), 2)
|
||||
item[f"L129_vs_{comparison}_{key}_delta_pct"] = round(
|
||||
100.0 * (medians["L129"][key] / medians[comparison][key]-1.0), 2)
|
||||
summary.append(item)
|
||||
(OUT / "summary.json").write_text(
|
||||
json.dumps({"runs": rows, "summary": summary}, indent=2) + "\n",
|
||||
@@ -0,0 +1,257 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Five 30 m/s UE runs for the L129 tunnel reach candidate."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import statistics
|
||||
import subprocess
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
HOST = Path("/home/jahni/VFHost")
|
||||
EDITOR = Path("/home/jahni/UnrealEngine/Engine/Binaries/Linux/UnrealEditor-Cmd")
|
||||
SPAWN_TN_M = (19.166015625, -14.2001953125, -753.3740234375)
|
||||
SPAWN_FI_M = (25.8369140625, 3.19921875, -737.0)
|
||||
|
||||
|
||||
def percentile(values: list[float], fraction: float) -> float | None:
|
||||
if not values:
|
||||
return None
|
||||
ordered = sorted(values)
|
||||
return ordered[max(0, min(len(ordered) - 1, math.ceil(len(ordered) * fraction) - 1))]
|
||||
|
||||
|
||||
def read_events(path: Path) -> list[dict]:
|
||||
rows = []
|
||||
if path.is_file():
|
||||
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
|
||||
if not line.startswith("{"):
|
||||
continue
|
||||
try:
|
||||
rows.append(json.loads(line))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return rows
|
||||
|
||||
|
||||
def run(scenario: str, condition: str, repetition: int, turn: bool = False) -> dict:
|
||||
lookahead = int(condition in ("lookahead", "turn_lookahead"))
|
||||
if scenario == "movement":
|
||||
speed, start, duration, exit_s, slot, spawn = (
|
||||
3000.0, 6.0, 12.0, 23.0, 0, SPAWN_TN_M)
|
||||
else:
|
||||
speed, start, duration, exit_s, slot, spawn = (
|
||||
140.0, 20.0, 12.0, 37.0, 1, SPAWN_FI_M)
|
||||
|
||||
label = f"{scenario}-{condition}-r{repetition}"
|
||||
output_group = "turn" if turn else scenario
|
||||
out = ROOT / "Saved/Linux/l129" / output_group / condition / "unreal"
|
||||
host_out = HOST / "Plugins/VoxelForge/Saved/Linux/l129" / output_group / condition
|
||||
host_saved = HOST / "Saved/Linux/l129"
|
||||
trace = out / f"{label}.trace.jsonl"
|
||||
abslog = out / f"{label}.log"
|
||||
stdout = out / f"{label}.stdout.log"
|
||||
export = host_out / "output" / label
|
||||
userdir = host_saved / "user" / label
|
||||
zendata = host_saved / "zen" / label
|
||||
ddc = host_saved / "DDC"
|
||||
for path in (out, export, userdir, zendata, ddc):
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
trace.unlink(missing_ok=True)
|
||||
spawn_cm = ",".join(f"{value * 100.0:.3f}" for value in spawn)
|
||||
command = [
|
||||
str(EDITOR), str(HOST / "VFHost.uproject"), "-nullrhi", "-unattended",
|
||||
"-nop4", "-nosplash", "-NoSound", "-corelimit=12", "-NoZenAutoLaunch",
|
||||
"-notraceserver", "-nocrashreports", "-DisablePlugins=AndroidFileServer",
|
||||
"-ddc=NoZenLocalFallback", f"-userdir={userdir}", f"-ZenDataPath={zendata}",
|
||||
f"-LocalDataCachePath={ddc}", "-run=VoxelForgeExplore", "-seed=0",
|
||||
"-archetype=TunnelNetwork", f"-slot={slot}", "-modes=export", "-gameconfig=1",
|
||||
"-coreworldtest=1", "-ownerfourstrateplan=1", "-corevoxelsizecm=25",
|
||||
"-coreislandtest=0", "-corefallbacktest=0", "-coreofftest=0", "-coreplantest=0",
|
||||
"-settingsref=/Game/VoxelForge/DA_Settings.DA_Settings", "-corehybridmesher=0",
|
||||
f"-out={export}", "-voxel.StreamingCoarseFirst=1",
|
||||
"-voxel.StreamingDynamicNearReserve=1", "-voxel.StreamingLegacyPendingResultCap=0",
|
||||
"-voxel.CoreRegionConcurrentAdmission=1", "-voxel.StreamingResultBacklogCap=256",
|
||||
"-voxel.StreamingReadyQueueDepth=8", "-voxel.StreamingBackgroundWorkerCap=1",
|
||||
"-voxel.CoreColumnCacheDirectMapped=0", "-voxel.StreamingFarApplySupplement=1",
|
||||
"-voxel.CoreMCGradientMemoization=1", "-voxel.StreamingCollisionLookahead=1",
|
||||
f"-voxel.CoreRegionLookahead={lookahead}", "-voxel.TestMove=1",
|
||||
f"-voxel.TestMoveSpeedCmPerSecond={speed:.1f}",
|
||||
f"-voxel.TestMoveStartSeconds={start:.1f}",
|
||||
f"-voxel.TestMoveDurationSeconds={duration:.1f}",
|
||||
f"-voxel.TestExitSeconds={exit_s:.1f}", "-voxel.TestMoveDirection=1,0,0",
|
||||
"-voxel.StreamingSchedulerPolicy=3", "-voxel.TestExitOnSteady=0",
|
||||
"-coreworldstreamtrace=1", f"-voxel.StartupTraceSpawnCm={spawn_cm}",
|
||||
"-voxel.StartupTraceUntilEndPlay=1", "-voxel.StartupTraceThroughCrossing=1",
|
||||
"-voxel.StartupTraceMaxTiles=16384", f"-voxel.StartupTraceFile={trace}",
|
||||
f"-abslog={abslog}",
|
||||
]
|
||||
if turn:
|
||||
command.extend(["-voxel.TestMoveTurnAfterSeconds=6.0",
|
||||
"-voxel.TestMoveTurnDirection=0,1,0"])
|
||||
started = time.monotonic()
|
||||
wrapped = ["taskset", "-c", "0-11", "timeout", "1740s", *command]
|
||||
with stdout.open("w", encoding="utf-8") as stream:
|
||||
process = subprocess.run(wrapped, cwd=ROOT, stdout=stream,
|
||||
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
||||
events = read_events(trace)
|
||||
samples = [event for event in events if event.get("type") == "streaming_sample"]
|
||||
moving = [event for event in samples if float(event.get("speed_cm_s", 0.0)) >= 50.0]
|
||||
stop_event = next((event for event in events
|
||||
if event.get("type") == "streaming_test_move_stopped"), {})
|
||||
stop_s = float(stop_event.get("t_s", 0.0))
|
||||
move_start = min((float(event.get("t_s", 0.0)) for event in moving), default=float("inf"))
|
||||
dwell = [event for event in samples if float(event.get("t_s", 0.0)) >= stop_s
|
||||
and float(event.get("speed_cm_s", 0.0)) < 50.0]
|
||||
backend = next((event for event in events if event.get("type") == "worker_backend_config"), {})
|
||||
cap = next((event for event in events if event.get("type") == "streaming_worker_cap_readback"), {})
|
||||
if process.returncode or len(moving) < 40 or len(dwell) < 16:
|
||||
raise RuntimeError(f"incomplete UE run {label}: exit={process.returncode}, "
|
||||
f"move={len(moving)}, dwell={len(dwell)}, trace={trace}")
|
||||
if (int(backend.get("streaming_far_apply_supplement", -1)) != 1
|
||||
or int(cap.get("streaming_background_worker_cap", -1)) != 1
|
||||
or int(backend.get("effective_tile_slots", -1)) != 8):
|
||||
raise RuntimeError(f"configuration readback mismatch: {backend}; {cap}")
|
||||
|
||||
moving_rows = []
|
||||
for event in moving:
|
||||
desired = event.get("desired_by_lod", [0] * 9)
|
||||
resident = event.get("resident_by_lod", [0] * 9)
|
||||
covered = event.get("covered_by_lod", resident)
|
||||
moving_rows.append({
|
||||
"near_ready_pct": 100.0 * sum(resident[:3]) / max(1, sum(desired[:3])),
|
||||
"lod0_ready_pct": 100.0 * resident[0] / max(1, desired[0]),
|
||||
"lod1_ready_pct": 100.0 * resident[1] / max(1, desired[1]),
|
||||
"lod2_ready_pct": 100.0 * resident[2] / max(1, desired[2]),
|
||||
"far_hole_pct": 100.0 * (sum(desired[3:]) - sum(covered[3:]))
|
||||
/ max(1, sum(desired[3:])),
|
||||
})
|
||||
work = [event for event in events if event.get("type") == "game_thread_work_frame"
|
||||
and move_start <= float(event.get("t_s", 0.0)) < stop_s]
|
||||
ticks = [float(event.get("tick_ms", 0.0)) for event in work]
|
||||
updates = [float(event.get("update_chunks_ms", 0.0)) for event in work]
|
||||
arrival = [event for event in samples if float(event.get("t_s", 0.0)) < start
|
||||
and float(event.get("speed_cm_s", 0.0)) < 50.0]
|
||||
|
||||
def settled(event: dict, end: int) -> bool:
|
||||
desired = event.get("desired_by_lod", [0] * 9)
|
||||
actual = event.get("settled_by_lod", [0] * 9)
|
||||
return sum(desired[:end]) > 0 and sum(actual[:end]) >= sum(desired[:end])
|
||||
|
||||
def far_holes(event: dict) -> float | None:
|
||||
desired = event.get("desired_by_lod", [0] * 9)[3:]
|
||||
covered = event.get("covered_by_lod", [0] * 9)[3:]
|
||||
return 100.0 * (sum(desired) - sum(covered)) / sum(desired) if sum(desired) else None
|
||||
|
||||
near_settled = next((event for event in arrival if settled(event, 3)), None)
|
||||
whole_settled = next((event for event in arrival if settled(event, 9)), None)
|
||||
far_clear = next((event for event in arrival if far_holes(event) == 0.0), None)
|
||||
compile_done = [event for event in events if event.get("type") == "core_region_compile_complete"
|
||||
and move_start <= float(event.get("t_s", 0.0)) < stop_s]
|
||||
compile_requests = [event for event in events
|
||||
if event.get("type") == "core_region_compile_request"
|
||||
and move_start <= float(event.get("t_s", 0.0)) < stop_s]
|
||||
lookahead_turns = [event for event in events
|
||||
if event.get("type") == "core_region_lookahead_turn"]
|
||||
row = {
|
||||
"scenario": scenario, "condition": condition, "repetition": repetition,
|
||||
"speed_mps": speed / 100.0, "core_region_lookahead": lookahead,
|
||||
"exit_code": process.returncode, "wall_s": round(time.monotonic() - started, 3),
|
||||
"moving_samples": len(moving), "dwell_samples": len(dwell),
|
||||
"near_ready_moving_mean_pct": statistics.mean(r["near_ready_pct"] for r in moving_rows),
|
||||
"lod0_ready_moving_mean_pct": statistics.mean(r["lod0_ready_pct"] for r in moving_rows),
|
||||
"lod1_ready_moving_mean_pct": statistics.mean(r["lod1_ready_pct"] for r in moving_rows),
|
||||
"lod2_ready_moving_mean_pct": statistics.mean(r["lod2_ready_pct"] for r in moving_rows),
|
||||
"far_holes_moving_mean_pct": statistics.mean(r["far_hole_pct"] for r in moving_rows),
|
||||
"game_thread_tick_p99_ms": percentile(ticks, 0.99),
|
||||
"game_thread_tick_max_ms": max(ticks, default=None),
|
||||
"stream_update_p99_ms": percentile(updates, 0.99),
|
||||
"stream_update_max_ms": max(updates, default=None),
|
||||
"lod02_settled_t_s": float(near_settled["t_s"]) if near_settled else None,
|
||||
"whole_view_settled_t_s": float(whole_settled["t_s"]) if whole_settled else None,
|
||||
"far_clear_t_s": float(far_clear["t_s"]) if far_clear else None,
|
||||
"far_holes_at_pre_move_pct": far_holes(arrival[-1]) if arrival else None,
|
||||
"pending_gate_p50_ms": percentile(
|
||||
[float(e.get("pending_gate_elapsed_ms", 0.0)) for e in compile_done], 0.50),
|
||||
"compile_queue_p95_ms": percentile(
|
||||
[float(e.get("compile_queue_ms", 0.0)) for e in compile_done], 0.95),
|
||||
"compile_task_p95_ms": percentile(
|
||||
[float(e.get("compile_task_ms", 0.0)) for e in compile_done], 0.95),
|
||||
"compiled_tiles_total": sum(int(e.get("compiled_tiles", 0)) for e in compile_done),
|
||||
"lookahead_tiles_peak": max((int(e.get("lookahead_region_tiles", 0))
|
||||
for e in compile_requests), default=0),
|
||||
"wasted_prefetch_tiles": sum(int(e.get("wasted_prefetch_tiles", 0))
|
||||
for e in compile_done),
|
||||
"lookahead_turn_events": lookahead_turns,
|
||||
"compile_completion_count": len(compile_done),
|
||||
"trace": str(trace.relative_to(ROOT)), "log": str(abslog.relative_to(ROOT)),
|
||||
}
|
||||
with (ROOT / "Saved/Linux/l129" / "runs.jsonl").open("a", encoding="utf-8") as stream:
|
||||
stream.write(json.dumps(row, sort_keys=True) + "\n")
|
||||
print("[L129Pair] " + json.dumps(row, sort_keys=True), flush=True)
|
||||
return row
|
||||
|
||||
|
||||
def pairs_for(runs: list[dict], scenario: str) -> list[dict]:
|
||||
pairs = []
|
||||
for repetition in range(1, 6):
|
||||
baseline = next(row for row in runs if row["scenario"] == scenario
|
||||
and row["condition"] == "baseline" and row["repetition"] == repetition)
|
||||
candidate = next(row for row in runs if row["scenario"] == scenario
|
||||
and row["condition"] == "lookahead" and row["repetition"] == repetition)
|
||||
pairs.append({"repetition": repetition,
|
||||
"near_ready_delta_pct": candidate["near_ready_moving_mean_pct"]
|
||||
- baseline["near_ready_moving_mean_pct"],
|
||||
"far_holes_delta_pct": candidate["far_holes_moving_mean_pct"]
|
||||
- baseline["far_holes_moving_mean_pct"],
|
||||
"tick_p99_delta_ms": candidate["game_thread_tick_p99_ms"]
|
||||
- baseline["game_thread_tick_p99_ms"],
|
||||
"tick_max_delta_ms": candidate["game_thread_tick_max_ms"]
|
||||
- baseline["game_thread_tick_max_ms"]})
|
||||
return pairs
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--scenario", choices=("movement",), default="movement")
|
||||
args = parser.parse_args()
|
||||
if not EDITOR.is_file():
|
||||
raise SystemExit(f"missing Unreal editor: {EDITOR}")
|
||||
root_out = ROOT / "Saved/Linux/l129" / args.scenario
|
||||
root_out.mkdir(parents=True, exist_ok=True)
|
||||
(ROOT / "Saved/Linux/l129").mkdir(parents=True, exist_ok=True)
|
||||
runs = []
|
||||
for repetition in range(1, 6):
|
||||
runs.append(run(args.scenario, "candidate", repetition))
|
||||
(root_out / "runs-partial.json").write_text(
|
||||
json.dumps(runs, indent=2) + "\n", encoding="utf-8")
|
||||
baseline_path = ROOT / "Saved/Linux/l127/ue/movement-pairs-summary.json"
|
||||
baseline = json.loads(baseline_path.read_text(encoding="utf-8"))["summary"]["merge"]["metrics"]
|
||||
metric_names = ("near_ready_moving_mean_pct", "far_holes_moving_mean_pct",
|
||||
"game_thread_tick_p99_ms", "game_thread_tick_max_ms")
|
||||
candidate = {name: statistics.median(row[name] for row in runs) for name in metric_names}
|
||||
reference = {name: baseline[name]["median"] for name in metric_names}
|
||||
deltas = {name: candidate[name] - reference[name] for name in metric_names}
|
||||
bar_pass = (candidate["near_ready_moving_mean_pct"] > reference["near_ready_moving_mean_pct"]
|
||||
and candidate["far_holes_moving_mean_pct"] <= reference["far_holes_moving_mean_pct"]
|
||||
and candidate["game_thread_tick_p99_ms"] <= reference["game_thread_tick_p99_ms"]
|
||||
and candidate["game_thread_tick_max_ms"] <= reference["game_thread_tick_max_ms"])
|
||||
summary = {
|
||||
"design": "L129 R=2.0 m passage influence; five runs at 30 m/s.",
|
||||
"scenario": args.scenario, "runs": runs,
|
||||
"baseline": {"commit": "b96dd73", "source_summary": str(baseline_path),
|
||||
"metrics": reference},
|
||||
"candidate_medians": candidate, "deltas": deltas,
|
||||
"bar_pass": bar_pass,
|
||||
}
|
||||
(root_out / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
|
||||
encoding="utf-8")
|
||||
print("[L129MovementSummary] " + json.dumps(summary, sort_keys=True), flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,188 +1,188 @@
|
||||
<!doctype html><meta charset='utf-8'>
|
||||
<title>L125 / L128 tunnel capture comparison</title>
|
||||
<title>L125 / L129 tunnel capture comparison</title>
|
||||
<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}h2{font-size:18px}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style>
|
||||
<h1>L125 / L128 slab ownership: identical views</h1>
|
||||
<h1>L125 / L129 v226: identical views</h1>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — rock-floor/401.7m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-rock-floor-station-1.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — rock-floor/792.8m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-rock-floor-station-2.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — rock-floor/1634.5m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-rock-floor-station-3.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — rock-floor/27.0m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-rock-floor-station-1.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — rock-floor/52.9m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-rock-floor-station-2.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — rock-floor/78.9m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-rock-floor-station-3.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — rock-floor/323.4m</h2>
|
||||
<p>rock-floor-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
||||
<p>rock-floor-close · L125 low_contrast_geometry_visible · L129 low_contrast_geometry_visible</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-1.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-rock-floor-station-1.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — rock-floor/333.4m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-2.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-rock-floor-station-2.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — rock-floor/343.4m</h2>
|
||||
<p>rock-floor-close · L125 pass · L128 pass</p>
|
||||
<p>rock-floor-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-rock-floor-station-3.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-rock-floor-station-3.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-1/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-1-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-1/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L129 low_contrast_geometry_visible</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-2/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-2-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-2/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-3/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-3-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-3-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — section-3/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — section-1/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-openair-1-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — section-1/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — section-2/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-openair-2-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — section-2/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — section-1/4m-outside</h2>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L129 low_contrast_geometry_visible</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-1-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-openair-1-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — section-1/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L128 low_contrast_geometry_visible</p>
|
||||
<p>open-air-close · L125 low_contrast_geometry_visible · L129 low_contrast_geometry_visible</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — section-2/4m-outside</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-2-4m-outside.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-openair-2-4m-outside.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — section-2/4m-interior-wall</h2>
|
||||
<p>open-air-close · L125 pass · L128 pass</p>
|
||||
<p>open-air-close · L125 pass · L129 pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125</figcaption><img src='../../Linux125/captures/L125/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L128 slab ownership</figcaption><img src='L128/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='L129/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,52 @@
|
||||
<!doctype html><meta charset='utf-8'>
|
||||
<title>L125 / L129 mouth close-ups</title>
|
||||
<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style>
|
||||
<h1>L125 v225 / L129 v226 tunnel mouths</h1>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — upper-mouth</h2>
|
||||
<p>pixel-identical; pass / pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-0-1-0-upper-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-0-1-0-upper-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/0-1/0 — lower-mouth</h2>
|
||||
<p>pixel-identical; pass / pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-0-1-0-lower-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-0-1-0-lower-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — upper-mouth</h2>
|
||||
<p>pixel-identical; pass / pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-1-2-0-upper-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-1-2-0-upper-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/1-2/0 — lower-mouth</h2>
|
||||
<p>pixel-identical; pass / pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-1-2-0-lower-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-1-2-0-lower-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — upper-mouth</h2>
|
||||
<p>pixel-identical; pass / pass</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-2-3-0-upper-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-2-3-0-upper-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2>passage/2-3/0 — lower-mouth</h2>
|
||||
<p>pixel-identical; low_contrast_geometry_visible / low_contrast_geometry_visible</p>
|
||||
<div>
|
||||
<figure><figcaption>L125 v225</figcaption><img src='before/passage-2-3-0-lower-mouth.png'></figure>
|
||||
<figure><figcaption>L129 v226</figcaption><img src='after/passage-2-3-0-lower-mouth.png'></figure>
|
||||
</div>
|
||||
</section>
|
||||
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,676 @@
|
||||
{
|
||||
"captures": [
|
||||
{
|
||||
"name": "passage-0-1-0-upper-mouth",
|
||||
"passage": "passage/0-1/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
8.324777182667596,
|
||||
20.450707805615995,
|
||||
-371.842578125
|
||||
],
|
||||
"target": [
|
||||
7.855654585481068,
|
||||
14.021907641948447,
|
||||
-371.942578125
|
||||
],
|
||||
"yaw": -175.82640818958697,
|
||||
"pitch": -0.8888012261216656,
|
||||
"focus": [
|
||||
8.0,
|
||||
16.0,
|
||||
-372.1224609375
|
||||
],
|
||||
"center_z": -372.1224609375,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-0-1-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 243380,
|
||||
"source_triangles": 287904,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
8.324777182667596,
|
||||
20.450707805615995,
|
||||
-371.842578125
|
||||
],
|
||||
"target_actual_m": [
|
||||
7.855654585481068,
|
||||
14.021907641948447,
|
||||
-371.942578125
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-0-1-0-upper-mouth",
|
||||
"image_sha256": "20a56bb0419cc9c0ccb6a3c3f6a79e7f1614d095a8b233ecc65dc836fee9eb3b"
|
||||
},
|
||||
{
|
||||
"name": "passage-0-1-0-upper-mouth",
|
||||
"passage": "passage/0-1/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
8.324777182667596,
|
||||
20.450707805615995,
|
||||
-371.842578125
|
||||
],
|
||||
"target": [
|
||||
7.855654585481068,
|
||||
14.021907641948447,
|
||||
-371.942578125
|
||||
],
|
||||
"yaw": -175.82640818958697,
|
||||
"pitch": -0.8888012261216656,
|
||||
"focus": [
|
||||
8.0,
|
||||
16.0,
|
||||
-372.1224609375
|
||||
],
|
||||
"center_z": -372.1224609375,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-0-1-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 243380,
|
||||
"source_triangles": 287904,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
8.324777182667596,
|
||||
20.450707805615995,
|
||||
-371.842578125
|
||||
],
|
||||
"target_actual_m": [
|
||||
7.855654585481068,
|
||||
14.021907641948447,
|
||||
-371.942578125
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-0-1-0-upper-mouth",
|
||||
"image_sha256": "20a56bb0419cc9c0ccb6a3c3f6a79e7f1614d095a8b233ecc65dc836fee9eb3b"
|
||||
},
|
||||
{
|
||||
"name": "passage-0-1-0-lower-mouth",
|
||||
"passage": "passage/0-1/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
32.68834531966199,
|
||||
9.553722879000034,
|
||||
-735.4805084803569
|
||||
],
|
||||
"target": [
|
||||
24.394507482044844,
|
||||
1.8614284070526241,
|
||||
-736.6798828125
|
||||
],
|
||||
"yaw": -132.84502956130385,
|
||||
"pitch": -6.05232406255234,
|
||||
"focus": [
|
||||
25.8369140625,
|
||||
3.19921875,
|
||||
-736.2672500132622
|
||||
],
|
||||
"center_z": -736.2672500132622,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-0-1-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 549170,
|
||||
"source_triangles": 582732,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
32.68834531966199,
|
||||
9.553722879000034,
|
||||
-735.4805084803569
|
||||
],
|
||||
"target_actual_m": [
|
||||
24.394507482044844,
|
||||
1.8614284070526241,
|
||||
-736.6798828125
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-0-1-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-0-1-0-lower-mouth",
|
||||
"image_sha256": "01e5f52b7c9080cb34ed9fb92b60360426ef21bc8934309542cd8736a116fc29"
|
||||
},
|
||||
{
|
||||
"name": "passage-0-1-0-lower-mouth",
|
||||
"passage": "passage/0-1/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
32.68834531966199,
|
||||
9.553722879000034,
|
||||
-735.4805084803569
|
||||
],
|
||||
"target": [
|
||||
24.394507482044844,
|
||||
1.8614284070526241,
|
||||
-736.6798828125
|
||||
],
|
||||
"yaw": -132.84502956130385,
|
||||
"pitch": -6.05232406255234,
|
||||
"focus": [
|
||||
25.8369140625,
|
||||
3.19921875,
|
||||
-736.2672500132622
|
||||
],
|
||||
"center_z": -736.2672500132622,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-0-1-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 549170,
|
||||
"source_triangles": 582732,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
32.68834531966199,
|
||||
9.553722879000034,
|
||||
-735.4805084803569
|
||||
],
|
||||
"target_actual_m": [
|
||||
24.394507482044844,
|
||||
1.8614284070526241,
|
||||
-736.6798828125
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-0-1-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-0-1-0-lower-mouth",
|
||||
"image_sha256": "01e5f52b7c9080cb34ed9fb92b60360426ef21bc8934309542cd8736a116fc29"
|
||||
},
|
||||
{
|
||||
"name": "passage-1-2-0-upper-mouth",
|
||||
"passage": "passage/1-2/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
23.39180762797774,
|
||||
-15.509524798921928,
|
||||
-731.7810546875
|
||||
],
|
||||
"target": [
|
||||
17.28788584589878,
|
||||
-13.618271096312476,
|
||||
-731.8810546875
|
||||
],
|
||||
"yaw": -72.7848029211395,
|
||||
"pitch": -0.8965458221544697,
|
||||
"focus": [
|
||||
19.166015625,
|
||||
-14.2001953125,
|
||||
-730.5610546875
|
||||
],
|
||||
"center_z": -730.5610546875,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-1-2-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 593026,
|
||||
"source_triangles": 638590,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
23.39180762797774,
|
||||
-15.509524798921928,
|
||||
-731.7810546875
|
||||
],
|
||||
"target_actual_m": [
|
||||
17.28788584589878,
|
||||
-13.618271096312476,
|
||||
-731.8810546875
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-1-2-0-upper-mouth",
|
||||
"image_sha256": "8314a919e0c4b16390622371be96c89459ddef922c20711db281c55227e29de2"
|
||||
},
|
||||
{
|
||||
"name": "passage-1-2-0-upper-mouth",
|
||||
"passage": "passage/1-2/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
23.39180762797774,
|
||||
-15.509524798921928,
|
||||
-731.7810546875
|
||||
],
|
||||
"target": [
|
||||
17.28788584589878,
|
||||
-13.618271096312476,
|
||||
-731.8810546875
|
||||
],
|
||||
"yaw": -72.7848029211395,
|
||||
"pitch": -0.8965458221544697,
|
||||
"focus": [
|
||||
19.166015625,
|
||||
-14.2001953125,
|
||||
-730.5610546875
|
||||
],
|
||||
"center_z": -730.5610546875,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-1-2-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 593026,
|
||||
"source_triangles": 638590,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
23.39180762797774,
|
||||
-15.509524798921928,
|
||||
-731.7810546875
|
||||
],
|
||||
"target_actual_m": [
|
||||
17.28788584589878,
|
||||
-13.618271096312476,
|
||||
-731.8810546875
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-1-2-0-upper-mouth",
|
||||
"image_sha256": "8314a919e0c4b16390622371be96c89459ddef922c20711db281c55227e29de2"
|
||||
},
|
||||
{
|
||||
"name": "passage-1-2-0-lower-mouth",
|
||||
"passage": "passage/1-2/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
27.129937681588373,
|
||||
-19.073450175278364,
|
||||
-751.8771866414096
|
||||
],
|
||||
"target": [
|
||||
17.48940045519192,
|
||||
-13.174246920336135,
|
||||
-753.05390625
|
||||
],
|
||||
"yaw": -58.53685078395012,
|
||||
"pitch": -5.943870452561027,
|
||||
"focus": [
|
||||
19.166015625,
|
||||
-14.2001953125,
|
||||
-751.73390625
|
||||
],
|
||||
"center_z": -751.73390625,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-1-2-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 544808,
|
||||
"source_triangles": 576830,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
27.129937681588373,
|
||||
-19.073450175278364,
|
||||
-751.8771866414096
|
||||
],
|
||||
"target_actual_m": [
|
||||
17.48940045519192,
|
||||
-13.174246920336135,
|
||||
-753.05390625
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-1-2-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-1-2-0-lower-mouth",
|
||||
"image_sha256": "dc1e5b79bb9afa6e1aa66edac7e0d84e1161ece0147b1ea58e4e60b93dca399b"
|
||||
},
|
||||
{
|
||||
"name": "passage-1-2-0-lower-mouth",
|
||||
"passage": "passage/1-2/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
27.129937681588373,
|
||||
-19.073450175278364,
|
||||
-751.8771866414096
|
||||
],
|
||||
"target": [
|
||||
17.48940045519192,
|
||||
-13.174246920336135,
|
||||
-753.05390625
|
||||
],
|
||||
"yaw": -58.53685078395012,
|
||||
"pitch": -5.943870452561027,
|
||||
"focus": [
|
||||
19.166015625,
|
||||
-14.2001953125,
|
||||
-751.73390625
|
||||
],
|
||||
"center_z": -751.73390625,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-1-2-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 544808,
|
||||
"source_triangles": 576830,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
27.129937681588373,
|
||||
-19.073450175278364,
|
||||
-751.8771866414096
|
||||
],
|
||||
"target_actual_m": [
|
||||
17.48940045519192,
|
||||
-13.174246920336135,
|
||||
-753.05390625
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-1-2-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-1-2-0-lower-mouth",
|
||||
"image_sha256": "dc1e5b79bb9afa6e1aa66edac7e0d84e1161ece0147b1ea58e4e60b93dca399b"
|
||||
},
|
||||
{
|
||||
"name": "passage-2-3-0-upper-mouth",
|
||||
"passage": "passage/2-3/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
-24.455025526892644,
|
||||
-5.631774473341657,
|
||||
-811.975390625
|
||||
],
|
||||
"target": [
|
||||
-18.110266432492157,
|
||||
-4.81795266462593,
|
||||
-812.075390625
|
||||
],
|
||||
"yaw": 82.6907653180847,
|
||||
"pitch": -0.8956299428824654,
|
||||
"focus": [
|
||||
-20.0625,
|
||||
-5.068359375,
|
||||
-810.755390625
|
||||
],
|
||||
"center_z": -810.755390625,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-2-3-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 59554,
|
||||
"source_triangles": 71494,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-24.455025526892644,
|
||||
-5.631774473341657,
|
||||
-811.975390625
|
||||
],
|
||||
"target_actual_m": [
|
||||
-18.110266432492157,
|
||||
-4.81795266462593,
|
||||
-812.075390625
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-2-3-0-upper-mouth",
|
||||
"image_sha256": "954c7be05d77c4ccf5d3a7a486cc7cd1e32f108120e02daac2bb2cf18ed2a325"
|
||||
},
|
||||
{
|
||||
"name": "passage-2-3-0-upper-mouth",
|
||||
"passage": "passage/2-3/0",
|
||||
"kind": "mouth",
|
||||
"station": "upper-mouth",
|
||||
"camera": [
|
||||
-24.455025526892644,
|
||||
-5.631774473341657,
|
||||
-811.975390625
|
||||
],
|
||||
"target": [
|
||||
-18.110266432492157,
|
||||
-4.81795266462593,
|
||||
-812.075390625
|
||||
],
|
||||
"yaw": 82.6907653180847,
|
||||
"pitch": -0.8956299428824654,
|
||||
"focus": [
|
||||
-20.0625,
|
||||
-5.068359375,
|
||||
-810.755390625
|
||||
],
|
||||
"center_z": -810.755390625,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-2-3-0-upper-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-upper-mouth.vfmesh",
|
||||
"drawn_triangles": 59554,
|
||||
"source_triangles": 71494,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-24.455025526892644,
|
||||
-5.631774473341657,
|
||||
-811.975390625
|
||||
],
|
||||
"target_actual_m": [
|
||||
-18.110266432492157,
|
||||
-4.81795266462593,
|
||||
-812.075390625
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-upper-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-upper-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-upper-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-2-3-0-upper-mouth",
|
||||
"image_sha256": "954c7be05d77c4ccf5d3a7a486cc7cd1e32f108120e02daac2bb2cf18ed2a325"
|
||||
},
|
||||
{
|
||||
"name": "passage-2-3-0-lower-mouth",
|
||||
"passage": "passage/2-3/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
-28.589162628136368,
|
||||
-1.22631300593053,
|
||||
-898.8116843726575
|
||||
],
|
||||
"target": [
|
||||
-18.26741313091866,
|
||||
-5.87721124217252,
|
||||
-900.0333984375
|
||||
],
|
||||
"yaw": 114.25594846721253,
|
||||
"pitch": -6.159177031829821,
|
||||
"focus": [
|
||||
-20.0625,
|
||||
-5.068359375,
|
||||
-898.7133984375
|
||||
],
|
||||
"center_z": -898.7133984375,
|
||||
"variant": "L125-v225",
|
||||
"capture": "captures/L129-mouth/before/passage-2-3-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 293832,
|
||||
"source_triangles": 314658,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-28.589162628136368,
|
||||
-1.22631300593053,
|
||||
-898.8116843726575
|
||||
],
|
||||
"target_actual_m": [
|
||||
-18.26741313091866,
|
||||
-5.87721124217252,
|
||||
-900.0333984375
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/before/passage-2-3-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-2-3-0-lower-mouth",
|
||||
"image_sha256": "295bc7662d9b699212110c61e60c7bd19e99d13ebe94d41201fa93e109bf707e"
|
||||
},
|
||||
{
|
||||
"name": "passage-2-3-0-lower-mouth",
|
||||
"passage": "passage/2-3/0",
|
||||
"kind": "mouth",
|
||||
"station": "lower-mouth",
|
||||
"camera": [
|
||||
-28.589162628136368,
|
||||
-1.22631300593053,
|
||||
-898.8116843726575
|
||||
],
|
||||
"target": [
|
||||
-18.26741313091866,
|
||||
-5.87721124217252,
|
||||
-900.0333984375
|
||||
],
|
||||
"yaw": 114.25594846721253,
|
||||
"pitch": -6.159177031829821,
|
||||
"focus": [
|
||||
-20.0625,
|
||||
-5.068359375,
|
||||
-898.7133984375
|
||||
],
|
||||
"center_z": -898.7133984375,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129-mouth/after/passage-2-3-0-lower-mouth.png",
|
||||
"scene": "Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-lower-mouth.vfmesh",
|
||||
"drawn_triangles": 293832,
|
||||
"source_triangles": 314658,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||
"route_distance_actual_m": null,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": null,
|
||||
"closeup_target_surface_distance_m": null,
|
||||
"closeup_predicted_target_offset_m": null,
|
||||
"closeup_wall_normal_alignment": null,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-28.589162628136368,
|
||||
-1.22631300593053,
|
||||
-898.8116843726575
|
||||
],
|
||||
"target_actual_m": [
|
||||
-18.26741313091866,
|
||||
-5.87721124217252,
|
||||
-900.0333984375
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-lower-mouth-mesh.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-lower-mouth-render.log",
|
||||
"Saved/Linux/l129/captures/mouth-closeups/after/passage-2-3-0-lower-mouth-quality.log"
|
||||
],
|
||||
"view": "passage-2-3-0-lower-mouth",
|
||||
"image_sha256": "295bc7662d9b699212110c61e60c7bd19e99d13ebe94d41201fa93e109bf707e"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -28,11 +28,11 @@
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"planned_floor_m": -445.66373993191075,
|
||||
"planned_grade_deg": 10.372328677972732,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 122264,
|
||||
"source_triangles": 146688,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 122294,
|
||||
"source_triangles": 146798,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 401.6612010038529,
|
||||
@@ -54,9 +54,9 @@
|
||||
-445.66373993191075
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-1-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-1-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
-7.026885053959959,
|
||||
@@ -100,11 +100,11 @@
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"planned_floor_m": -516.0616688299093,
|
||||
"planned_grade_deg": 10.367725129664787,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 586094,
|
||||
"source_triangles": 626214,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 586092,
|
||||
"source_triangles": 626196,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 792.8284020077059,
|
||||
@@ -126,9 +126,9 @@
|
||||
-516.0616688299093
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-2-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-2-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
-2.471476828908,
|
||||
@@ -172,11 +172,11 @@
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"planned_floor_m": -667.5348848643227,
|
||||
"planned_grade_deg": 10.360515186362372,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 137258,
|
||||
"source_triangles": 166706,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 137288,
|
||||
"source_triangles": 166736,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 1634.4566030115589,
|
||||
@@ -198,9 +198,9 @@
|
||||
-667.5348848643227
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-rock-floor-station-3-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-rock-floor-station-3-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
17.33622182815858,
|
||||
@@ -244,11 +244,11 @@
|
||||
"route_length_m": 114.99063175809309,
|
||||
"planned_floor_m": -738.1970266319915,
|
||||
"planned_grade_deg": 10.657740387934142,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 652040,
|
||||
"source_triangles": 719644,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 652056,
|
||||
"source_triangles": 719660,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 26.963657939523273,
|
||||
@@ -270,9 +270,9 @@
|
||||
-738.1970266319915
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-1-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-1-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
15.354124807038394,
|
||||
@@ -316,11 +316,11 @@
|
||||
"route_length_m": 114.99063175809309,
|
||||
"planned_floor_m": -742.995373541633,
|
||||
"planned_grade_deg": 10.645569354114926,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 636134,
|
||||
"source_triangles": 700530,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 636162,
|
||||
"source_triangles": 700558,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 52.927315879046546,
|
||||
@@ -342,9 +342,9 @@
|
||||
-742.995373541633
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-2-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-2-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
-4.766428465537912,
|
||||
@@ -388,11 +388,11 @@
|
||||
"route_length_m": 114.99063175809309,
|
||||
"planned_floor_m": -747.7963166548619,
|
||||
"planned_grade_deg": 10.659092990906162,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 580464,
|
||||
"source_triangles": 639368,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 580472,
|
||||
"source_triangles": 639376,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 78.89097381856982,
|
||||
@@ -414,9 +414,9 @@
|
||||
-747.7963166548619
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-rock-floor-station-3-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-rock-floor-station-3-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
-12.283352972838873,
|
||||
@@ -460,11 +460,11 @@
|
||||
"route_length_m": 494.0722798830563,
|
||||
"planned_floor_m": -871.0755965556104,
|
||||
"planned_grade_deg": 10.274530613220444,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 474960,
|
||||
"source_triangles": 502358,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-rock-floor-station-1.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-1.vfmesh",
|
||||
"drawn_triangles": 474964,
|
||||
"source_triangles": 502362,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||
"route_distance_actual_m": 323.4481319239866,
|
||||
@@ -486,9 +486,9 @@
|
||||
-871.0755965556104
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-1-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-1-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-1-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-1-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
9.103799793973732,
|
||||
@@ -532,11 +532,11 @@
|
||||
"route_length_m": 494.0722798830563,
|
||||
"planned_floor_m": -872.8561420785873,
|
||||
"planned_grade_deg": 10.266334408339132,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 494500,
|
||||
"source_triangles": 524338,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-rock-floor-station-2.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-2.vfmesh",
|
||||
"drawn_triangles": 494504,
|
||||
"source_triangles": 524342,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 333.4481319239866,
|
||||
@@ -558,9 +558,9 @@
|
||||
-872.8561420785873
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-2-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-2-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-2-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-2-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
15.204108325185125,
|
||||
@@ -604,11 +604,11 @@
|
||||
"route_length_m": 494.0722798830563,
|
||||
"planned_floor_m": -874.6379150751349,
|
||||
"planned_grade_deg": 10.259484647608062,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 485352,
|
||||
"source_triangles": 512660,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-rock-floor-station-3.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-3.vfmesh",
|
||||
"drawn_triangles": 485356,
|
||||
"source_triangles": 512664,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 343.4481319239866,
|
||||
@@ -630,9 +630,9 @@
|
||||
-874.6379150751349
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-rock-floor-station-3-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-3-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-3-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-rock-floor-station-3-quality.log"
|
||||
],
|
||||
"floor_anchor_position_m": [
|
||||
15.464091528009144,
|
||||
@@ -682,11 +682,11 @@
|
||||
"route_distance_m": 8.3545,
|
||||
"requested_route_distance_m": 8.3545,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-outside.vfmesh",
|
||||
"drawn_triangles": 275333,
|
||||
"source_triangles": 327761,
|
||||
"source_triangles": 327745,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 8.3545,
|
||||
@@ -708,9 +708,9 @@
|
||||
-373.75
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -747,11 +747,11 @@
|
||||
"route_distance_m": 8.3545,
|
||||
"requested_route_distance_m": 8.3545,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 308012,
|
||||
"source_triangles": 368140,
|
||||
"source_triangles": 368124,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "low_contrast_geometry_visible",
|
||||
"route_distance_actual_m": 8.3545,
|
||||
@@ -773,9 +773,9 @@
|
||||
-373.75
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-1-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-1-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -812,11 +812,11 @@
|
||||
"route_distance_m": 14.4925,
|
||||
"requested_route_distance_m": 14.4925,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-outside.vfmesh",
|
||||
"drawn_triangles": 275333,
|
||||
"source_triangles": 327761,
|
||||
"source_triangles": 327745,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 14.4925,
|
||||
@@ -838,9 +838,9 @@
|
||||
-376.0
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -877,11 +877,11 @@
|
||||
"route_distance_m": 14.4925,
|
||||
"requested_route_distance_m": 14.4925,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 345044,
|
||||
"source_triangles": 414692,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 345026,
|
||||
"source_triangles": 414658,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 14.4925,
|
||||
@@ -903,9 +903,9 @@
|
||||
-376.0
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-2-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-2-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -942,35 +942,35 @@
|
||||
"route_distance_m": 1265.3425000000002,
|
||||
"requested_route_distance_m": 1265.3425000000002,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-3-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside.vfmesh",
|
||||
"drawn_triangles": 151372,
|
||||
"source_triangles": 183724,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-3-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-outside.vfmesh",
|
||||
"drawn_triangles": 149234,
|
||||
"source_triangles": 181128,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 1265.3425000000002,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": 3.9999999999999947,
|
||||
"closeup_target_surface_distance_m": 0.06828066292003203,
|
||||
"closeup_predicted_target_offset_m": 0.06828066292003203,
|
||||
"closeup_wall_normal_alignment": 0.9604791479186932,
|
||||
"closeup_camera_target_distance_m": 3.9999999999999907,
|
||||
"closeup_target_surface_distance_m": 0.06836631107301705,
|
||||
"closeup_predicted_target_offset_m": 0.06836631107301705,
|
||||
"closeup_wall_normal_alignment": 0.9604329420550252,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-28.639699107248397,
|
||||
-15.583356294879769,
|
||||
-601.2437793015765
|
||||
-28.63982379180018,
|
||||
-15.582695163623317,
|
||||
-601.2438490311043
|
||||
],
|
||||
"target_actual_m": [
|
||||
-24.95574413685722,
|
||||
-14.176529326299274,
|
||||
-600.5734706737007
|
||||
-24.955621627611308,
|
||||
-14.176566764792845,
|
||||
-600.5734332352072
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1007,35 +1007,35 @@
|
||||
"route_distance_m": 1265.3425000000002,
|
||||
"requested_route_distance_m": 1265.3425000000002,
|
||||
"route_length_m": 2026.6238040154117,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-0-1-0-openair-3-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 150614,
|
||||
"source_triangles": 183232,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-0-1-0-openair-3-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 148100,
|
||||
"source_triangles": 180244,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 1265.3425000000002,
|
||||
"route_station_adjustment_m": 0.0,
|
||||
"closeup_camera_target_distance_m": 4.000000000000011,
|
||||
"closeup_target_surface_distance_m": 0.15815699667954516,
|
||||
"closeup_predicted_target_offset_m": 0.15815699667954516,
|
||||
"closeup_wall_normal_alignment": 0.9379407978793181,
|
||||
"closeup_camera_target_distance_m": 4.000000000000004,
|
||||
"closeup_target_surface_distance_m": 0.15667051955483755,
|
||||
"closeup_predicted_target_offset_m": 0.15667051955483755,
|
||||
"closeup_wall_normal_alignment": 0.936006465878356,
|
||||
"fallback_kind": null,
|
||||
"fallback_surface_distance_m": null,
|
||||
"camera_actual_m": [
|
||||
-21.87278031692096,
|
||||
-11.881551644506661,
|
||||
-599.3233300443438
|
||||
-21.875641690065105,
|
||||
-11.887416826703374,
|
||||
-599.3020917133557
|
||||
],
|
||||
"target_actual_m": [
|
||||
-24.868945473985846,
|
||||
-14.149254069257264,
|
||||
-600.6946505992728
|
||||
-24.866552934428398,
|
||||
-14.149067333208382,
|
||||
-600.6947104389109
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-0-1-0-openair-3-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-0-1-0-openair-3-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1072,11 +1072,11 @@
|
||||
"route_distance_m": 83.504,
|
||||
"requested_route_distance_m": 83.504,
|
||||
"route_length_m": 114.99063175809309,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside.vfmesh",
|
||||
"drawn_triangles": 620798,
|
||||
"source_triangles": 684760,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-outside.vfmesh",
|
||||
"drawn_triangles": 620814,
|
||||
"source_triangles": 684776,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 83.504,
|
||||
@@ -1098,9 +1098,9 @@
|
||||
-747.5006103515625
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1137,11 +1137,11 @@
|
||||
"route_distance_m": 83.504,
|
||||
"requested_route_distance_m": 83.504,
|
||||
"route_length_m": 114.99063175809309,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 609749,
|
||||
"source_triangles": 668123,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 609757,
|
||||
"source_triangles": 668131,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 83.504,
|
||||
@@ -1163,9 +1163,9 @@
|
||||
-748.1744141343152
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-1-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-1-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1202,11 +1202,11 @@
|
||||
"route_distance_m": 104.362,
|
||||
"requested_route_distance_m": 104.362,
|
||||
"route_length_m": 114.99063175809309,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside.vfmesh",
|
||||
"drawn_triangles": 584534,
|
||||
"source_triangles": 636994,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-outside.vfmesh",
|
||||
"drawn_triangles": 584542,
|
||||
"source_triangles": 637002,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 104.362,
|
||||
@@ -1228,9 +1228,9 @@
|
||||
-752.0293187551489
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1267,11 +1267,11 @@
|
||||
"route_distance_m": 104.362,
|
||||
"requested_route_distance_m": 104.362,
|
||||
"route_length_m": 114.99063175809309,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-1-2-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 572250,
|
||||
"source_triangles": 618638,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-1-2-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 572258,
|
||||
"source_triangles": 618646,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 104.362,
|
||||
@@ -1293,9 +1293,9 @@
|
||||
-752.0074179101423
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-1-2-0-openair-2-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-1-2-0-openair-2-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1332,9 +1332,9 @@
|
||||
"route_distance_m": 16.616500000000002,
|
||||
"requested_route_distance_m": 16.616500000000002,
|
||||
"route_length_m": 494.0722798830563,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-openair-1-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-outside.vfmesh",
|
||||
"drawn_triangles": 104612,
|
||||
"source_triangles": 129326,
|
||||
"verified": true,
|
||||
@@ -1358,9 +1358,9 @@
|
||||
-816.1078690565205
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1397,9 +1397,9 @@
|
||||
"route_distance_m": 16.616500000000002,
|
||||
"requested_route_distance_m": 16.616500000000002,
|
||||
"route_length_m": 494.0722798830563,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-openair-1-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 94962,
|
||||
"source_triangles": 118028,
|
||||
"verified": true,
|
||||
@@ -1423,9 +1423,9 @@
|
||||
-815.6327986602337
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-1-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-1-4m-interior-wall-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1462,11 +1462,11 @@
|
||||
"route_distance_m": 374.929,
|
||||
"requested_route_distance_m": 374.929,
|
||||
"route_length_m": 494.0722798830563,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside.vfmesh",
|
||||
"drawn_triangles": 475856,
|
||||
"source_triangles": 504240,
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-openair-2-4m-outside.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-outside.vfmesh",
|
||||
"drawn_triangles": 475860,
|
||||
"source_triangles": 504244,
|
||||
"verified": true,
|
||||
"pixel_quality_status": "pass",
|
||||
"route_distance_actual_m": 374.929,
|
||||
@@ -1488,9 +1488,9 @@
|
||||
-879.7662205769708
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-outside-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-outside-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-outside-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-outside-quality.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1527,9 +1527,9 @@
|
||||
"route_distance_m": 374.929,
|
||||
"requested_route_distance_m": 374.929,
|
||||
"route_length_m": 494.0722798830563,
|
||||
"variant": "L128-slab-ownership-v226",
|
||||
"capture": "captures/L128/passage-2-3-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"variant": "L129-v226",
|
||||
"capture": "captures/L129/passage-2-3-0-openair-2-4m-interior-wall.png",
|
||||
"scene": "Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-interior-wall.vfmesh",
|
||||
"drawn_triangles": 486480,
|
||||
"source_triangles": 513552,
|
||||
"verified": true,
|
||||
@@ -1553,9 +1553,9 @@
|
||||
-879.75
|
||||
],
|
||||
"logs": [
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l128/captures/L128/passage-2-3-0-openair-2-4m-interior-wall-quality.log"
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-interior-wall-mesh.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-interior-wall-render.log",
|
||||
"Saved/Linux/l129/captures/L129/passage-2-3-0-openair-2-4m-interior-wall-quality.log"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 163 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 106 KiB |
@@ -0,0 +1,174 @@
|
||||
diff --git a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||||
index dc4ca32..aac34ff 100644
|
||||
--- a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||||
+++ b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||||
@@ -494,7 +494,8 @@ namespace VoxelForgeCore
|
||||
// Version 223 projects the floor onto one continuous arc-length profile and groups
|
||||
// dense passage samples into coarse tile candidates. Version 224 keeps the same
|
||||
// continuous floor while relaxing the spline chord tolerance and bounding shell work.
|
||||
- inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 225;
|
||||
+ // Version 226 bounds smooth-passage influence in physical metres and narrows its reach.
|
||||
+ inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 226;
|
||||
|
||||
enum class FieldChannel : std::uint32_t
|
||||
{
|
||||
diff --git a/Standalone/Core/src/ShapeWorldInternal.h b/Standalone/Core/src/ShapeWorldInternal.h
|
||||
index 517f375..dc258a1 100644
|
||||
--- a/Standalone/Core/src/ShapeWorldInternal.h
|
||||
+++ b/Standalone/Core/src/ShapeWorldInternal.h
|
||||
@@ -72,11 +72,11 @@ static bool VF_IsL98PassagePrepareTraceEnabled()
|
||||
return bEnabled;
|
||||
}
|
||||
|
||||
-static double VF_L93PassageCarveReachMetres()
|
||||
+static double VF_L129PassageCarveReachMetres()
|
||||
{
|
||||
- // The generated world uses a fixed bounded tube influence. An explicit diagnostic
|
||||
- // option can still select the legacy point-evaluation path for comparisons.
|
||||
- return 4.0;
|
||||
+ // Keep the sweep cutoff and its spatial bounds on one physical reach. Diagnostic
|
||||
+ // comparisons can still select another bounded reach or the point-evaluation path.
|
||||
+ return 2.0;
|
||||
}
|
||||
|
||||
enum class EPassageDensityQueryCaller : std::size_t
|
||||
@@ -306,7 +306,7 @@ public:
|
||||
profileStats_(profileStats),profileLod_(profileLod),
|
||||
passageCarveReachMetres_(std::isfinite(passageCarveReachMetres)
|
||||
&&passageCarveReachMetres>=0.0?passageCarveReachMetres
|
||||
- :VF_L93PassageCarveReachMetres())
|
||||
+ :VF_L129PassageCarveReachMetres())
|
||||
{
|
||||
mayContainResolvedBoundaryBand_=shape.ResolvedBoundaryBandsIntersectSubvoxelRange(
|
||||
minimumSubvoxels_[2],maximumSubvoxels_[2]);
|
||||
@@ -4813,11 +4813,14 @@ private:
|
||||
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||
constexpr double PassageShellMetres=0.75;
|
||||
constexpr double ReliefMetres=0.21;
|
||||
- constexpr double SweepReachMetres=4.0;
|
||||
+ const double SweepReachMetres=VF_L129PassageCarveReachMetres();
|
||||
constexpr double CornerBlendMetres=0.50;
|
||||
constexpr std::size_t CandidateFineSamplesPerSpan=5;
|
||||
+ const double qPerMetre=Q*1000000.0/
|
||||
+ std::max<std::uint32_t>(1,ResolvedLayout->coreVoxelSizeMicrometres);
|
||||
const double requiredReach=std::max(SweepReachMetres+ReliefMetres
|
||||
+CornerBlendMetres*0.25,PassageShellMetres+ReliefMetres);
|
||||
+ const double requiredReachCoreVoxels=requiredReach*qPerMetre/Q;
|
||||
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
|
||||
++passageIndex)
|
||||
{
|
||||
@@ -4854,7 +4857,7 @@ private:
|
||||
routeMinimum[axis]=std::min(routeMinimum[axis],localMinimum[axis]);
|
||||
routeMaximum[axis]=std::max(routeMaximum[axis],localMaximum[axis]);
|
||||
}
|
||||
- const double localExtent=requiredReach
|
||||
+ const double localExtent=requiredReachCoreVoxels
|
||||
+std::max(prepared.radiusA,prepared.radiusB)/Q+0.01;
|
||||
FPassageProofBound proof;
|
||||
for(std::size_t axis=0;axis<3;++axis)
|
||||
@@ -4872,7 +4875,8 @@ private:
|
||||
std::ceil((localMaximum[axis]+localExtent)*Q));
|
||||
}
|
||||
}
|
||||
- const double routeExtent=maximumRadiusSubvoxels/Q+requiredReach+0.01;
|
||||
+ const double routeExtent=maximumRadiusSubvoxels/Q
|
||||
+ +requiredReachCoreVoxels+0.01;
|
||||
const double tileExtent=routeExtent;
|
||||
std::array<std::int64_t,3> featureMinimum{},featureMaximum{};
|
||||
for(std::size_t axis=0;axis<3;++axis)
|
||||
@@ -11442,7 +11446,7 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
||||
const FIntVector& origin,std::int32_t step,std::int32_t cells,std::uint32_t seed)
|
||||
{
|
||||
constexpr std::int64_t Q=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||
- constexpr double InfluenceMetres=4.0;
|
||||
+ const double InfluenceMetres=VF_L129PassageCarveReachMetres();
|
||||
constexpr double OpenAirSideWallHeightMetres=1.0;
|
||||
if(!shape_||step<=0||cells<=0||!std::isfinite(passageCarveReachMetres_)
|
||||
||std::abs(passageCarveReachMetres_-InfluenceMetres)>1.0e-9)return;
|
||||
diff --git a/Standalone/Tools/verify/baselines/README.md b/Standalone/Tools/verify/baselines/README.md
|
||||
index 45fbb9f..fc7a59a 100644
|
||||
--- a/Standalone/Tools/verify/baselines/README.md
|
||||
+++ b/Standalone/Tools/verify/baselines/README.md
|
||||
@@ -4,7 +4,7 @@ These inputs are byte-for-byte copies of the historical files consumed by the
|
||||
verification gates. The gates now read this tracked directory instead of
|
||||
`Saved/Linux`, which is generated and is not present in a fresh checkout.
|
||||
|
||||
-- `owner-hash/`: L46, L52 and L53 diagnostics plus the pinned v212/v214 owner hash baselines.
|
||||
+- `owner-hash/`: L46, L52 and L53 diagnostics plus the pinned v212/v214 and L129 v226 owner hash baselines.
|
||||
- `historical-controls/`: L35, L36 and L38 regression-control logs.
|
||||
- `fixtures/`: Linux25 owner JSON inputs and L33 style-override fixtures.
|
||||
- `landmarks/`: L45–L48 landmark mesh and layout controls.
|
||||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline
|
||||
new file mode 100644
|
||||
index 0000000..9d3b87b
|
||||
--- /dev/null
|
||||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline
|
||||
@@ -0,0 +1,12 @@
|
||||
+[PipelineFullDetailHash] tiles=960 density=0x91931a57a067fd92 mesh=0xa818654be89790ac payload=0x370ff80451105a39 topology=0x06e507557aa70173
|
||||
+[PipelineWholeViewHash] tiles=2370 density=0x1573b570e1cbbf7e mesh=0xd88bf8bcf69ce1ce payload=0x347541780c9d8d71 topology=0x6b8ff8640be6e9d4
|
||||
+[PipelineLODHash] lod=0 tiles=512 density=0x2fd4c78685a43cfe mesh=0x50478cff1c1f8ca0 payload=0x54e48e57e0af26de topology=0x860c011cfdb9833a
|
||||
+[PipelineLODHash] lod=1 tiles=448 density=0x4b8d9a6dcd2942ad mesh=0x17e89b7087bfe711 payload=0x2389c109eb780db6 topology=0x7eccd4cf560d0630
|
||||
+[PipelineLODHash] lod=2 tiles=320 density=0x600ce5633a8f9e83 mesh=0xcd40f163b4cf3e0e payload=0xbe81dc276737a33a topology=0x942806963fedb92d
|
||||
+[PipelineLODHash] lod=3 tiles=208 density=0xf778be0581c49ed8 mesh=0x9aacf9e2a23034f8 payload=0xc1d4a985f2db3df5 topology=0xcdfdb412d3784023
|
||||
+[PipelineLODHash] lod=4 tiles=240 density=0xfb11591772a3d18e mesh=0xebf2baee8764591b payload=0xe491d7ac9c0061ad topology=0xd618ac33b95ce494
|
||||
+[PipelineLODHash] lod=5 tiles=144 density=0x2f8b7b7fb1e67258 mesh=0x4cd508cbe97344fd payload=0x2b6e96a6050458c9 topology=0x4ff6d0eda8988573
|
||||
+[PipelineLODHash] lod=6 tiles=96 density=0x0114a34c8b8d6113 mesh=0xb1fec4d01ae1fa44 payload=0x3e50cfd429b8e950 topology=0x08090c96d15c1618
|
||||
+[PipelineLODHash] lod=7 tiles=96 density=0x3836ed8cfce73418 mesh=0x40bc6589c5fc1aac payload=0x677349bcae16790f topology=0x36e3aa53192e6a6b
|
||||
+[PipelineLODHash] lod=8 tiles=306 density=0x144f3c1fd722708b mesh=0xef77b28bf7fd9453 payload=0xe3f47b37fcd61489 topology=0x5a3c73e295494e04
|
||||
+[PipelineExactQueryHash] probes=9 density=0x7b7c50ac24ccadcc unclamped=0x7b7c50ac24ccadcc detail=0xefcba20c0c70c415 collision=0xe604823a249029bf path=direct-Core-queries
|
||||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline
|
||||
new file mode 100644
|
||||
index 0000000..128c807
|
||||
--- /dev/null
|
||||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline
|
||||
@@ -0,0 +1,12 @@
|
||||
+[PipelineFullDetailHash] tiles=960 density=0xe1aa01ac806a84fb mesh=0x453624e695910639 payload=0x2f5793602ea13144 topology=0x31a43376cb129e55
|
||||
+[PipelineWholeViewHash] tiles=2578 density=0xb82dc1dcdadda8ff mesh=0xe74e85bf3cb0909b payload=0x40bc3871dd9dccbe topology=0x855e712b549606c3
|
||||
+[PipelineLODHash] lod=0 tiles=512 density=0x8119a4f12c4661f4 mesh=0xc074e3705293bef2 payload=0x36c965f6b43875ea topology=0x38bed0df168486d0
|
||||
+[PipelineLODHash] lod=1 tiles=448 density=0x6270dd0856c53432 mesh=0xa803bb427deeba9a payload=0xf4718f1ce85d4f4f topology=0x7b770585aafd8174
|
||||
+[PipelineLODHash] lod=2 tiles=320 density=0xf774df80811a61c1 mesh=0xb223f0f68d0310f8 payload=0x6c3fd8c4aa100ee9 topology=0x923485084c866600
|
||||
+[PipelineLODHash] lod=3 tiles=272 density=0x62088ea9f38d2ed0 mesh=0x19bb327ba4ba3287 payload=0xd04c1223d50da0ea topology=0xf3817d1351cc89c5
|
||||
+[PipelineLODHash] lod=4 tiles=272 density=0xb743eb64967bddcd mesh=0xf6b5bd36b0ebfead payload=0xd1284c1540f50636 topology=0x4a6e197e2a1a9500
|
||||
+[PipelineLODHash] lod=5 tiles=208 density=0x38706b628a74dd17 mesh=0x445b1c7b51489cbb payload=0x713efc66290768f7 topology=0x56486b919146bb1e
|
||||
+[PipelineLODHash] lod=6 tiles=144 density=0xd53849b2002a1faa mesh=0xaa210abc8498c415 payload=0xd109aef8639706d1 topology=0x61a4d75fbbc35268
|
||||
+[PipelineLODHash] lod=7 tiles=96 density=0xb0ea9a140275c9cc mesh=0x3ffd8365c8b0ec29 payload=0x3577afb0a2e4a420 topology=0x97530aafde15b7e0
|
||||
+[PipelineLODHash] lod=8 tiles=306 density=0x8b3d1816799d67a0 mesh=0x80bf554f17700e1e payload=0xccbe22c3333a9c34 topology=0xcb11b28f6b6bcc50
|
||||
+[PipelineExactQueryHash] probes=9 density=0xf2df67b38b7802df unclamped=0x48b347986345b557 detail=0xefcba20c0c70c415 collision=0x137e8f6c0b03a624 path=direct-Core-queries
|
||||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline
|
||||
new file mode 100644
|
||||
index 0000000..49f85bb
|
||||
--- /dev/null
|
||||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline
|
||||
@@ -0,0 +1,12 @@
|
||||
+[PipelineFullDetailHash] tiles=960 density=0xace56c8f205238ad mesh=0xa9c603a1248de6b8 payload=0xea55f1f4fcc6a894 topology=0x5ea7bc78a1b678ae
|
||||
+[PipelineWholeViewHash] tiles=2370 density=0x637fdf29ccba949b mesh=0xb02cf034b0c9e375 payload=0x74240706eac0c770 topology=0xe607e19fd4684210
|
||||
+[PipelineLODHash] lod=0 tiles=512 density=0xcd6ab28cfa504aca mesh=0xf03dc80a669fca31 payload=0x397aded1c3d2d297 topology=0xb4a1dc84fabc1fe3
|
||||
+[PipelineLODHash] lod=1 tiles=448 density=0xce6e713828b2a20a mesh=0x1cf408c25d67d18c payload=0x8a2b5d20571c997e topology=0x51cd985fe8e7d100
|
||||
+[PipelineLODHash] lod=2 tiles=320 density=0x353ee7ab408a9da1 mesh=0x8d355a8d598d56d5 payload=0x458f26e32d815635 topology=0x2e89b3cba09efcfe
|
||||
+[PipelineLODHash] lod=3 tiles=208 density=0xfe4f53b3ec010392 mesh=0xbd04d2da98d5b2e0 payload=0x10627f36d82200e8 topology=0xd625f3434ac0a893
|
||||
+[PipelineLODHash] lod=4 tiles=240 density=0x0be8798407724eaf mesh=0x131c303cbbe51434 payload=0x2a90ecf0a2411ca0 topology=0xe3e054a371152e08
|
||||
+[PipelineLODHash] lod=5 tiles=144 density=0xf20897ad272103a9 mesh=0x13d00b6253ae1f72 payload=0x0db3880693a962fa topology=0x462bd87a80f15e89
|
||||
+[PipelineLODHash] lod=6 tiles=96 density=0xc040fcac457d6313 mesh=0x1ed132eeb718fb62 payload=0xcd0214e35577c6e3 topology=0x2c56c69e6fdcfd64
|
||||
+[PipelineLODHash] lod=7 tiles=96 density=0xc2d419446355fdb8 mesh=0x4ea44452574fc84b payload=0xfd9779bedfc9ae0f topology=0x8948546e770c9b72
|
||||
+[PipelineLODHash] lod=8 tiles=306 density=0x62db31696f2da831 mesh=0xd373f9e9481532fe payload=0x540a60526e0e3e46 topology=0xc725cb901e6dc335
|
||||
+[PipelineExactQueryHash] probes=9 density=0xc949c4df2ce6f9d9 unclamped=0xc949c4df2ce6f9d9 detail=0x114c501e2d830d94 collision=0xe6011d3a248d4849 path=direct-Core-queries
|
||||
diff --git a/Standalone/Tools/verify/verify.py b/Standalone/Tools/verify/verify.py
|
||||
index 5fc1584..70f6a69 100644
|
||||
--- a/Standalone/Tools/verify/verify.py
|
||||
+++ b/Standalone/Tools/verify/verify.py
|
||||
@@ -122,11 +122,11 @@ RECIPE_RE = re.compile(
|
||||
|
||||
def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]:
|
||||
if recipe == "surface-world" and style == 1:
|
||||
- return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v225.baseline",
|
||||
- "L125-v225-stamped-passage-sweep")
|
||||
+ return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline",
|
||||
+ "L129-v226-physical-passage-reach")
|
||||
if recipe == "floating-islands" and style == 2:
|
||||
- return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v225.baseline",
|
||||
- "L125-v225-stamped-passage-sweep")
|
||||
+ return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline",
|
||||
+ "L129-v226-physical-passage-reach")
|
||||
raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}")
|
||||
|
||||
|
||||