142 lines
4.7 KiB
GDScript
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
|