Skip to content

Commit 914eba9

Browse files
committed
Added controller pose type.
1 parent f5c7402 commit 914eba9

File tree

5 files changed

+171
-26
lines changed

5 files changed

+171
-26
lines changed

VERSIONS.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 1.2.0 (in progress)
22
- Added hand pose controller capable of generating XR input actions
33
- Added debounce hold and release times for poses
4+
- Added controller pose type [skeleton, aim, grab]
45

56
# 1.1.0
67
- Moved fitness function to separate resource

addons/hand_pose_detector/hand_pose_controller.gd

+89-11
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,60 @@ extends Node
88
## This script creates an XRControllerTracker moved by an associated
99
## HandPoseDetector, and capable of generating XR Input Actions in response
1010
## to detected hand poses.
11+
##
12+
## The XRControllerTracker will have a "default" pose whose position is based
13+
## on the tracked hand and the selected pose_type.
14+
15+
16+
## Pose Type
17+
enum PoseType {
18+
SKELETON, ## Skeleton pose (palm pose)
19+
AIM, ## Aim pose (aiming pose)
20+
GRIP ## Grip pose (gripping pose)
21+
}
22+
23+
# Table of left-hand pose transforms by PoseType
24+
const _POSE_TRANSFORMS_LEFT : Array[Transform3D] = [
25+
# Skeleton-pose (identity)
26+
Transform3D(
27+
Basis.IDENTITY,
28+
Vector3.ZERO),
29+
30+
# Aim pose - see OpenXR specification
31+
Transform3D(
32+
Basis(Quaternion(0.4304593, -0.5609855, 0.4304593, 0.5609855)),
33+
Vector3(-0.03, 0.08, 0.025)),
34+
35+
# Grip pose - see OpenXR specification
36+
Transform3D(
37+
Basis(Quaternion(0.6408564, -0.2988362, 0.6408564, 0.2988362)),
38+
Vector3(0.0, 0.0, 0.025))
39+
]
40+
41+
# Table of right-hand pose transforms by PoseType
42+
const _POSE_TRANSFORMS_RIGHT : Array[Transform3D] = [
43+
# Skeleton-pose (identity)
44+
Transform3D(
45+
Basis.IDENTITY,
46+
Vector3.ZERO),
47+
48+
# Aim pose - see OpenXR specification
49+
Transform3D(
50+
Basis(Quaternion(0.4304593, 0.5609855, -0.4304593, 0.5609855)),
51+
Vector3(0.03, 0.08, 0.025)),
52+
53+
# Grip pose - see OpenXR specification
54+
Transform3D(
55+
Basis(Quaternion(-0.6408564, -0.2988362, 0.6408564, -0.2988362)),
56+
Vector3(0.0, 0.0, 0.025))
57+
]
1158

1259

1360
## Name for the virtual controller tracker
1461
@export var tracker_name : String = "/user/hand_pose_controller/left"
1562

16-
## Pose name
17-
@export var pose_name : String = &"default"
63+
## Pose type
64+
@export var pose_type : PoseType = PoseType.SKELETON
1865

1966
## Hand poses generating boolean values
2067
@export var action_set : HandPoseActionSet
@@ -56,17 +103,33 @@ func _process(_delta: float) -> void:
56103
if not pose_detector.tracker or not tracker:
57104
return
58105

59-
# Get the tracker pose
60-
var pose := pose_detector.tracker.get_pose(pose_name)
106+
# Get the hand tracker pose
107+
var pose := pose_detector.tracker.get_pose(&"default")
61108
if not pose:
62109
return
63110

111+
# Get the conversion transform
112+
var hand := pose_detector.tracker.hand
113+
114+
# Get the conversion transform
115+
var conv_xform : Transform3D
116+
if hand == XRPositionalTracker.TrackerHand.TRACKER_HAND_LEFT:
117+
conv_xform = _POSE_TRANSFORMS_LEFT[pose_type]
118+
else:
119+
conv_xform = _POSE_TRANSFORMS_RIGHT[pose_type]
120+
121+
# Apply conversion to pose components
122+
var pose_transform := pose.transform * conv_xform
123+
var pose_linear := pose.linear_velocity * conv_xform.basis
124+
var pose_angular := _rotate_angular_velocity(pose.angular_velocity, conv_xform.basis)
125+
64126
# Update the controller tracker pose
127+
tracker.hand = hand
65128
tracker.set_pose(
66129
pose.name,
67-
pose.transform,
68-
pose.linear_velocity,
69-
pose.angular_velocity,
130+
pose_transform,
131+
pose_linear,
132+
pose_angular,
70133
pose.tracking_confidence)
71134

72135

