Files
mech/scripts/mech_skeleton_modifier.gd

55 lines
1.8 KiB
GDScript

class_name MechSkeletonModifier extends SkeletonModifier3D
@export var _pelvis_bone: String = "Pelvis"
@export var _ankle_bone_l: String = "Ankle_L"
@export var _leg_ik_target_l: Node3D
@export var _ankle_bone_r: String = "Ankle_R"
@export var _leg_ik_target_r: Node3D
@export var _feet_stretch_pelvis_lowering_factor: float = 0.3
var _skeleton: Skeleton3D
var _pelvis_rest_y: float
var _feet_rest_distance: float
func _ready() -> void:
_skeleton = get_skeleton()
var pelvis_rest := _skeleton.get_bone_global_rest(_skeleton.find_bone(_pelvis_bone))
var ankle_rest_l := _skeleton.get_bone_global_rest(
_skeleton.find_bone(_ankle_bone_l)
)
var ankle_rest_r := _skeleton.get_bone_global_rest(
_skeleton.find_bone(_ankle_bone_r)
)
_pelvis_rest_y = (
pelvis_rest.origin.y - (ankle_rest_l.origin.y + ankle_rest_r.origin.y) / 2
)
_feet_rest_distance = ankle_rest_l.origin.distance_to(ankle_rest_r.origin)
func _process_modification() -> void:
if not _skeleton:
return
var pelvis_bone := _skeleton.find_bone(_pelvis_bone)
var pelvis_bone_pose := _skeleton.get_bone_global_pose(pelvis_bone)
var leg_target_pos_l := to_local(_leg_ik_target_l.global_position)
var leg_target_pos_r := to_local(_leg_ik_target_r.global_position)
var pelvis_pos := (leg_target_pos_l + leg_target_pos_r) / 2
pelvis_pos.y = minf(leg_target_pos_l.y, leg_target_pos_r.y) + _pelvis_rest_y
var feet_distance := (leg_target_pos_l * Vector3(1, 0, 1)).distance_to(
leg_target_pos_r * Vector3(1, 0, 1)
)
var feet_stretch_pelvis_lowering := (
(feet_distance - _feet_rest_distance) * _feet_stretch_pelvis_lowering_factor
)
pelvis_pos.y -= clampf(feet_stretch_pelvis_lowering, 0, _pelvis_rest_y)
pelvis_bone_pose.origin = pelvis_pos
_skeleton.set_bone_global_pose(pelvis_bone, pelvis_bone_pose)