godot-ultraleap-plugin/demo/scripts/DebugHands.gd

142 lines
4.7 KiB
GDScript

class_name DebugHands
extends Node3D
@export var tracking : UltraleapDevice
@export var hide_non_visible_hands : bool = true
@export var use_interpolated_frames : bool = false
var frame : UltraleapFrame
var colours : Dictionary = {
"red": "E40303",
"orange": "FF8C00",
"yellow": "FFED00",
"green": "008026",
"indigo": "24408E",
"violet": "732982"
}
var finger_names : Array = [
"Thumb",
"Index",
"Middle",
"Ring",
"Pinky"
]
func _ready():
# If we want to use signals (is it still working actually?)
#tracking.frame_received.connect(on_frame_received)
pass
func _process(_delta):
if tracking == null:
get_node("LeftHand").hide()
get_node("RightHand").hide()
return
frame = get_frame_from_device()
if frame == null:
return
if (!frame.is_left_hand_visible && get_node("LeftHand").visible && hide_non_visible_hands):
get_node("LeftHand").hide()
elif (frame.is_left_hand_visible):
if (!get_node("LeftHand").visible):
get_node("LeftHand").show()
set_hand_transform(frame.left_hand, UltraleapTypes.Chirality.Left)
if (!frame.is_right_hand_visible && get_node("RightHand").visible && hide_non_visible_hands):
get_node("RightHand").hide()
elif (frame.is_right_hand_visible):
if (!get_node("RightHand").visible):
get_node("RightHand").show()
set_hand_transform(frame.right_hand, UltraleapTypes.Chirality.Right)
if Input.is_action_just_pressed("save_pose"):
print("Saving pose")
var error = ResourceSaver.save(frame.left_hand, "res://LeftHandPose.tres")
if error != OK:
printerr("Failure saving a hand pose")
error = ResourceSaver.save(frame.right_hand, "res://RightHandPose.tres")
if error != OK:
printerr("Failure saving a hand pose")
func get_frame_from_device():
if not use_interpolated_frames:
return tracking.get_last_frame()
var f : UltraleapFrame = tracking.get_interpolated_frame(Time.get_ticks_usec())
if f == null:
return tracking.get_last_frame()
return f
func set_hand_transform(hand : UltraleapHand, chirality : UltraleapTypes.Chirality):
var chirality_str = chirality_to_str(chirality)
var hand_root = get_node(chirality_str + "Hand") as Node3D
var arm = hand_root.get_node(chirality_str + "Arm")
set_bone_transform(hand.arm, arm, colours["violet"])
for i in range(5):
set_finger_transform(hand.digits[i], chirality, finger_names[i], hand_root, colours.values()[i])
# Below shows how this can be done by accessing individual fingers instead of iterating
# set_finger_transform(hand.thumb, chirality, "Thumb", hand_root, colours["red"])
# set_finger_transform(hand.index, chirality, "Index", hand_root, colours["orange"])
# set_finger_transform(hand.middle, chirality, "Middle", hand_root, colours["yellow"])
# set_finger_transform(hand.ring, chirality, "Ring", hand_root, colours["green"])
# set_finger_transform(hand.pinky, chirality, "Pinky", hand_root, colours["indigo"])
func set_finger_transform(digit : UltraleapDigit, chirality : UltraleapTypes.Chirality, finger : String, node : Node3D, colour : Color = Color("ffffff")):
var chirality_str = chirality_to_str(chirality)
var palm = node.get_node(chirality_str + "Palm")
var metacarpal = palm.get_node(chirality_str + finger + "Metacarpal")
var proximal = metacarpal.get_node(chirality_str + finger + "Proximal")
var intermediate = proximal.get_node(chirality_str + finger + "Intermediate")
var distal = intermediate.get_node(chirality_str + finger + "Distal")
set_bone_transform(digit.metacarpal, metacarpal, colour)
set_bone_transform(digit.proximal, proximal, colour)
set_bone_transform(digit.intermediate, intermediate, colour)
set_bone_transform(digit.distal, distal, colour)
func set_bone_transform(bone : UltraleapBone, model : Node3D, colour : Color = Color("ffffff")):
var pos = (bone.next_joint + bone.prev_joint) / 2
var length = (bone.next_joint - bone.prev_joint).length()
var transform_m : Transform3D = Transform3D(global_transform)
model.global_position = transform_m * pos
# Multiply by quaternion, which is this object orientation, to rotate the hands
model.global_rotation = (quaternion * bone.orientation * Quaternion(Vector3.RIGHT, deg_to_rad(90))).get_euler()
var mesh
var material
if model is CSGBox3D:
mesh = model
material = (mesh.material as StandardMaterial3D)
if model is MeshInstance3D:
mesh = model.mesh
material = model.mesh.material
if mesh is CapsuleMesh:
mesh.radius = bone.width / 2
mesh.height = length + (mesh.radius * 2)
else:
mesh.size.x = bone.width
mesh.size.z = length
mesh.size.y = 0.01
material.albedo_color = colour
func chirality_to_str(chirality : UltraleapTypes.Chirality):
return "Left" if chirality == UltraleapTypes.Left else "Right"
func on_frame_received(received_frame : UltraleapFrame):
frame = received_frame