netfishing/tests/exported_decal_hotfix_validation.gd

163 lines
5.1 KiB
GDScript

extends SceneTree
const FEATURE_ASSET_ROOTS: Dictionary = {
"eyes": "res://art/exported/characters/faces/eyes",
"mouth": "res://art/exported/characters/faces/mouth",
"nose": "res://art/exported/characters/faces/noses",
}
const FACIAL_FEATURE_SIZE_LIMIT: int = 512
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
CharacterCustomizationCatalog.refresh_feature_assets()
assert(CharacterCustomizationCatalog._feature_textures.is_empty())
assert(
CharacterCustomizationCatalog._canonical_feature_filename(
"eyes_alligator_eyes.png"
) == "eyes_alligator_eyes.png"
)
assert(
CharacterCustomizationCatalog._canonical_feature_filename(
"eyes_alligator_eyes.png.import"
) == "eyes_alligator_eyes.png"
)
assert(
CharacterCustomizationCatalog._canonical_feature_filename(
"eyes_alligator_eyes.png.remap"
) == "eyes_alligator_eyes.png"
)
assert(
CharacterCustomizationCatalog._canonical_feature_filename(
"eyes_alligator_eyes.jpg"
).is_empty()
)
var load_candidates: Array[Dictionary] = []
for category_id: String in FEATURE_ASSET_ROOTS:
var options := CharacterCustomizationCatalog.options_for(category_id)
var expected_ids: Dictionary = _feature_ids_on_disk(category_id)
assert(options.size() == expected_ids.size() + 1)
var seen_ids: Dictionary = {}
for option: Dictionary in options:
var option_id := str(option.get("id", ""))
assert(not seen_ids.has(option_id))
seen_ids[option_id] = true
if option_id != "none":
var texture_path := (
CharacterCustomizationCatalog.feature_texture_path(
category_id, option_id
)
)
assert(not texture_path.is_empty())
assert(ResourceLoader.exists(texture_path, "Texture2D"))
_validate_feature_import(texture_path)
load_candidates.append({
"category_id": category_id,
"option_id": option_id,
})
for expected_id: String in expected_ids:
assert(seen_ids.has(expected_id))
assert(CharacterCustomizationCatalog._feature_textures.is_empty())
assert(
load_candidates.size()
> CharacterCustomizationCatalog.FEATURE_TEXTURE_CACHE_LIMIT
)
for candidate_index: int in range(
CharacterCustomizationCatalog.FEATURE_TEXTURE_CACHE_LIMIT + 1
):
var candidate: Dictionary = load_candidates[candidate_index]
assert(CharacterCustomizationCatalog.texture_for(
str(candidate["category_id"]),
str(candidate["option_id"]),
) != null)
assert(
CharacterCustomizationCatalog._feature_textures.size()
== CharacterCustomizationCatalog.FEATURE_TEXTURE_CACHE_LIMIT
)
for mouth_id: String in ["open_ah", "open_oh", "open_smile"]:
assert(CharacterCustomizationCatalog.texture_for(
"mouth", mouth_id
) != null)
assert(
CharacterCustomizationCatalog._feature_textures.size()
<= CharacterCustomizationCatalog.FEATURE_TEXTURE_CACHE_LIMIT
)
_validate_linux_arm64_texture_format()
await _validate_incremental_profile_previews()
print("Exported decal hotfix validation: PASS")
quit()
func _validate_feature_import(texture_path: String) -> void:
var import_config := ConfigFile.new()
assert(import_config.load(texture_path + ".import") == OK)
assert(int(import_config.get_value("params", "compress/mode", -1)) == 2)
assert(not bool(import_config.get_value(
"params", "mipmaps/generate", true
)))
assert(int(import_config.get_value(
"params", "process/size_limit", 0
)) == FACIAL_FEATURE_SIZE_LIMIT)
assert(int(import_config.get_value(
"params", "detect_3d/compress_to", -1
)) == 0)
func _validate_linux_arm64_texture_format() -> void:
var export_config := ConfigFile.new()
assert(export_config.load("res://export_presets.cfg") == OK)
assert(not bool(export_config.get_value(
"preset.3.options", "texture_format/s3tc_bptc", true
)))
assert(bool(export_config.get_value(
"preset.3.options", "texture_format/etc2_astc", false
)))
func _validate_incremental_profile_previews() -> void:
var profile_page := ProfilePage.new()
root.add_child(profile_page)
await process_frame
for category_id: String in CharacterCustomizationCatalog.FEATURE_CATEGORIES:
var cached_before: int = (
(profile_page.get("_feature_preview_cache") as Dictionary).size()
)
profile_page.call("_select_category", category_id)
var initial_requests: int = (
(profile_page.get("_feature_preview_requests") as Array).size()
)
assert(initial_requests > 3)
for _frame: int in 4:
await process_frame
var cached_after: int = (
(profile_page.get("_feature_preview_cache") as Dictionary).size()
)
assert(cached_after > cached_before)
assert(cached_after - cached_before < initial_requests)
profile_page.queue_free()
for _frame: int in 8:
await process_frame
func _feature_ids_on_disk(category_id: String) -> Dictionary:
var result: Dictionary = {}
var root_path: String = str(FEATURE_ASSET_ROOTS[category_id])
var directory := DirAccess.open(root_path)
assert(directory != null)
for file_name: String in directory.get_files():
if not file_name.to_lower().ends_with(".png"):
continue
var option_id: String = (
CharacterCustomizationCatalog._feature_id_from_filename(
category_id, file_name
)
)
if not option_id.is_empty():
result[option_id] = true
return result