Feat/14 movement overhaul #20

Merged
Dotts merged 86 commits from feat/14-movement-overhaul into main 2026-07-17 10:44:23 -07:00
Showing only changes of commit d297da4c35 - Show all commits
+18 -19
View File
@@ -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()