архитектура и цели для агентов
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
extends SceneTree
|
||||
|
||||
const STREAMING_SCENE := "res://src/scenes/streaming/eastern_kingdoms_streaming.tscn"
|
||||
|
||||
const CHECKPOINTS := [
|
||||
{
|
||||
"name": "elwynn_waterfall_front",
|
||||
"camera": Vector3(16445.0, 125.0, 26295.0),
|
||||
"target": Vector3(16518.84, 68.0, 26427.27),
|
||||
"player": Vector3(16518.84, 55.0, 26427.27),
|
||||
},
|
||||
{
|
||||
"name": "elwynn_waterfall_side",
|
||||
"camera": Vector3(16670.0, 115.0, 26320.0),
|
||||
"target": Vector3(16518.84, 72.0, 26427.27),
|
||||
"player": Vector3(16518.84, 55.0, 26427.27),
|
||||
},
|
||||
{
|
||||
"name": "goldshire_inn_windows",
|
||||
"camera": Vector3(16942.0, 82.0, 26503.0),
|
||||
"target": Vector3(17042.27, 66.0, 26530.91),
|
||||
"player": Vector3(17042.27, 58.0, 26530.91),
|
||||
},
|
||||
{
|
||||
"name": "goldshire_blacksmith_windows",
|
||||
"camera": Vector3(16892.0, 79.0, 26562.0),
|
||||
"target": Vector3(16972.46, 64.0, 26526.7),
|
||||
"player": Vector3(16972.46, 58.0, 26526.7),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
_capture_async.call_deferred()
|
||||
|
||||
|
||||
func _capture_async() -> void:
|
||||
var args := OS.get_cmdline_user_args()
|
||||
var output_dir := _arg(args, "--output", "user://render_checkpoints")
|
||||
var only := _arg(args, "--only", "").to_lower()
|
||||
var wait_seconds := float(_arg(args, "--wait", "8.0"))
|
||||
var width := int(_arg(args, "--width", "1280"))
|
||||
var height := int(_arg(args, "--height", "900"))
|
||||
var headless := DisplayServer.get_name().to_lower() == "headless"
|
||||
var dry_run := args.has("--dry-run") or headless
|
||||
|
||||
get_root().size = Vector2i(maxi(16, width), maxi(16, height))
|
||||
var abs_output_dir := ProjectSettings.globalize_path(output_dir)
|
||||
if not dry_run:
|
||||
DirAccess.make_dir_recursive_absolute(abs_output_dir)
|
||||
elif headless and not args.has("--dry-run"):
|
||||
print("RENDER_CHECKPOINT dry-run: headless display cannot capture viewport PNGs.")
|
||||
|
||||
var packed: PackedScene = load(STREAMING_SCENE)
|
||||
if packed == null:
|
||||
push_error("Cannot load streaming scene: %s" % STREAMING_SCENE)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var world = packed.instantiate()
|
||||
if not (world is Node3D):
|
||||
push_error("Streaming scene root is not Node3D: %s" % STREAMING_SCENE)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var camera := Camera3D.new()
|
||||
camera.name = "CheckpointCamera"
|
||||
camera.current = true
|
||||
camera.fov = 62.0
|
||||
camera.far = 50000.0
|
||||
camera.position = CHECKPOINTS[0].get("camera", Vector3.ZERO)
|
||||
(world as Node3D).add_child(camera)
|
||||
world.set("camera_path", NodePath("CheckpointCamera"))
|
||||
world.set("debug_streaming", true)
|
||||
get_root().add_child(world)
|
||||
await process_frame
|
||||
await process_frame
|
||||
|
||||
var player := world.get_node_or_null("ThirdPersonPlayer") as Node3D
|
||||
if player != null:
|
||||
player.set_process(false)
|
||||
player.set_physics_process(false)
|
||||
var visual := player.get_node_or_null("Visual") as Node3D
|
||||
if visual != null:
|
||||
visual.visible = false
|
||||
|
||||
var captured := 0
|
||||
for checkpoint_variant in CHECKPOINTS:
|
||||
var checkpoint: Dictionary = checkpoint_variant
|
||||
var checkpoint_name := String(checkpoint.get("name", "checkpoint"))
|
||||
if not only.is_empty() and not checkpoint_name.to_lower().contains(only):
|
||||
continue
|
||||
|
||||
camera.global_position = checkpoint.get("camera", Vector3.ZERO)
|
||||
camera.look_at(checkpoint.get("target", Vector3.ZERO), Vector3.UP)
|
||||
if player != null:
|
||||
player.global_position = checkpoint.get("player", checkpoint.get("target", Vector3.ZERO))
|
||||
if world.has_method("_refresh_streaming_targets_at"):
|
||||
world.call("_refresh_streaming_targets_at", camera.global_position, true)
|
||||
|
||||
await create_timer(maxf(wait_seconds, 0.0)).timeout
|
||||
if dry_run:
|
||||
print("RENDER_CHECKPOINT dry_run name=%s camera=%s target=%s" % [
|
||||
checkpoint_name,
|
||||
camera.global_position,
|
||||
checkpoint.get("target", Vector3.ZERO),
|
||||
])
|
||||
captured += 1
|
||||
continue
|
||||
|
||||
await RenderingServer.frame_post_draw
|
||||
|
||||
var image := get_root().get_texture().get_image()
|
||||
var file_name := "%s.png" % checkpoint_name
|
||||
var abs_path := abs_output_dir.path_join(file_name)
|
||||
var err := image.save_png(abs_path)
|
||||
if err != OK:
|
||||
push_error("Failed to save checkpoint %s to %s (err=%d)" % [checkpoint_name, abs_path, err])
|
||||
quit(1)
|
||||
return
|
||||
print("RENDER_CHECKPOINT saved %s" % abs_path)
|
||||
captured += 1
|
||||
|
||||
world.queue_free()
|
||||
if captured <= 0:
|
||||
push_error("No checkpoints captured. --only filter was: %s" % only)
|
||||
quit(1)
|
||||
return
|
||||
quit(0)
|
||||
|
||||
|
||||
func _arg(args: PackedStringArray, name: String, default_value: String) -> String:
|
||||
var idx := args.find(name)
|
||||
if idx >= 0 and idx + 1 < args.size():
|
||||
return args[idx + 1]
|
||||
return default_value
|
||||
Reference in New Issue
Block a user