196 lines
7.3 KiB
GDScript
196 lines
7.3 KiB
GDScript
@tool
|
|
extends Node3D
|
|
|
|
@export var tracking : UltraleapDeviceNode
|
|
@export var handedness : UltraleapTypes.Chirality = UltraleapTypes.Chirality.Left
|
|
@export var skeleton : Skeleton3D
|
|
@export var ex_map : RigMap
|
|
@export var rig_settings : RigSettings
|
|
@export var use_interpolation : bool = true
|
|
|
|
var wrist_pos : Vector3
|
|
var transform_offset : Transform3D = Transform3D.IDENTITY
|
|
var original_arm_length : float = 0.0
|
|
|
|
@export var global_bone_scale : Vector3 = Vector3(1, 1, 1)
|
|
|
|
func _ready():
|
|
if skeleton == null:
|
|
return
|
|
|
|
skeleton.animate_physical_bones = true
|
|
|
|
if ex_map.get("arm") != "" and ex_map.get("wrist") != "":
|
|
var arm_rest_transform : Transform3D = skeleton.get_bone_global_rest(skeleton.find_bone(ex_map.get("arm")))
|
|
var wrist_rest_transform : Transform3D = skeleton.get_bone_global_rest(skeleton.find_bone(ex_map.get("wrist")))
|
|
original_arm_length = (wrist_rest_transform.origin - arm_rest_transform.origin).length()
|
|
|
|
func _process(_delta):
|
|
if tracking == null:
|
|
skeleton.hide()
|
|
return
|
|
|
|
if Engine.is_editor_hint() and not tracking.run_in_editor:
|
|
skeleton.reset_bone_poses()
|
|
skeleton.show()
|
|
return
|
|
|
|
var frame : UltraleapFrame = tracking.get_last_frame()
|
|
if frame == null:
|
|
skeleton.hide()
|
|
return
|
|
if use_interpolation:
|
|
var interpolated_frame : UltraleapFrame = tracking.get_interpolated_frame(Time.get_ticks_usec())
|
|
if interpolated_frame != null:
|
|
frame = interpolated_frame
|
|
|
|
if handedness == UltraleapTypes.Chirality.Left:
|
|
if frame.is_left_hand_visible:
|
|
skeleton.show()
|
|
set_hand(frame.left_hand)
|
|
else:
|
|
skeleton.hide()
|
|
|
|
else:
|
|
if frame.is_right_hand_visible:
|
|
skeleton.show()
|
|
set_hand(frame.right_hand)
|
|
else:
|
|
skeleton.hide()
|
|
|
|
func set_hand(hand : UltraleapHand):
|
|
transform_offset = tracking.global_transform.inverse()
|
|
if rig_settings.set_arm:
|
|
transform_offset *= set_arm(hand)
|
|
if rig_settings.set_palm:
|
|
set_palm(hand)
|
|
|
|
set_wrist(hand)
|
|
|
|
set_finger("thumb", hand)
|
|
set_finger("index", hand)
|
|
set_finger("middle", hand)
|
|
set_finger("ring", hand)
|
|
set_finger("pinky", hand)
|
|
|
|
func set_arm(hand : UltraleapHand) -> Transform3D:
|
|
var arm_name : String = ex_map.get("arm")
|
|
|
|
var bone_idx : int = skeleton.find_bone(arm_name)
|
|
|
|
var base : Basis = Basis(hand.arm.orientation)
|
|
var origin : Vector3 = hand.arm.prev_joint
|
|
if rig_settings.keep_original_arm_size:
|
|
var dir : Vector3 = hand.arm.prev_joint - hand.arm.next_joint
|
|
origin = hand.arm.next_joint + (dir.normalized() * original_arm_length)
|
|
var t : Transform3D = (Transform3D(base, origin) * rig_settings.bone_transform)
|
|
|
|
skeleton.set_bone_pose_rotation(bone_idx, t.basis.get_rotation_quaternion())
|
|
skeleton.set_bone_pose_position(bone_idx, t.origin)
|
|
#skeleton.set_bone_pose_scale(bone_idx, global_bone_scale)
|
|
|
|
return t
|
|
|
|
func set_palm(hand : UltraleapHand):
|
|
var palm_name : String = ex_map.get("palm")
|
|
|
|
var bone_idx : int = skeleton.find_bone(palm_name)
|
|
var base : Basis = Basis(hand.palm.orientation)
|
|
var origin : Vector3 = hand.palm.position
|
|
var t : Transform3D = Transform3D(base, origin) * rig_settings.bone_transform
|
|
|
|
skeleton.set_bone_pose_rotation(bone_idx, t.basis.get_rotation_quaternion())
|
|
skeleton.set_bone_pose_position(bone_idx, t.origin)
|
|
#skeleton.set_bone_pose_scale(bone_idx, global_bone_scale)
|
|
|
|
func set_wrist(hand : UltraleapHand):
|
|
var wrist_name : String = ex_map.get("wrist")
|
|
|
|
var bone_idx : int = skeleton.find_bone(wrist_name)
|
|
var t : Transform3D = transform_offset.inverse() * get_wrist_transform(hand)
|
|
|
|
skeleton.set_bone_pose_rotation(bone_idx, t.basis.get_rotation_quaternion())
|
|
skeleton.set_bone_pose_position(bone_idx, t.origin)
|
|
#skeleton.set_bone_pose_scale(bone_idx, global_bone_scale)
|
|
|
|
func set_finger(finger_name : String, hand : UltraleapHand):
|
|
if finger_name == "thumb":
|
|
set_metacarpal(finger_name, "proximal", hand.get(finger_name), get_wrist_transform(hand))
|
|
else:
|
|
set_metacarpal(finger_name, "metacarpal", hand.get(finger_name), get_wrist_transform(hand))
|
|
set_bone(finger_name, "proximal", "metacarpal", hand.get(finger_name))
|
|
set_bone(finger_name, "intermediate", "proximal", hand.get(finger_name))
|
|
set_bone(finger_name, "distal", "intermediate", hand.get(finger_name))
|
|
set_tip(finger_name, hand.get(finger_name))
|
|
|
|
func set_tip(finger_name : String, finger : UltraleapDigit):
|
|
var tip_name : String = ex_map.get(finger_name + "_tip")
|
|
|
|
if tip_name == "":
|
|
return
|
|
|
|
var prev_base : Basis = Basis(finger.get("distal").orientation)
|
|
var prev_origin : Vector3 = finger.get("distal").prev_joint
|
|
var prev_t : Transform3D = Transform3D(prev_base, prev_origin) * rig_settings.bone_transform
|
|
|
|
var base : Basis = Basis(finger.get("distal").orientation)
|
|
var origin : Vector3 = finger.get("distal").next_joint
|
|
var t : Transform3D = prev_t.inverse() * (Transform3D(base, origin) * rig_settings.bone_transform)
|
|
|
|
set_bone_rotation(ex_map.get(finger_name + "_tip"), t.basis.get_rotation_quaternion())
|
|
if rig_settings.set_joints_positions:
|
|
set_bone_position(ex_map.get(finger_name + "_tip"), t.origin)
|
|
#set_bone_scale(ex_map.get(finger_name + "_tip"), global_bone_scale)
|
|
|
|
func set_metacarpal(finger_name : String, bone_name : String, finger : UltraleapDigit, wrist : Transform3D):
|
|
var base : Basis = Basis(finger.get(bone_name).orientation)
|
|
var origin : Vector3 = finger.get(bone_name).prev_joint
|
|
var t : Transform3D = wrist.inverse() * Transform3D(base, origin) * rig_settings.bone_transform
|
|
|
|
set_bone_rotation(ex_map.get(finger_name + "_" + bone_name), t.basis.get_rotation_quaternion())
|
|
if rig_settings.set_joints_positions:
|
|
set_bone_position(ex_map.get(finger_name + "_" + bone_name), t.origin)
|
|
#set_bone_scale(ex_map.get(finger_name + "_" + bone_name), global_bone_scale)
|
|
|
|
func set_bone(finger_name : String, bone_name : String, prev_bone_name : String, finger : UltraleapDigit):
|
|
if (
|
|
finger.get(bone_name) == null
|
|
or ex_map.get(finger_name + "_" + bone_name) == ""
|
|
or ex_map.get(finger_name + "_" + prev_bone_name) == ""
|
|
):
|
|
return
|
|
|
|
var prev_base : Basis = Basis(finger.get(prev_bone_name).orientation)
|
|
var prev_origin : Vector3 = finger.get(prev_bone_name).prev_joint
|
|
var prev_t : Transform3D = Transform3D(prev_base, prev_origin) * rig_settings.bone_transform
|
|
|
|
var base : Basis = Basis(finger.get(bone_name).orientation)
|
|
var origin : Vector3 = finger.get(bone_name).prev_joint
|
|
var t : Transform3D = prev_t.inverse() * Transform3D(base, origin) * rig_settings.bone_transform
|
|
|
|
set_bone_rotation(ex_map.get(finger_name + "_" + bone_name), t.basis.get_rotation_quaternion())
|
|
if rig_settings.set_joints_positions:
|
|
set_bone_position(ex_map.get(finger_name + "_" + bone_name), t.origin)
|
|
#set_bone_scale(ex_map.get(finger_name + "_" + bone_name), global_bone_scale)
|
|
|
|
func set_bone_rotation(bone_name : String, bone_rotation : Quaternion):
|
|
var bone_idx : int = skeleton.find_bone(bone_name)
|
|
if bone_idx == -1:
|
|
return
|
|
skeleton.set_bone_pose_rotation(bone_idx, bone_rotation)
|
|
|
|
func set_bone_position(bone_name : String, bone_position : Vector3):
|
|
var bone_idx : int = skeleton.find_bone(bone_name)
|
|
if bone_idx == -1:
|
|
return
|
|
skeleton.set_bone_pose_position(bone_idx, bone_position)
|
|
|
|
func set_bone_scale(bone_name : String, bone_scale : Vector3):
|
|
var bone_idx : int = skeleton.find_bone(bone_name)
|
|
skeleton.set_bone_pose_scale(bone_idx, bone_scale)
|
|
|
|
func get_wrist_transform(hand : UltraleapHand) -> Transform3D:
|
|
var base : Basis = Basis(hand.palm.orientation)
|
|
var origin : Vector3 = hand.arm.next_joint
|
|
return Transform3D(base, origin) * rig_settings.bone_transform
|