@@ -85,10 +148,6 @@ func _get_configuration_warnings() -> PackedStringArray:
85148
if tracker_name == "":
86149
warnings.append("Tracker name not set")
87150

88-
# Verify pose name is set
89-
if pose_name == "":
90-
warnings.append("Pose name not set")
91-
92151
# Verify parent pose
93152
var parent_pose_detector := get_parent() as HandPoseDetector
94153
if not parent_pose_detector:
@@ -132,3 +191,22 @@ func _pose_ended(p_name : String) -> void:
132191
tracker.set_input(action.action_name, false)
133192
else:
134193
tracker.set_input(action.action_name, 0.0)
194+
195+
196+
# Returns an angular velocity rotated by the given basis matrix.
197+
static func _rotate_angular_velocity(vel : Vector3, basis : Basis) -> Vector3:
198+
# Get the angular velocity length
199+
var len := vel.length()
200+
if is_zero_approx(len):
201+
return Vector3.ZERO
202+
203+
# Normalize the angular velocity
204+
vel /= len
205+
206+
# Rotate the angular velocity using quaternion composition
207+
var vel_quat := Quaternion.from_euler(vel)
208+
vel_quat *= basis.get_rotation_quaternion()
209+
vel = vel_quat.get_euler()
210+
211+
# Scale the angular velocity back to the appropriate magnitude
212+
return vel * len

addons/hand_pose_detector/poses/point.tres

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@ max = 0.0
1515
script = ExtResource("2_kgqxd")
1616
type = 0
1717
min = 0.0
18-
from = 90.0
19-
to = 130.0
18+
from = 80.0
19+
to = 110.0
2020
max = 0.0
2121

2222
[sub_resource type="Resource" id="Resource_ngpot"]
2323
script = ExtResource("2_kgqxd")
2424
type = 0
2525
min = 0.0
26-
from = 90.0
27-
to = 130.0
26+
from = 80.0
27+
to = 110.0
2828
max = 0.0
2929

3030
[sub_resource type="Resource" id="Resource_kbi8m"]
3131
script = ExtResource("2_kgqxd")
3232
type = 0
3333
min = 0.0
34-
from = 90.0
35-
to = 130.0
34+
from = 80.0
35+
to = 110.0
3636
max = 0.0
3737

3838
[sub_resource type="Resource" id="Resource_3xngl"]

addons/hand_pose_detector/poses/point_thumb_up.tres

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,24 @@ max = 0.0
2323
script = ExtResource("2_0x328")
2424
type = 0
2525
min = 0.0
26-
from = 90.0
27-
to = 130.0
26+
from = 80.0
27+
to = 110.0
2828
max = 0.0
2929

3030
[sub_resource type="Resource" id="Resource_nqpii"]
3131
script = ExtResource("2_0x328")
3232
type = 0
3333
min = 0.0
34-
from = 90.0
35-
to = 130.0
34+
from = 80.0
35+
to = 110.0
3636
max = 0.0
3737

3838
[sub_resource type="Resource" id="Resource_1ygpc"]
3939
script = ExtResource("2_0x328")
4040
type = 0
4141
min = 0.0
42-
from = 90.0
43-
to = 130.0
42+
from = 80.0
43+
to = 110.0
4444
max = 0.0
4545

4646
[sub_resource type="Resource" id="Resource_yunfv"]
@@ -55,8 +55,8 @@ max = 0.0
5555
script = ExtResource("2_0x328")
5656
type = 0
5757
min = 0.0
58-
from = 40.0
59-
to = 20.0
58+
from = 50.0
59+
to = 40.0
6060
max = 0.0
6161

6262
[resource]

demo.tscn

+67-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
[gd_scene load_steps=9 format=3 uid="uid://y0j46ct8rv7f"]
1+
[gd_scene load_steps=18 format=3 uid="uid://y0j46ct8rv7f"]
22

33
[ext_resource type="Script" path="res://demo.gd" id="1_3t01i"]
44
[ext_resource type="PackedScene" uid="uid://cjcehqrfoxav3" path="res://assets/gltf/LeftHandHumanoid.gltf" id="2_qj6xm"]
55
[ext_resource type="PackedScene" uid="uid://df5hynbooj1uj" path="res://addons/hand_pose_detector/hand_pose_detector.tscn" id="3_sea3p"]
66
[ext_resource type="Resource" uid="uid://ckjd0xa2a240p" path="res://addons/hand_pose_detector/poses/standard_pose_set.tres" id="4_aw253"]
77
[ext_resource type="PackedScene" uid="uid://dabmoo0spa6vg" path="res://assets/gltf/RightHandHumanoid.gltf" id="4_uvuof"]
8+
[ext_resource type="PackedScene" uid="uid://bh8isvqs258cp" path="res://addons/hand_pose_detector/hand_pose_controller.tscn" id="5_0abgo"]
9+
[ext_resource type="Script" path="res://addons/hand_pose_detector/hand_pose_action.gd" id="7_ownji"]
10+
[ext_resource type="Resource" uid="uid://ra50ueubhepa" path="res://addons/hand_pose_detector/poses/point_thumb_up.tres" id="8_pcf64"]
11+
[ext_resource type="Script" path="res://addons/hand_pose_detector/hand_pose_action_set.gd" id="9_ux58f"]
812

