99 lines
3.5 KiB
GDScript
99 lines
3.5 KiB
GDScript
extends SceneTree
|
|
|
|
## Converts the heavy baked ADT cache into a lightweight runtime streaming cache.
|
|
##
|
|
## Usage:
|
|
## godot --headless --path <project> --script res://src/tools/build_adt_streaming_cache.gd -- \
|
|
## --map Azeroth --input res://data/cache/baked_terrain_v2 --output res://data/cache/baked_terrain_stream_v1 --force
|
|
|
|
const BAKED_TILE_SCRIPT := preload("res://src/resources/baked_adt_tile.gd")
|
|
const STREAMING_TILE_SCRIPT := preload("res://src/resources/streaming_adt_tile.gd")
|
|
|
|
|
|
func _initialize() -> void:
|
|
var args := OS.get_cmdline_user_args()
|
|
var map_name := _arg(args, "--map", "Azeroth")
|
|
var input_dir := _res(_arg(args, "--input", "res://data/cache/baked_terrain_v2"))
|
|
var output_dir := _res(_arg(args, "--output", "res://data/cache/baked_terrain_stream_v1"))
|
|
var force := args.has("--force")
|
|
|
|
var in_map_dir := input_dir.path_join(map_name)
|
|
var out_map_dir := output_dir.path_join(map_name)
|
|
var in_map_abs := ProjectSettings.globalize_path(in_map_dir)
|
|
var out_map_abs := ProjectSettings.globalize_path(out_map_dir)
|
|
if not DirAccess.dir_exists_absolute(in_map_abs):
|
|
push_error("Input baked terrain cache not found: %s" % in_map_dir)
|
|
quit(1)
|
|
return
|
|
DirAccess.make_dir_recursive_absolute(out_map_abs)
|
|
|
|
var dir := DirAccess.open(in_map_dir)
|
|
if dir == null:
|
|
push_error("Cannot open input cache dir: %s" % in_map_dir)
|
|
quit(1)
|
|
return
|
|
|
|
var files := dir.get_files()
|
|
files.sort()
|
|
var converted := 0
|
|
var skipped := 0
|
|
var failed := 0
|
|
var started_ms := Time.get_ticks_msec()
|
|
|
|
for file_name in files:
|
|
if not file_name.ends_with(".res"):
|
|
continue
|
|
var in_path := in_map_dir.path_join(file_name)
|
|
var out_path := out_map_dir.path_join(file_name)
|
|
if not force and ResourceLoader.exists(out_path):
|
|
skipped += 1
|
|
continue
|
|
|
|
var baked: Resource = load(in_path)
|
|
if baked == null or baked.get_script() != BAKED_TILE_SCRIPT:
|
|
push_warning("Invalid baked tile: %s" % in_path)
|
|
failed += 1
|
|
continue
|
|
|
|
var stream_tile: Resource = STREAMING_TILE_SCRIPT.new()
|
|
stream_tile.set("format_version", STREAMING_TILE_SCRIPT.FORMAT_VERSION)
|
|
stream_tile.set("map_name", str(baked.get("map_name")))
|
|
stream_tile.set("tile_x", int(baked.get("tile_x")))
|
|
stream_tile.set("tile_y", int(baked.get("tile_y")))
|
|
stream_tile.set("tile_origin", baked.get("tile_origin"))
|
|
stream_tile.set("texture_size", int(baked.get("coarse_texture_size")))
|
|
stream_tile.set("wmo_names", baked.get("wmo_names"))
|
|
stream_tile.set("wmo_placements", baked.get("wmo_placements"))
|
|
stream_tile.set("m2_names", baked.get("m2_names"))
|
|
stream_tile.set("m2_placements", baked.get("m2_placements"))
|
|
stream_tile.set("terrain_mesh", baked.get("coarse_mesh"))
|
|
|
|
var err := ResourceSaver.save(stream_tile, out_path)
|
|
if err != OK:
|
|
push_warning("Failed to save streaming tile %s (err=%d)" % [out_path, err])
|
|
failed += 1
|
|
continue
|
|
|
|
converted += 1
|
|
if converted % 25 == 0:
|
|
print("Converted %d tiles..." % converted)
|
|
|
|
var elapsed_ms := Time.get_ticks_msec() - started_ms
|
|
print("Streaming cache finished. converted=%d skipped=%d failed=%d elapsed=%.2fs" % [
|
|
converted, skipped, failed, float(elapsed_ms) / 1000.0
|
|
])
|
|
quit(0 if failed == 0 else 2)
|
|
|
|
|
|
func _arg(args: PackedStringArray, name: String, default: String) -> String:
|
|
var idx := args.find(name)
|
|
if idx >= 0 and idx + 1 < args.size():
|
|
return args[idx + 1]
|
|
return default
|
|
|
|
|
|
func _res(path: String) -> String:
|
|
if path.begins_with("res://") or path.begins_with("user://"):
|
|
return path
|
|
return "res://" + path.trim_prefix("./").trim_prefix("/")
|