Merge pull request 'test(M00): record Goldshire pose evidence' (#9) from work/sindo-main-codex/m00-camera-pose-evidence into master
Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
# M00-QAR-CAMERA-POSE-EVIDENCE-001 — Goldshire camera pose evidence
|
||||||
|
|
||||||
|
<!-- OPENWC_CLAIM:M00-QAR-CAMERA-POSE-EVIDENCE-001:sindo-main-codex:2026-07-14 -->
|
||||||
|
|
||||||
|
## Ownership
|
||||||
|
|
||||||
|
- Target: M00
|
||||||
|
- Program: QAR
|
||||||
|
- Owner/Agent ID: sindo-main-codex
|
||||||
|
- Branch: `work/sindo-main-codex/m00-camera-pose-evidence`
|
||||||
|
- Lease expires UTC: 2026-07-14
|
||||||
|
- Integrator: milestone integrator
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Produce coarse-to-fine yaw/pitch evidence for the build 12340 Goldshire Inn reference and classify whether framing dominates the paired-image gap.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Changing manifest camera defaults before human approval.
|
||||||
|
- Treating minimum perceptual error as proof of exact camera parity.
|
||||||
|
- Committing proprietary reference images or generated candidates.
|
||||||
|
|
||||||
|
## Paths
|
||||||
|
|
||||||
|
- Exclusive: camera-pose evidence record
|
||||||
|
- Shared/hotspots: renderer baseline and module fidelity findings
|
||||||
|
- Generated/ignored: all sweep PNGs and JSON under `user://`
|
||||||
|
|
||||||
|
## Contracts and data
|
||||||
|
|
||||||
|
- Public API/events: none
|
||||||
|
- Schema/format version: unchanged
|
||||||
|
- Migration/compatibility: none
|
||||||
|
- Consumers: M00 fidelity review
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Requires: merged camera-pose sweep and local build 12340 reference
|
||||||
|
- Blocks: classification of the Goldshire WMO paired gap
|
||||||
|
- External state: `sources/OpenWCReferenceCheckpoints/goldshire_inn_large_wmo.jpg`
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- Commands: coarse and fine real sweeps, ranking inspection, repository gates
|
||||||
|
- Fixtures: private Goldshire Inn build 12340 screenshot
|
||||||
|
- Fidelity evidence: ranked mean perceptual error and changed-pixel ratio
|
||||||
|
- Performance budget: offline diagnostic only
|
||||||
|
|
||||||
|
## Documentation deliverables
|
||||||
|
|
||||||
|
- Inline public API docs: unchanged
|
||||||
|
- Module specification: fidelity finding and remaining risk
|
||||||
|
- Data-flow diagram: unchanged
|
||||||
|
- Sequence/state/dependency diagrams: unchanged
|
||||||
|
- Source map/status updates: baseline evidence
|
||||||
|
|
||||||
|
## Simplicity and naming
|
||||||
|
|
||||||
|
- Important names introduced: none
|
||||||
|
- Simplest considered solution: use the merged bounded grid runner
|
||||||
|
- Rejected complexity/abstractions: optimizer or renderer changes
|
||||||
|
- Unavoidable complexity and justification: real images must be rendered for each candidate
|
||||||
|
- Measured optimization evidence: single pass per candidate
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
- State: ready-for-review
|
||||||
|
- Done: private reference dimensions verified; coarse, extended and limit sweeps completed; representative candidates inspected; runner failure handling hardened
|
||||||
|
- Next: investigate Goldshire Inn spatial/placement composition separately; do not change manifest yaw/pitch from this metric
|
||||||
|
- Blocked by:
|
||||||
|
|
||||||
|
## Handoff
|
||||||
|
|
||||||
|
- Commit: this work-package commit
|
||||||
|
- Results: zero offset mean error 0.099632; coarse best (-10,-20) 0.077575; metric decreased monotonically to (0,-60) 0.063574/changed ratio 0.549556, while visual inspection showed only grass and no inn
|
||||||
|
- Remaining risks: full-frame color error cannot register a missing landmark; WMO placement/streaming at this checkpoint remains unresolved
|
||||||
|
- Documentation updated: `docs/CAMERA_POSE_SWEEP.md`, `docs/modules/world-renderer.md`
|
||||||
@@ -14,10 +14,11 @@ This offline M00 diagnostic recovers reproducible checkpoint framing when an ori
|
|||||||
-Checkpoint elwynn_adt_boundary `
|
-Checkpoint elwynn_adt_boundary `
|
||||||
-YawOffsets -15,-10,-5,0,5,10,15 `
|
-YawOffsets -15,-10,-5,0,5,10,15 `
|
||||||
-PitchOffsets -10,-5,0,5,10 `
|
-PitchOffsets -10,-5,0,5,10 `
|
||||||
|
-ViewportWidth 1280 -ViewportHeight 960 `
|
||||||
-WaitSeconds 2
|
-WaitSeconds 2
|
||||||
```
|
```
|
||||||
|
|
||||||
Each candidate receives its own output directory and comparison report. `ranking.json` sorts candidates by mean perceptual error and then changed-pixel ratio. Use `-PlanOnly` to validate the Cartesian grid and output paths without rendering. Run a coarse grid first, then a finer grid around the best candidate.
|
Each candidate receives its own output directory and comparison report. The viewport must exactly match the reference image dimensions; the runner fails on `size_mismatch` instead of inventing a score. `ranking.json` sorts candidates by mean perceptual error and then changed-pixel ratio. Use `-PlanOnly` to validate the Cartesian grid and output paths without rendering. Run a coarse grid first, then a finer grid around the best candidate.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
@@ -37,3 +38,11 @@ The smallest error is a candidate, not automatic fidelity approval. Geometry, ma
|
|||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
The headless capture dry-run must report requested yaw and pitch offsets. Comparator `--self-test` covers paired metrics. Sweep `-PlanOnly` covers deterministic grid expansion and output naming without requiring a display. A real ranked sweep requires a display and a private build 12340 reference image.
|
The headless capture dry-run must report requested yaw and pitch offsets. Comparator `--self-test` covers paired metrics. Sweep `-PlanOnly` covers deterministic grid expansion and output naming without requiring a display. A real ranked sweep requires a display and a private build 12340 reference image.
|
||||||
|
|
||||||
|
## Goldshire Inn evidence — 2026-07-12
|
||||||
|
|
||||||
|
The private `2560x1440` build 12340 `goldshire_inn_large_wmo` reference was evaluated at FOV 62 degrees. A coarse 5x5 grid over yaw/pitch `[-20, -10, 0, 10, 20]` reduced mean error from `0.099632` at `(0, 0)` to `0.077575` at `(-10, -20)`. Extending pitch produced `0.070901` at `(0, -40)` and `0.063574` at `(0, -60)` with changed-pixel ratio `0.549556`.
|
||||||
|
|
||||||
|
This is not a camera-pose solution. Human inspection shows the original-client reference centered on the Goldshire Inn, while the zero-offset OpenWC candidate contains forest/roads and no inn; negative pitch increasingly fills the frame with grass. The monotonically improving full-frame metric rewards similar green color coverage rather than landmark alignment. Therefore the manifest pose is unchanged and this checkpoint remains spatial/placement-composition evidence. A future registration metric must use approved landmark or region masks before it can select camera pose automatically.
|
||||||
|
|
||||||
|
During this run the sweep orchestration was hardened in two ways: expected comparator exit code `1` is now collected through an explicit child process, and viewport dimensions are explicit. A reference/candidate `size_mismatch` now fails before ranking instead of producing an empty metric.
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
|||||||
- Camera-occluder probe не нашёл camera containment в пяти точках; paired mismatch локализован прежде всего в manual look direction/target/FOV calibration, с явным ограничением по RID-only geometry.
|
- Camera-occluder probe не нашёл camera containment в пяти точках; paired mismatch локализован прежде всего в manual look direction/target/FOV calibration, с явным ограничением по RID-only geometry.
|
||||||
- Empirical FOV sweep выявил, что checkpoint camera должна явно вызывать `make_current()`; после исправления projection ranking остаётся inconclusive из-за неизвестного manual yaw/pitch/framing reference.
|
- Empirical FOV sweep выявил, что checkpoint camera должна явно вызывать `make_current()`; после исправления projection ranking остаётся inconclusive из-за неизвестного manual yaw/pitch/framing reference.
|
||||||
- Camera-pose sweep can now rank bounded yaw/pitch grids without changing manifest defaults; perceptual ranking remains diagnostic and requires human framing approval.
|
- Camera-pose sweep can now rank bounded yaw/pitch grids without changing manifest defaults; perceptual ranking remains diagnostic and requires human framing approval.
|
||||||
|
- Goldshire Inn pose evidence has no landmark-aligned optimum: full-frame error decreases as negative pitch replaces the missing inn composition with grass. The checkpoint remains a spatial/placement gap, not a validated camera offset.
|
||||||
- D3D12 descriptor issues remain; the capture-path anonymous `RefCounted` shutdown leak is regression-covered by a clean verbose dry-run, while other RID/resource diagnostics still require independent evidence.
|
- D3D12 descriptor issues remain; the capture-path anonymous `RefCounted` shutdown leak is regression-covered by a clean verbose dry-run, while other RID/resource diagnostics still require independent evidence.
|
||||||
- M2/WMO/material/particle/ribbon/portal parity incomplete.
|
- M2/WMO/material/particle/ribbon/portal parity incomplete.
|
||||||
- Public API is mostly exported configuration rather than stable contracts.
|
- Public API is mostly exported configuration rather than stable contracts.
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ param(
|
|||||||
[double[]]$YawOffsets = @(-10.0, 0.0, 10.0),
|
[double[]]$YawOffsets = @(-10.0, 0.0, 10.0),
|
||||||
[double[]]$PitchOffsets = @(-10.0, 0.0, 10.0),
|
[double[]]$PitchOffsets = @(-10.0, 0.0, 10.0),
|
||||||
[double]$CameraFov = 62.0,
|
[double]$CameraFov = 62.0,
|
||||||
|
[int]$ViewportWidth = 1280,
|
||||||
|
[int]$ViewportHeight = 900,
|
||||||
[double]$WaitSeconds = 2.0,
|
[double]$WaitSeconds = 2.0,
|
||||||
[double]$MeasureSeconds = 0.1,
|
[double]$MeasureSeconds = 0.1,
|
||||||
[switch]$PlanOnly
|
[switch]$PlanOnly
|
||||||
@@ -62,19 +64,26 @@ try {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
& $GodotPath --path . --script res://src/tools/capture_render_checkpoints.gd -- `
|
$captureArguments = @(
|
||||||
--output $candidateOutput --only $Checkpoint --single-pass `
|
"--path", ".", "--script", "res://src/tools/capture_render_checkpoints.gd", "--",
|
||||||
--camera-fov $cameraFovText `
|
"--output", $candidateOutput, "--only", $Checkpoint, "--single-pass",
|
||||||
--camera-yaw-offset $yawText --camera-pitch-offset $pitchText `
|
"--camera-fov", $cameraFovText,
|
||||||
--wait $waitSecondsText --measure $measureSecondsText
|
"--camera-yaw-offset", $yawText, "--camera-pitch-offset", $pitchText,
|
||||||
if ($LASTEXITCODE -ne 0) {
|
"--viewport-width", $ViewportWidth, "--viewport-height", $ViewportHeight,
|
||||||
|
"--wait", $waitSecondsText, "--measure", $measureSecondsText
|
||||||
|
)
|
||||||
|
$captureProcess = Start-Process -FilePath $GodotPath -ArgumentList $captureArguments -Wait -PassThru
|
||||||
|
if ($captureProcess.ExitCode -ne 0) {
|
||||||
throw "Capture failed for yaw=$yawText pitch=$pitchText"
|
throw "Capture failed for yaw=$yawText pitch=$pitchText"
|
||||||
}
|
}
|
||||||
|
|
||||||
& $GodotPath --headless --path . --script res://src/tools/compare_render_checkpoints.gd -- `
|
$comparisonArguments = @(
|
||||||
--reference $ReferenceDirectory --candidate $candidateOutput `
|
"--headless", "--path", ".", "--script", "res://src/tools/compare_render_checkpoints.gd", "--",
|
||||||
--only $Checkpoint --output $comparisonReport
|
"--reference", $ReferenceDirectory, "--candidate", $candidateOutput,
|
||||||
if ($LASTEXITCODE -notin @(0, 1)) {
|
"--only", $Checkpoint, "--output", $comparisonReport
|
||||||
|
)
|
||||||
|
$comparisonProcess = Start-Process -FilePath $GodotPath -ArgumentList $comparisonArguments -Wait -PassThru -NoNewWindow
|
||||||
|
if ($comparisonProcess.ExitCode -notin @(0, 1)) {
|
||||||
throw "Comparison failed for yaw=$yawText pitch=$pitchText"
|
throw "Comparison failed for yaw=$yawText pitch=$pitchText"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,8 +91,13 @@ try {
|
|||||||
if ($comparison.compared_count -lt 1) {
|
if ($comparison.compared_count -lt 1) {
|
||||||
throw "No paired image was compared for yaw=$yawText pitch=$pitchText"
|
throw "No paired image was compared for yaw=$yawText pitch=$pitchText"
|
||||||
}
|
}
|
||||||
$meanError = ($comparison.results | Measure-Object -Property mean_perceptual_error -Average).Average
|
$metricResults = @($comparison.results | Where-Object { $null -ne $_.mean_perceptual_error })
|
||||||
$changedRatio = ($comparison.results | Measure-Object -Property changed_pixel_ratio -Average).Average
|
if ($metricResults.Count -ne $comparison.compared_count) {
|
||||||
|
$statuses = ($comparison.results.status | Sort-Object -Unique) -join ","
|
||||||
|
throw "Comparison produced no numeric metric for yaw=$yawText pitch=$pitchText statuses=$statuses"
|
||||||
|
}
|
||||||
|
$meanError = ($metricResults | Measure-Object -Property mean_perceptual_error -Average).Average
|
||||||
|
$changedRatio = ($metricResults | Measure-Object -Property changed_pixel_ratio -Average).Average
|
||||||
$ranking.Add([pscustomobject]@{
|
$ranking.Add([pscustomobject]@{
|
||||||
yaw_offset_degrees = $yawOffset
|
yaw_offset_degrees = $yawOffset
|
||||||
pitch_offset_degrees = $pitchOffset
|
pitch_offset_degrees = $pitchOffset
|
||||||
@@ -106,6 +120,7 @@ try {
|
|||||||
schema_version = 1
|
schema_version = 1
|
||||||
checkpoint = $Checkpoint
|
checkpoint = $Checkpoint
|
||||||
reference_directory = [IO.Path]::GetFullPath($ReferenceDirectory)
|
reference_directory = [IO.Path]::GetFullPath($ReferenceDirectory)
|
||||||
|
viewport = @($ViewportWidth, $ViewportHeight)
|
||||||
candidates = $rankedCandidates
|
candidates = $rankedCandidates
|
||||||
}
|
}
|
||||||
New-Item -ItemType Directory -Force -Path $absoluteOutput | Out-Null
|
New-Item -ItemType Directory -Force -Path $absoluteOutput | Out-Null
|
||||||
|
|||||||
Reference in New Issue
Block a user