Files
Papay-Shooter/debug/akiba_integrity_probe.gd
T
2026-08-02 02:20:02 -04:00

244 lines
9.0 KiB
GDScript

extends SceneTree
## Geometry/material regression probe for Akiba Crossing.
##
## This deliberately verifies the mechanisms that prove the requested fixes:
## imported art has one transformed triangle collider per rendered mesh (not
## an enclosing AABB), every supported prop sits on its declared plane, every
## utility curve terminates at a pole/building terminal, and cable interiors
## do not intersect static geometry.
var _frames := 0
var _result_ready := false
var _exit_code := 0
func _initialize() -> void:
change_scene_to_file("res://scenes/maps/neon_alley/neon_alley.tscn")
func _process(_delta: float) -> bool:
_frames += 1
if _result_ready:
if _frames >= 45:
quit(_exit_code)
return false
if _frames < 90:
return false
if current_scene == null:
printerr("AKIBA_INTEGRITY no current scene")
quit(1)
return false
var exact_bodies := 0
var exact_meshes := 0
var exact_shapes := 0
var collision_mismatches := 0
var fallbacks := 0
var untextured_cars := 0
var out_of_district := 0
for candidate in root.find_children("*", "StaticBody3D", true, false):
var body := candidate as StaticBody3D
if body.has_meta("exact_collision_fallback"):
fallbacks += 1
if not body.has_meta("mesh_exact_collision"):
continue
exact_bodies += 1
var meshes := body.find_children("*", "MeshInstance3D", true, false)
var shapes := body.find_children(
"ExactMeshCollision_*", "CollisionShape3D", false, false)
exact_meshes += meshes.size()
exact_shapes += shapes.size()
if meshes.size() != shapes.size():
collision_mismatches += 1
_report_collision_issue(body,
"mesh_count=%d shape_count=%d" % [meshes.size(), shapes.size()])
for shape_candidate in shapes:
var shape := shape_candidate as CollisionShape3D
if not shape.shape is ConcavePolygonShape3D \
or (shape.shape as ConcavePolygonShape3D).get_faces().is_empty():
collision_mismatches += 1
_report_collision_issue(body, "%s is not triangle collision" % shape.name)
continue
var source_path: String = str(shape.get_meta("source_mesh_path", ""))
var source := root.get_node_or_null(NodePath(source_path)) as MeshInstance3D
if source == null:
collision_mismatches += 1
_report_collision_issue(body, "%s has no source mesh" % shape.name)
continue
var expected := body.global_transform.affine_inverse() * source.global_transform
if not shape.transform.is_equal_approx(expected):
collision_mismatches += 1
_report_collision_issue(body, "%s transform differs from %s" % [
shape.name, source.name])
if body.name.begins_with("Car_") and not _has_textured_surface(body):
untextured_cars += 1
for child in root.find_children("*", "MeshInstance3D", true, false):
var mesh_instance := child as MeshInstance3D
if mesh_instance.mesh == null:
continue
var global_bounds := _transform_aabb(
mesh_instance.get_aabb(), mesh_instance.global_transform)
var center := global_bounds.get_center()
if absf(center.x) > 336.0 or absf(center.z) > 336.0:
out_of_district += 1
if out_of_district <= 8:
print("AKIBA_OUT_OF_DISTRICT %s center=%s" % [
mesh_instance.get_path(), center])
var support_checked := 0
var unsupported := 0
var road_lamps := 0
var road_intrusions := 0
for candidate in root.find_children("*", "Node3D", true, false):
var node := candidate as Node3D
if node.has_meta("support_fitted"):
support_checked += 1
var plane := float(node.get_meta("support_plane_y"))
var bounds := _global_visual_bounds(node)
if bounds.size == Vector3.ZERO or absf(bounds.position.y - plane) > 0.025:
unsupported += 1
if unsupported <= 8:
print("AKIBA_UNSUPPORTED_PROP %s bottom=%.4f plane=%.4f" % [
node.get_path(), bounds.position.y, plane])
var source_path: String = str(node.get_meta("source_asset_path", ""))
if source_path.contains("light-curved"):
road_lamps += 1
var p := node.global_position
var central_ns := absf(p.x) < 20.0
var central_ew := absf(p.z) < 20.0
if (central_ns and absf(p.x) < 7.0) \
or (central_ew and absf(p.z) < 7.0):
road_intrusions += 1
print("AKIBA_ROAD_LAMP %s position=%s" % [node.get_path(), p])
var terminals: Array[Vector3] = []
for marker in root.find_children("UtilityTerminal_*", "Node3D", true, false):
terminals.append((marker as Node3D).global_position)
var curves: Dictionary = {}
var cable_intersections := 0
var space: PhysicsDirectSpaceState3D = \
current_scene.get_world_3d().direct_space_state
for candidate in root.find_children("PowerCable_*", "MeshInstance3D", true, false):
var cable := candidate as MeshInstance3D
var curve_id := int(cable.get_meta("curve_id", -1))
var segment_index := int(cable.get_meta("segment_index", -1))
var segment_count := int(cable.get_meta("segment_count", 0))
if not curves.has(curve_id):
curves[curve_id] = {
"from": cable.get_meta("cable_from"),
"to": cable.get_meta("cable_to"),
"first": segment_index,
"last": segment_index,
}
else:
var record: Dictionary = curves[curve_id]
if segment_index < int(record["first"]):
record["first"] = segment_index
record["from"] = cable.get_meta("cable_from")
if segment_index > int(record["last"]):
record["last"] = segment_index
record["to"] = cable.get_meta("cable_to")
curves[curve_id] = record
var from: Vector3 = cable.get_meta("cable_from")
var to: Vector3 = cable.get_meta("cable_to")
var query := PhysicsRayQueryParameters3D.create(
from.lerp(to, 0.16), from.lerp(to, 0.84))
query.collide_with_areas = false
var hit: Dictionary = space.intersect_ray(query)
if not hit.is_empty():
cable_intersections += 1
if cable_intersections <= 8:
print("AKIBA_CABLE_INTERSECTION curve=%d segment=%d/%d collider=%s" % [
curve_id, segment_index, segment_count,
(hit["collider"] as Node).get_path()])
var unterminated_curves := 0
for curve_id in curves:
var record: Dictionary = curves[curve_id]
if not _near_terminal(record["from"], terminals) \
or not _near_terminal(record["to"], terminals):
unterminated_curves += 1
if unterminated_curves <= 8:
print("AKIBA_UNTERMINATED_CURVE id=%s from=%s to=%s" % [
curve_id, record["from"], record["to"]])
var power_cables := root.find_children(
"PowerCable_*", "MeshInstance3D", true, false).size()
var utility_poles := root.find_children(
"UtilityPole_*", "StaticBody3D", true, false).size()
var failures := collision_mismatches + fallbacks + untextured_cars \
+ out_of_district + unsupported + road_intrusions \
+ cable_intersections + unterminated_curves
print("AKIBA_INTEGRITY exact_bodies=%d exact_meshes=%d exact_shapes=%d collision_mismatches=%d fallbacks=%d untextured_cars=%d out_of_district=%d support_checked=%d unsupported=%d road_lamps=%d road_intrusions=%d cables=%d curves=%d poles=%d terminals=%d cable_intersections=%d unterminated_curves=%d failures=%d" % [
exact_bodies, exact_meshes, exact_shapes, collision_mismatches,
fallbacks, untextured_cars, out_of_district, support_checked,
unsupported, road_lamps, road_intrusions, power_cables,
curves.size(), utility_poles, terminals.size(), cable_intersections,
unterminated_curves, failures])
if failures > 0:
printerr("AKIBA_INTEGRITY FAILED")
_exit_code = 1
else:
print("AKIBA_INTEGRITY PASSED")
_exit_code = 0
unload_current_scene()
_result_ready = true
_frames = 0
return false
func _report_collision_issue(body: StaticBody3D, detail: String) -> void:
print("AKIBA_COLLISION_MISMATCH %s %s" % [body.get_path(), detail])
func _near_terminal(point: Vector3, terminals: Array[Vector3]) -> bool:
for terminal in terminals:
if point.distance_to(terminal) <= 0.035:
return true
return false
func _global_visual_bounds(node: Node) -> AABB:
var result := AABB()
var has_bounds := false
for child in node.find_children("*", "MeshInstance3D", true, false):
var mesh_instance := child as MeshInstance3D
if mesh_instance.mesh == null:
continue
var transformed := _transform_aabb(
mesh_instance.get_aabb(), mesh_instance.global_transform)
result = result.merge(transformed) if has_bounds else transformed
has_bounds = true
return result if has_bounds else AABB()
func _transform_aabb(bounds: AABB, xform: Transform3D) -> AABB:
var result := AABB(xform * bounds.position, Vector3.ZERO)
for x in 2:
for y in 2:
for z in 2:
var corner := bounds.position + Vector3(
bounds.size.x * float(x),
bounds.size.y * float(y),
bounds.size.z * float(z))
result = result.expand(xform * corner)
return result
func _has_textured_surface(body: Node) -> bool:
for child in body.find_children("*", "MeshInstance3D", true, false):
var mesh_instance := child as MeshInstance3D
if mesh_instance.mesh == null:
continue
for surface in mesh_instance.mesh.get_surface_count():
var material := mesh_instance.get_active_material(surface)
if material is ShaderMaterial \
and (material.get_shader_parameter("has_texture") == true \
or material.get_shader_parameter("use_vertex_color") == true):
return true
if material is BaseMaterial3D and material.albedo_texture != null:
return true
return false