render: extract native M2 animation resource observer
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
class_name M2NativeAnimationResourceObserver
|
||||
extends RefCounted
|
||||
|
||||
## Resolves the existing native GryphonRoost animated M2 prototype path.
|
||||
|
||||
const M2_NATIVE_ANIMATED_BUILDER_SCRIPT := preload(
|
||||
"res://addons/mpq_extractor/loaders/m2_native_animated_builder.gd"
|
||||
)
|
||||
|
||||
var _native_animated_builder: Object
|
||||
|
||||
|
||||
func _init(native_animated_builder: Object = M2_NATIVE_ANIMATED_BUILDER_SCRIPT) -> void:
|
||||
_native_animated_builder = native_animated_builder
|
||||
|
||||
|
||||
## Returns whether the normalized path uses the historical native animation path.
|
||||
func is_native_animation_candidate(normalized_relative_path: String) -> bool:
|
||||
return normalized_relative_path.to_lower().contains("gryphonroost")
|
||||
|
||||
|
||||
## Returns the exact cached or newly adopted native animated prototype.
|
||||
## Rejected native candidates are marked static-only for the renderer session.
|
||||
func observe(
|
||||
normalized_relative_path: String,
|
||||
extracted_directory: String,
|
||||
raw_model_repository: RefCounted,
|
||||
prototype_cache_state: RefCounted,
|
||||
debug_logging_enabled: bool = false
|
||||
) -> Node3D:
|
||||
if (
|
||||
normalized_relative_path.is_empty()
|
||||
or not is_native_animation_candidate(normalized_relative_path)
|
||||
or raw_model_repository == null
|
||||
or prototype_cache_state == null
|
||||
):
|
||||
return null
|
||||
|
||||
var cached_prototype := prototype_cache_state.call(
|
||||
"find_animated_prototype",
|
||||
normalized_relative_path
|
||||
) as Node3D
|
||||
if cached_prototype != null:
|
||||
return cached_prototype
|
||||
if bool(prototype_cache_state.call(
|
||||
"is_animation_static",
|
||||
normalized_relative_path
|
||||
)):
|
||||
return null
|
||||
|
||||
var animated_model_data: Dictionary = raw_model_repository.call(
|
||||
"load_animated_model_data",
|
||||
extracted_directory,
|
||||
normalized_relative_path
|
||||
)
|
||||
var animated_surfaces: Array = animated_model_data.get(
|
||||
"animated_surfaces",
|
||||
[]
|
||||
)
|
||||
if animated_model_data.is_empty() or animated_surfaces.is_empty():
|
||||
prototype_cache_state.call(
|
||||
"mark_animation_static",
|
||||
normalized_relative_path
|
||||
)
|
||||
return null
|
||||
|
||||
var prototype := build_animated_prototype(
|
||||
animated_model_data,
|
||||
extracted_directory
|
||||
)
|
||||
if prototype == null or prototype.get_child_count() <= 0:
|
||||
prototype_cache_state.call(
|
||||
"mark_animation_static",
|
||||
normalized_relative_path
|
||||
)
|
||||
return null
|
||||
|
||||
prototype = prototype_cache_state.call(
|
||||
"adopt_animated_prototype",
|
||||
normalized_relative_path,
|
||||
prototype
|
||||
) as Node3D
|
||||
if debug_logging_enabled:
|
||||
print(
|
||||
(
|
||||
"M2_NATIVE_ANIM_CACHE path=%s surfaces=%d bones=%d "
|
||||
+ "anim_id=%d seq=%d score=%d length=%.2f"
|
||||
)
|
||||
% [
|
||||
normalized_relative_path,
|
||||
animated_surfaces.size(),
|
||||
(animated_model_data.get("bones", []) as Array).size(),
|
||||
int(animated_model_data.get("animation_id", -1)),
|
||||
int(animated_model_data.get("animation_sequence_index", -1)),
|
||||
int(animated_model_data.get("animation_activity_score", 0)),
|
||||
float(animated_model_data.get("animation_length", 0.0)),
|
||||
]
|
||||
)
|
||||
return prototype
|
||||
|
||||
|
||||
## Builds one prototype through the exact native animated builder dependency.
|
||||
func build_animated_prototype(
|
||||
animated_model_data: Dictionary,
|
||||
extracted_directory: String
|
||||
) -> Node3D:
|
||||
if _native_animated_builder == null:
|
||||
return null
|
||||
return _native_animated_builder.call(
|
||||
"build",
|
||||
animated_model_data,
|
||||
extracted_directory
|
||||
) as Node3D
|
||||
@@ -0,0 +1 @@
|
||||
uid://bc3kgi23usncx
|
||||
Reference in New Issue
Block a user