vrp-gruppe-sechs/escape-room/old_skripte/xr_hand_modifier_3d.gd

120 lines
3.8 KiB
GDScript

# XRToolsHandPoseController.gd
# Hängt am XRController3D (Left/Right)
# Verwaltet Hand-Posen basierend auf Trigger und Grip
extends XRController3D
class_name XRToolsHandPoseController
@export var hand_modifier: XRHandModifier3D
@export var hand_side: String = "left" # "left" oder "right"
var current_pose: String = "open"
var trigger_value: float = 0.0
var grip_value: float = 0.0
var pose_blend: float = 0.0
var target_pose_blend: float = 0.0
func _ready() -> void:
if not hand_modifier:
push_error("XRToolsHandPoseController: XRHandModifier3D nicht zugewiesen!")
return
print("Hand-Posen initialisiert für: ", hand_side)
func _process(delta: float) -> void:
_update_input()
_update_hand_animation(delta)
func _update_input() -> void:
# Trigger und Grip direkt vom Controller auslesen
trigger_value = get_float("trigger")
grip_value = get_float("grip")
# Pose basierend auf Input bestimmen
if grip_value > 0.7:
target_pose_blend = 0.0
current_pose = "fist"
elif trigger_value > 0.5 and grip_value < 0.3:
target_pose_blend = 1.0
current_pose = "pointing"
else:
target_pose_blend = 2.0
current_pose = "open"
func _update_hand_animation(delta: float) -> void:
# Sanftes Blending zwischen Posen
pose_blend = lerp(pose_blend, target_pose_blend, 5.0 * delta)
# XRHandModifier3D animiert automatisch basierend auf Skeleton-Posen
# Wende Bone-Transformationen direkt an
var skeleton: Skeleton3D = hand_modifier.get_parent() as Skeleton3D
if not skeleton:
return
# Passe Finger-Bones basierend auf aktuelle Pose an
_apply_pose_to_skeleton(skeleton, current_pose, pose_blend)
func _apply_pose_to_skeleton(skeleton: Skeleton3D, pose: String, blend: float) -> void:
"""Wende die Pose auf die Skeleton-Bones an"""
# Finde alle Finger-Bones
var thumb = _find_bone_index(skeleton, "Thumb")
var index = _find_bone_index(skeleton, "Index")
var middle = _find_bone_index(skeleton, "Middle")
var ring = _find_bone_index(skeleton, "Ring")
var pinky = _find_bone_index(skeleton, "Pinky")
match pose:
"fist":
# Alle Finger gekrümmt
_bend_finger(skeleton, thumb, blend)
_bend_finger(skeleton, index, blend)
_bend_finger(skeleton, middle, blend)
_bend_finger(skeleton, ring, blend)
_bend_finger(skeleton, pinky, blend)
"pointing":
# Zeigefinger gestreckt, andere gekrümmt
_extend_finger(skeleton, index, blend)
_bend_finger(skeleton, thumb, blend * 0.5)
_bend_finger(skeleton, middle, blend)
_bend_finger(skeleton, ring, blend)
_bend_finger(skeleton, pinky, blend)
"open":
# Alle Finger gestreckt
_extend_finger(skeleton, thumb, blend)
_extend_finger(skeleton, index, blend)
_extend_finger(skeleton, middle, blend)
_extend_finger(skeleton, ring, blend)
_extend_finger(skeleton, pinky, blend)
func _find_bone_index(skeleton: Skeleton3D, bone_name: String) -> int:
"""Finde den Index eines Bones nach Name (Substring-Match)"""
for i in range(skeleton.get_bone_count()):
if skeleton.get_bone_name(i).to_lower().contains(bone_name.to_lower()):
return i
return -1
func _bend_finger(skeleton: Skeleton3D, bone_idx: int, amount: float) -> void:
"""Krümme einen Finger (Rotation um X-Achse)"""
if bone_idx < 0:
return
var current_pose = skeleton.get_bone_pose(bone_idx)
var bent_rotation = Quaternion.from_euler(Vector3(amount * 1.5, 0, 0))
current_pose.basis = Basis(bent_rotation)
skeleton.set_bone_pose(bone_idx, current_pose)
func _extend_finger(skeleton: Skeleton3D, bone_idx: int, amount: float) -> void:
"""Strecke einen Finger (Rotation zurück auf Neutral)"""
if bone_idx < 0:
return
var current_pose = skeleton.get_bone_pose(bone_idx)
var extended_rotation = Quaternion.from_euler(Vector3(-amount * 0.5, 0, 0))
current_pose.basis = Basis(extended_rotation)
skeleton.set_bone_pose(bone_idx, current_pose)