Feat/14 movement overhaul #20
@@ -66,6 +66,16 @@ func load_model(path: String) -> void:
|
|||||||
scene.position = Vector3(0, position_y_offset * scale_factor, 0)
|
scene.position = Vector3(0, position_y_offset * scale_factor, 0)
|
||||||
print("SkinnedPlayerModel: applied scale %.4f, y_offset %.4f" % [scale_factor, position_y_offset])
|
print("SkinnedPlayerModel: applied scale %.4f, y_offset %.4f" % [scale_factor, position_y_offset])
|
||||||
|
|
||||||
|
# Find skeleton FIRST (needed for mesh binding fix below)
|
||||||
|
skeleton = _find_skeleton(scene)
|
||||||
|
if skeleton:
|
||||||
|
print("SkinnedPlayerModel: found skeleton '%s' with %d bones" % [skeleton.name, skeleton.get_bone_count()])
|
||||||
|
# Cache bone indices for fast lookups in procedural animations
|
||||||
|
for i in range(skeleton.get_bone_count()):
|
||||||
|
_bone_cache[skeleton.get_bone_name(i)] = i
|
||||||
|
else:
|
||||||
|
print("SkinnedPlayerModel: WARNING - no skeleton found")
|
||||||
|
|
||||||
# Find mesh instance for first-person mode
|
# Find mesh instance for first-person mode
|
||||||
_mesh_instance = scene.find_child("Tda Miku for fbx_mesh", true, false)
|
_mesh_instance = scene.find_child("Tda Miku for fbx_mesh", true, false)
|
||||||
if not _mesh_instance:
|
if not _mesh_instance:
|
||||||
@@ -92,16 +102,6 @@ func load_model(path: String) -> void:
|
|||||||
print("SkinnedPlayerModel: scene tree:")
|
print("SkinnedPlayerModel: scene tree:")
|
||||||
_print_tree(scene, 0)
|
_print_tree(scene, 0)
|
||||||
|
|
||||||
# Find skeleton
|
|
||||||
skeleton = _find_skeleton(scene)
|
|
||||||
if skeleton:
|
|
||||||
print("SkinnedPlayerModel: found skeleton '%s' with %d bones" % [skeleton.name, skeleton.get_bone_count()])
|
|
||||||
# Cache bone indices for fast lookups in procedural animations
|
|
||||||
for i in range(skeleton.get_bone_count()):
|
|
||||||
_bone_cache[skeleton.get_bone_name(i)] = i
|
|
||||||
else:
|
|
||||||
print("SkinnedPlayerModel: WARNING - no skeleton found")
|
|
||||||
|
|
||||||
# Find AnimationPlayer
|
# Find AnimationPlayer
|
||||||
animation_player = _find_animation_player(scene)
|
animation_player = _find_animation_player(scene)
|
||||||
if animation_player:
|
if animation_player:
|
||||||
@@ -370,7 +370,6 @@ func play_animation(anim_name: String) -> void:
|
|||||||
|
|
||||||
var _last_played: String = ""
|
var _last_played: String = ""
|
||||||
var _missing_anim_warned: Array = []
|
var _missing_anim_warned: Array = []
|
||||||
var _skin_update_acc: float = 0.0
|
|
||||||
|
|
||||||
func _warn_missing(anim_name: String) -> void:
|
func _warn_missing(anim_name: String) -> void:
|
||||||
## Warn once per missing animation, not every frame.
|
## Warn once per missing animation, not every frame.
|
||||||
@@ -392,14 +391,14 @@ func _process(delta: float) -> void:
|
|||||||
elif _last_played == "":
|
elif _last_played == "":
|
||||||
print("SkinnedPlayerModel: NOT playing")
|
print("SkinnedPlayerModel: NOT playing")
|
||||||
|
|
||||||
# Force skeleton skin update — GLTF runtime loaded models need explicit
|
# Force skeleton skin update EVERY frame, deferred to ensure it runs
|
||||||
# bone pose re-application to trigger MeshInstance vertex deformation.
|
# AFTER the AnimationPlayer has advanced its poses this frame.
|
||||||
# Throttled to ~30fps to avoid per-frame overhead.
|
# GLTF runtime loaded models need this to emit bone_pose_changed,
|
||||||
if skeleton and animation_player.is_playing():
|
# which triggers the MeshInstance to re-compute its skin vertex buffers.
|
||||||
_skin_update_acc += delta
|
# Without deferral, this runs before AnimationPlayer._process() (due to
|
||||||
if _skin_update_acc > 0.033:
|
# tree order), so the MeshInstance would render with stale poses.
|
||||||
_skin_update_acc = 0.0
|
if skeleton:
|
||||||
_update_skin()
|
call_deferred("_update_skin")
|
||||||
|
|
||||||
# Get movement state from parent PlayerMovementController
|
# Get movement state from parent PlayerMovementController
|
||||||
var parent = get_parent()
|
var parent = get_parent()
|
||||||
|
|||||||
Reference in New Issue
Block a user