first commit
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
extends SceneTree
|
||||
|
||||
const ADT_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/adt_builder.gd")
|
||||
const BAKED_TILE_SCRIPT := preload("res://resources/baked_adt_tile.gd")
|
||||
|
||||
var _builder
|
||||
var _loader
|
||||
var _image_cache: Dictionary = {}
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var args := OS.get_cmdline_user_args()
|
||||
var map_name := _get_arg_value(args, "--map", "Azeroth")
|
||||
var extracted_dir := _normalize_res_path(_get_arg_value(args, "--extracted", "res://extracted"))
|
||||
var output_dir := _normalize_res_path(_get_arg_value(args, "--output", "res://cache/baked_terrain_v2"))
|
||||
var legacy_texture_size = _get_optional_int_arg(args, "--texture-size")
|
||||
var full_texture_size := maxi(
|
||||
256,
|
||||
_get_arg_value(
|
||||
args,
|
||||
"--full-texture-size",
|
||||
str(legacy_texture_size if legacy_texture_size != null else 2048)
|
||||
).to_int()
|
||||
)
|
||||
var coarse_texture_size := maxi(
|
||||
128,
|
||||
_get_arg_value(
|
||||
args,
|
||||
"--coarse-texture-size",
|
||||
str(legacy_texture_size if legacy_texture_size != null else 512)
|
||||
).to_int()
|
||||
)
|
||||
var tile_x: Variant = _get_optional_int_arg(args, "--tile-x")
|
||||
var tile_y: Variant = _get_optional_int_arg(args, "--tile-y")
|
||||
var force := args.has("--force")
|
||||
|
||||
_builder = ADT_BUILDER_SCRIPT.new()
|
||||
if not ClassDB.class_exists("ADTLoader"):
|
||||
push_error("ADTLoader not found. Rebuild GDExtension first.")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
_loader = ClassDB.instantiate("ADTLoader")
|
||||
if _loader == null:
|
||||
push_error("Failed to instantiate ADTLoader.")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var map_dir := extracted_dir.path_join("World/Maps/%s" % map_name)
|
||||
var dir := DirAccess.open(map_dir)
|
||||
if dir == null:
|
||||
push_error("Cannot open map directory: %s" % map_dir)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(output_dir.path_join(map_name)))
|
||||
|
||||
var baked := 0
|
||||
var skipped := 0
|
||||
var failed := 0
|
||||
var started_ms := Time.get_ticks_msec()
|
||||
|
||||
for file_name in dir.get_files():
|
||||
if not file_name.ends_with(".adt"):
|
||||
continue
|
||||
|
||||
var stem := file_name.trim_suffix(".adt")
|
||||
var parts := stem.split("_")
|
||||
if parts.size() != 3 or parts[0] != map_name:
|
||||
continue
|
||||
if not parts[1].is_valid_int() or not parts[2].is_valid_int():
|
||||
continue
|
||||
|
||||
var tx := parts[1].to_int()
|
||||
var ty := parts[2].to_int()
|
||||
if tile_x != null and tx != tile_x:
|
||||
continue
|
||||
if tile_y != null and ty != tile_y:
|
||||
continue
|
||||
var source_res_path := map_dir.path_join(file_name)
|
||||
var source_abs_path := ProjectSettings.globalize_path(source_res_path)
|
||||
var output_res_path := output_dir.path_join(map_name).path_join("%s_%d_%d.res" % [map_name, tx, ty])
|
||||
var output_abs_path := ProjectSettings.globalize_path(output_res_path)
|
||||
|
||||
if not force and FileAccess.file_exists(output_abs_path):
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
var data: Dictionary = _loader.call("load_adt", source_abs_path)
|
||||
if data.is_empty() or not data.has("chunks"):
|
||||
push_warning("Bake failed to parse ADT: %s" % source_res_path)
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
var full_payload: Dictionary = _builder.build_baked_tile_render_payload(
|
||||
data,
|
||||
_image_cache,
|
||||
ProjectSettings.globalize_path(extracted_dir),
|
||||
0,
|
||||
full_texture_size)
|
||||
var coarse_payload: Dictionary = _builder.build_baked_tile_render_payload(
|
||||
data,
|
||||
_image_cache,
|
||||
ProjectSettings.globalize_path(extracted_dir),
|
||||
3,
|
||||
coarse_texture_size)
|
||||
|
||||
if full_payload.is_empty():
|
||||
push_warning("Bake produced empty full mesh: %s" % source_res_path)
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
var baked_tile: Resource = BAKED_TILE_SCRIPT.new()
|
||||
baked_tile.set("format_version", BAKED_TILE_SCRIPT.FORMAT_VERSION)
|
||||
baked_tile.set("map_name", map_name)
|
||||
baked_tile.set("tile_x", tx)
|
||||
baked_tile.set("tile_y", ty)
|
||||
baked_tile.set("tile_origin", _builder.get_tile_origin_for_data(data))
|
||||
baked_tile.set("full_texture_size", full_texture_size)
|
||||
baked_tile.set("coarse_texture_size", coarse_texture_size)
|
||||
baked_tile.set("wmo_names", data.get("wmo_names", PackedStringArray()))
|
||||
baked_tile.set("wmo_placements", data.get("wmo_placements", []))
|
||||
baked_tile.set("m2_names", data.get("m2_names", PackedStringArray()))
|
||||
baked_tile.set("m2_placements", data.get("m2_placements", []))
|
||||
baked_tile.set("full_mesh", full_payload.get("mesh", null))
|
||||
baked_tile.set("coarse_mesh", coarse_payload.get("mesh", null))
|
||||
|
||||
var save_err := ResourceSaver.save(baked_tile, output_res_path)
|
||||
if save_err != OK:
|
||||
push_warning("Failed to save baked tile: %s (err=%d)" % [output_res_path, save_err])
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
baked += 1
|
||||
if baked % 25 == 0:
|
||||
print("Baked %d tiles..." % baked)
|
||||
|
||||
var elapsed_ms := Time.get_ticks_msec() - started_ms
|
||||
print("Bake finished. baked=%d skipped=%d failed=%d elapsed=%.2fs" % [
|
||||
baked, skipped, failed, float(elapsed_ms) / 1000.0])
|
||||
quit(0 if failed == 0 else 2)
|
||||
|
||||
|
||||
func _get_arg_value(args: PackedStringArray, name: String, default_value: String) -> String:
|
||||
var index := args.find(name)
|
||||
if index >= 0 and index + 1 < args.size():
|
||||
return args[index + 1]
|
||||
return default_value
|
||||
|
||||
|
||||
func _get_optional_int_arg(args: PackedStringArray, name: String):
|
||||
var index := args.find(name)
|
||||
if index >= 0 and index + 1 < args.size() and args[index + 1].is_valid_int():
|
||||
return args[index + 1].to_int()
|
||||
return null
|
||||
|
||||
|
||||
func _normalize_res_path(path: String) -> String:
|
||||
if path.begins_with("res://"):
|
||||
return path
|
||||
return "res://%s" % path.trim_prefix("./").trim_prefix("/")
|
||||
Reference in New Issue
Block a user