913
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_gp80n"]
1014
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
@@ -18,6 +22,40 @@ background_mode = 2
1822
sky = SubResource("Sky_wwtaq")
1923
tonemap_mode = 2
2024

25+
[sub_resource type="Resource" id="Resource_0u7th"]
26+
script = ExtResource("7_ownji")
27+
pose = ExtResource("8_pcf64")
28+
action_type = 0
29+
action_name = "point_thumb_up"
30+
31+
[sub_resource type="Resource" id="Resource_0mgap"]
32+
script = ExtResource("9_ux58f")
33+
actions = Array[ExtResource("7_ownji")]([SubResource("Resource_0u7th")])
34+
35+
[sub_resource type="GDScript" id="GDScript_tpxpg"]
36+
script/source = "extends XRController3D
37+
38+
39+
# Called every frame. 'delta' is the elapsed time since the previous frame.
40+
func _process(_delta: float) -> void:
41+
$Aim.visible = is_button_pressed(\"point_thumb_up\")
42+
"
43+
44+
[sub_resource type="CapsuleMesh" id="CapsuleMesh_oevpt"]
45+
radius = 0.01
46+
height = 0.05
47+
radial_segments = 6
48+
rings = 3
49+
50+
[sub_resource type="GDScript" id="GDScript_xq4qg"]
51+
script/source = "extends XRController3D
52+
53+
54+
# Called every frame. 'delta' is the elapsed time since the previous frame.
55+
func _process(_delta: float) -> void:
56+
$Aim.visible = is_button_pressed(\"point_thumb_up\")
57+
"
58+
2159
[node name="Demo" type="Node3D"]
2260
script = ExtResource("1_3t01i")
2361
@@ -45,6 +83,11 @@ show_when_tracked = true
4583
[node name="LeftHandPose" parent="XROrigin3D/LeftTrackedHand" instance=ExtResource("3_sea3p")]
4684
hand_pose_set = ExtResource("4_aw253")
4785
86+
[node name="LeftHandPoseController" parent="XROrigin3D/LeftTrackedHand/LeftHandPose" instance=ExtResource("5_0abgo")]
87+
tracker_name = "/user/hand_pose_controller/left"
88+
pose_type = 1
89+
action_set = SubResource("Resource_0mgap")
90+
4891
[node name="RightTrackedHand" type="XRNode3D" parent="XROrigin3D"]
4992
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 1, 0)
5093
tracker = &"/user/hand_tracker/right"
@@ -59,6 +102,29 @@ hand_tracker = &"/user/hand_tracker/right"
59102
hand_pose_set = ExtResource("4_aw253")
60103
tracker_name = "/user/hand_tracker/right"
61104
105+
[node name="RightHandPoseController" parent="XROrigin3D/RightTrackedHand/RightHandPose" instance=ExtResource("5_0abgo")]
106+
tracker_name = "/user/hand_pose_controller/right"
107+
pose_type = 1
108+
action_set = SubResource("Resource_0mgap")
109+
110+
[node name="LeftPoseController" type="XRController3D" parent="XROrigin3D"]
111+
tracker = &"/user/hand_pose_controller/left"
112+
script = SubResource("GDScript_tpxpg")
113+
114+
[node name="Aim" type="MeshInstance3D" parent="XROrigin3D/LeftPoseController"]
115+
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
116+
visible = false
117+
mesh = SubResource("CapsuleMesh_oevpt")
118+
119+
[node name="RightPoseController" type="XRController3D" parent="XROrigin3D"]
120+
tracker = &"/user/hand_pose_controller/right"
121+
script = SubResource("GDScript_xq4qg")
122+
123+
[node name="Aim" type="MeshInstance3D" parent="XROrigin3D/RightPoseController"]
124+
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
125+
visible = false
126+
mesh = SubResource("CapsuleMesh_oevpt")
127+
62128
[node name="LeftHandLabel" type="Label3D" parent="."]
63129
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2, -3)
64130
text = "Left Hand"

0 commit comments

Comments
 (0)