d467ffee7f
Work-Package: M00-QAR-VISUAL-DIFF-001 Agent: sindo-main-codex Tests: synthetic JPG/PNG diff, manifest, coordination and documentation gates Fidelity: five build 12340 references compared; coordinate and placement gaps recorded
91 lines
4.3 KiB
GDScript
91 lines
4.3 KiB
GDScript
extends SceneTree
|
|
|
|
const MANIFEST_PATH := "res://src/tools/render_baseline_manifest.json"
|
|
const STREAMING_LOADER := preload("res://src/scenes/streaming/streaming_world_loader.gd")
|
|
const STREAMING_TILE := preload("res://src/resources/streaming_adt_tile.gd")
|
|
const SPLAT_TILE := preload("res://src/resources/splat_adt_tile.gd")
|
|
const CONTROL_SPLAT_TILE := preload("res://src/resources/control_splat_adt_tile.gd")
|
|
const WMO_STREAMING := preload("res://src/resources/wmo_streaming_resource.gd")
|
|
const WMO_BUILDER := preload("res://addons/mpq_extractor/loaders/wmo_builder.gd")
|
|
const M2_BUILDER := preload("res://addons/mpq_extractor/loaders/m2_builder.gd")
|
|
|
|
|
|
func _initialize() -> void:
|
|
var manifest := _load_manifest()
|
|
if manifest.is_empty():
|
|
quit(1)
|
|
return
|
|
|
|
var failures: Array[String] = []
|
|
_expect(int(manifest.get("schema_version", 0)) == 1, "manifest schema must be version 1", failures)
|
|
_expect(String(manifest.get("profile", "")) == "Blizzlike335", "manifest profile must be Blizzlike335", failures)
|
|
_expect(ResourceLoader.exists(String(manifest.get("scene", ""))), "streaming scene must exist", failures)
|
|
var fidelity_viewport: Array = manifest.get("fidelity_comparison_viewport", [])
|
|
_expect(fidelity_viewport.size() == 2 and int(fidelity_viewport[0]) > 0 and int(fidelity_viewport[1]) > 0, "fidelity comparison viewport must contain positive width and height", failures)
|
|
|
|
var covered := {}
|
|
var names := {}
|
|
for checkpoint_variant in manifest.get("checkpoints", []):
|
|
if not (checkpoint_variant is Dictionary):
|
|
failures.append("checkpoint entry must be a dictionary")
|
|
continue
|
|
var checkpoint: Dictionary = checkpoint_variant
|
|
var checkpoint_name := String(checkpoint.get("name", ""))
|
|
_expect(not checkpoint_name.is_empty(), "checkpoint name must not be empty", failures)
|
|
_expect(not names.has(checkpoint_name), "duplicate checkpoint name: %s" % checkpoint_name, failures)
|
|
names[checkpoint_name] = true
|
|
for key in ["camera", "target", "player"]:
|
|
var value = checkpoint.get(key, [])
|
|
_expect(value is Array and value.size() == 3, "%s.%s must contain three coordinates" % [checkpoint_name, key], failures)
|
|
for coverage_variant in checkpoint.get("coverage", []):
|
|
covered[String(coverage_variant)] = true
|
|
|
|
for required_variant in manifest.get("required_coverage", []):
|
|
var required := String(required_variant)
|
|
_expect(covered.has(required), "missing checkpoint coverage: %s" % required, failures)
|
|
|
|
var comparison_budgets: Dictionary = manifest.get("comparison_budgets", {})
|
|
for threshold_name in ["visual_mean_perceptual_error_max", "visual_changed_pixel_ratio_max", "visual_pixel_error_threshold"]:
|
|
var threshold := float(comparison_budgets.get(threshold_name, -1.0))
|
|
_expect(threshold >= 0.0 and threshold <= 1.0, "%s must be between 0 and 1" % threshold_name, failures)
|
|
|
|
var contract: Dictionary = manifest.get("cache_contract", {})
|
|
var actual_versions := {
|
|
"baked_terrain": STREAMING_LOADER.REQUIRED_BAKED_TILE_FORMAT_VERSION,
|
|
"streaming_terrain": STREAMING_TILE.FORMAT_VERSION,
|
|
"terrain_splat": SPLAT_TILE.FORMAT_VERSION,
|
|
"terrain_control_splat": CONTROL_SPLAT_TILE.FORMAT_VERSION,
|
|
"wmo_streaming": WMO_STREAMING.FORMAT_VERSION,
|
|
"wmo_builder": WMO_BUILDER.WMO_BUILDER_FORMAT_VERSION,
|
|
"m2_material": M2_BUILDER.MATERIAL_FORMAT_VERSION,
|
|
}
|
|
for cache_name in actual_versions:
|
|
var entry: Dictionary = contract.get(cache_name, {})
|
|
_expect(int(entry.get("version", -1)) == int(actual_versions[cache_name]), "cache version mismatch for %s" % cache_name, failures)
|
|
_expect(not String(entry.get("invalidate", "")).is_empty(), "cache invalidation rule missing for %s" % cache_name, failures)
|
|
|
|
if not failures.is_empty():
|
|
for failure in failures:
|
|
push_error("RENDER_BASELINE_MANIFEST: %s" % failure)
|
|
quit(1)
|
|
return
|
|
print("RENDER_BASELINE_MANIFEST PASS checkpoints=%d coverage=%d caches=%d" % [names.size(), covered.size(), actual_versions.size()])
|
|
quit(0)
|
|
|
|
|
|
func _load_manifest() -> Dictionary:
|
|
var file := FileAccess.open(MANIFEST_PATH, FileAccess.READ)
|
|
if file == null:
|
|
push_error("Cannot open render baseline manifest: %s" % MANIFEST_PATH)
|
|
return {}
|
|
var parsed = JSON.parse_string(file.get_as_text())
|
|
if not (parsed is Dictionary):
|
|
push_error("Render baseline manifest is not a JSON object")
|
|
return {}
|
|
return parsed
|
|
|
|
|
|
func _expect(condition: bool, message: String, failures: Array[String]) -> void:
|
|
if not condition:
|
|
failures.append(message)
|