Skip to content

Commit 05f6719

Browse files
committed
Add motion range support
1 parent 1c43d49 commit 05f6719

File tree

10 files changed

+145
-5
lines changed

10 files changed

+145
-5
lines changed

SConstruct

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ elif env['platform'] == "linux":
7474
target_path += "linux/"
7575
godot_cpp_library += '.linux'
7676

77+
# make sure we have access to the correct headers, cheating here a little.
78+
openxr_include_path += "openxr_loader_windows/1.0.16/include/"
79+
7780
# note, on linux the OpenXR SDK is installed in /usr and should be accessible
7881
if env['use_llvm']:
7982
env['CXX'] = 'clang++'

demo/Main.tscn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1, -0.5 )
114114

115115
[node name="Right_hand" parent="FPSController" instance=ExtResource( 5 )]
116116
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1, -0.5 )
117+
motion_range = 0
117118

118119
[node name="Table" parent="." instance=ExtResource( 3 )]
119120
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -6 )

demo/addons/godot-openxr/CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ Changes to the Godot OpenXR asset
33

44
1.0.1
55
-------------------
6-
- Fix crash issue on Oculus Link when taking headset off and putting it back on.
6+
- Fix crash issue on Oculus Link when taking headset off and putting it back on
7+
- Add support for finger tracking motion range
78

89
1.0.0
910
-------------------

demo/project.godot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ singletons=[ "res://addons/godot-openxr/godot_openxr.gdnlib" ]
3434

3535
Fire={
3636
"deadzone": 0.5,
37-
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
37+
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
3838
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
3939
]
4040
}

src/openxr/OpenXRApi.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ bool OpenXRApi::initialiseInstance() {
595595
if (isExtensionSupported(XR_EXT_HAND_TRACKING_EXTENSION_NAME, extensionProperties, extensionCount)) {
596596
Godot::print("- Hand tracking extension found");
597597
hand_tracking_ext = true;
598+
599+
if (isExtensionSupported(XR_EXT_HAND_JOINTS_MOTION_RANGE_EXTENSION_NAME, extensionProperties, extensionCount)) {
600+
Godot::print("- Hand motion range extension found");
601+
hand_motion_range_ext = true;
602+
}
598603
}
599604

600605
if (isExtensionSupported(XR_MND_BALL_ON_STICK_EXTENSION_NAME, extensionProperties, extensionCount)) {
@@ -618,6 +623,10 @@ bool OpenXRApi::initialiseInstance() {
618623
enabledExtensions[enabledExtensionCount++] = XR_EXT_HAND_TRACKING_EXTENSION_NAME;
619624
}
620625

626+
if (hand_motion_range_ext) {
627+
enabledExtensions[enabledExtensionCount++] = XR_EXT_HAND_JOINTS_MOTION_RANGE_EXTENSION_NAME;
628+
}
629+
621630
if (monado_stick_on_ball_ext) {
622631
enabledExtensions[enabledExtensionCount++] = XR_MND_BALL_ON_STICK_EXTENSION_NAME;
623632
}
@@ -1172,6 +1181,7 @@ bool OpenXRApi::initialiseHandTracking() {
11721181
for (int i = 0; i < 2; i++) {
11731182
XrHandTrackerCreateInfoEXT createInfo = {
11741183
.type = XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT,
1184+
.next = nullptr,
11751185
.hand = i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT,
11761186
.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT,
11771187
};
@@ -1363,8 +1373,8 @@ void OpenXRApi::uninitialize() {
13631373
view_pose_valid = false;
13641374
head_pose_valid = false;
13651375
hand_tracking_ext = false;
1376+
hand_motion_range_ext = false;
13661377
monado_stick_on_ball_ext = false;
1367-
hand_tracking_ext = false;
13681378
hand_tracking_supported = false;
13691379
initialised = false;
13701380
}
@@ -1373,6 +1383,30 @@ bool OpenXRApi::is_initialised() {
13731383
return initialised;
13741384
}
13751385

1386+
// hand tracking
1387+
const HandTracker *OpenXRApi::get_hand_tracker(uint32_t p_hand) const {
1388+
if (p_hand < MAX_TRACKED_HANDS) {
1389+
return &hand_trackers[p_hand];
1390+
} else {
1391+
return nullptr;
1392+
}
1393+
}
1394+
1395+
XrHandJointsMotionRangeEXT OpenXRApi::get_motion_range(uint32_t p_hand) const {
1396+
if (p_hand < MAX_TRACKED_HANDS) {
1397+
return hand_trackers[p_hand].motion_range;
1398+
} else {
1399+
// just return this as the default
1400+
return XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
1401+
}
1402+
}
1403+
1404+
void OpenXRApi::set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range) {
1405+
if (p_hand < MAX_TRACKED_HANDS) {
1406+
hand_trackers[p_hand].motion_range = p_motion_range;
1407+
}
1408+
}
1409+
13761410
// config
13771411
XrFormFactor OpenXRApi::get_form_factor() const {
13781412
return form_factor;
@@ -1997,9 +2031,19 @@ void OpenXRApi::update_handtracking() {
19972031
for (int i = 0; i < 2; i++) {
19982032
XrHandJointsLocateInfoEXT locateInfo = {
19992033
.type = XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT,
2034+
.next = nullptr,
20002035
.baseSpace = play_space,
20012036
.time = time,
20022037
};
2038+
XrHandJointsMotionRangeInfoEXT motionRangeInfo;
2039+
2040+
if (hand_motion_range_ext) {
2041+
motionRangeInfo.type = XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT;
2042+
motionRangeInfo.next = nullptr;
2043+
motionRangeInfo.handJointsMotionRange = hand_trackers[i].motion_range;
2044+
2045+
locateInfo.next = &motionRangeInfo;
2046+
}
20032047

20042048
result = xrLocateHandJointsEXT(hand_trackers[i].hand_tracker, &locateInfo, &hand_trackers[i].locations);
20052049
if (xr_result(result, "failed to get tracking for hand {0}!", i)) {

src/openxr/OpenXRApi.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ class OpenXRApi;
5858
#include "openxr/actions/actionset.h"
5959

6060
// TODO move hand tracker logic into it's own source files, I'll do a separate PR for that in due time.
61+
#define MAX_TRACKED_HANDS 2
62+
6163
class HandTracker {
6264
public:
6365
bool is_initialised = false;
66+
XrHandJointsMotionRangeEXT motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
6467

6568
XrHandTrackerEXT hand_tracker;
6669
XrHandJointLocationEXT joint_locations[XR_HAND_JOINT_COUNT_EXT];
@@ -153,6 +156,7 @@ class OpenXRApi {
153156

154157
// extensions
155158
bool hand_tracking_ext = false;
159+
bool hand_motion_range_ext = false;
156160
bool monado_stick_on_ball_ext = false;
157161
bool hand_tracking_supported = false;
158162

@@ -184,7 +188,7 @@ class OpenXRApi {
184188
bool view_pose_valid = false;
185189
bool head_pose_valid = false;
186190

187-
HandTracker hand_trackers[2]; // Fixed for left and right hand
191+
HandTracker hand_trackers[MAX_TRACKED_HANDS]; // Fixed for left and right hand
188192

189193
// config
190194
/*
@@ -257,7 +261,10 @@ class OpenXRApi {
257261
return false;
258262
};
259263

260-
const HandTracker *get_hand_tracker(int p_hand) { return &hand_trackers[p_hand]; };
264+
// hand tracking
265+
const HandTracker *get_hand_tracker(uint32_t p_hand) const;
266+
XrHandJointsMotionRangeEXT get_motion_range(uint32_t p_hand) const;
267+
void set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range);
261268

262269
// config
263270
XrFormFactor get_form_factor() const;

src/openxr/OpenXRHand.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ void OpenXRHand::_register_methods() {
1515
register_method("set_hand", &OpenXRHand::set_hand);
1616
register_property<OpenXRHand, int>("hand", &OpenXRHand::set_hand, &OpenXRHand::get_hand, 0, GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_ENUM, "Left,Right");
1717

18+
register_method("get_motion_range", &OpenXRHand::get_motion_range);
19+
register_method("set_motion_range", &OpenXRHand::set_motion_range);
20+
register_property<OpenXRHand, int>("motion_range", &OpenXRHand::set_motion_range, &OpenXRHand::get_motion_range, 0, GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_ENUM, "Unobstructed,Conform to controller");
21+
1822
register_method("is_active", &OpenXRHand::is_active);
1923
}
2024

2125
OpenXRHand::OpenXRHand() {
2226
hand = 0;
27+
motion_range = 0;
2328
openxr_api = OpenXRApi::openxr_get_api();
2429

2530
for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
@@ -74,6 +79,8 @@ void OpenXRHand::_ready() {
7479
printf("Couldn't obtain joint for %s\n", node_names[i]);
7580
}
7681
}
82+
83+
_set_motion_range();
7784
}
7885

7986
void OpenXRHand::_physics_process(float delta) {
@@ -176,3 +183,33 @@ int OpenXRHand::get_hand() const {
176183
void OpenXRHand::set_hand(int p_hand) {
177184
hand = p_hand == 1 ? 1 : 0;
178185
}
186+
187+
int OpenXRHand::get_motion_range() const {
188+
return motion_range;
189+
}
190+
191+
void OpenXRHand::set_motion_range(int p_motion_range) {
192+
motion_range = p_motion_range;
193+
_set_motion_range();
194+
}
195+
196+
void OpenXRHand::_set_motion_range() {
197+
if (openxr_api == NULL) {
198+
return;
199+
}
200+
201+
XrHandJointsMotionRangeEXT xr_motion_range;
202+
switch (motion_range) {
203+
case 0:
204+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
205+
break;
206+
case 1:
207+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
208+
break;
209+
default:
210+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
211+
break;
212+
}
213+
214+
openxr_api->set_motion_range(hand, xr_motion_range);
215+
}

src/openxr/OpenXRHand.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ class OpenXRHand : public Spatial {
1515
private:
1616
OpenXRApi *openxr_api;
1717
int hand;
18+
int motion_range;
1819

1920
Spatial *joints[XR_HAND_JOINT_COUNT_EXT];
21+
void _set_motion_range();
2022

2123
public:
2224
static void _register_methods();
@@ -32,6 +34,9 @@ class OpenXRHand : public Spatial {
3234

3335
int get_hand() const;
3436
void set_hand(int p_hand);
37+
38+
int get_motion_range() const;
39+
void set_motion_range(int p_motion_range);
3540
};
3641
} // namespace godot
3742

src/openxr/OpenXRSkeleton.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ void OpenXRSkeleton::_register_methods() {
1414
register_method("get_hand", &OpenXRSkeleton::get_hand);
1515
register_method("set_hand", &OpenXRSkeleton::set_hand);
1616
register_property<OpenXRSkeleton, int>("hand", &OpenXRSkeleton::set_hand, &OpenXRSkeleton::get_hand, 0, GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_ENUM, "Left,Right");
17+
18+
register_method("get_motion_range", &OpenXRSkeleton::get_motion_range);
19+
register_method("set_motion_range", &OpenXRSkeleton::set_motion_range);
20+
register_property<OpenXRSkeleton, int>("motion_range", &OpenXRSkeleton::set_motion_range, &OpenXRSkeleton::get_motion_range, 0, GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_ENUM, "Unobstructed,Conform to controller");
1721
}
1822

1923
OpenXRSkeleton::OpenXRSkeleton() {
2024
hand = 0;
25+
motion_range = 0;
2126
openxr_api = OpenXRApi::openxr_get_api();
2227

2328
for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
@@ -79,6 +84,8 @@ void OpenXRSkeleton::_ready() {
7984
Godot::print("Couldn't obtain bone for {0}", bone_name);
8085
}
8186
}
87+
88+
_set_motion_range();
8289
}
8390

8491
void OpenXRSkeleton::_physics_process(float delta) {
@@ -149,3 +156,33 @@ int OpenXRSkeleton::get_hand() const {
149156
void OpenXRSkeleton::set_hand(int p_hand) {
150157
hand = p_hand == 1 ? 1 : 0;
151158
}
159+
160+
int OpenXRSkeleton::get_motion_range() const {
161+
return motion_range;
162+
}
163+
164+
void OpenXRSkeleton::set_motion_range(int p_motion_range) {
165+
motion_range = p_motion_range;
166+
_set_motion_range();
167+
}
168+
169+
void OpenXRSkeleton::_set_motion_range() {
170+
if (openxr_api == NULL) {
171+
return;
172+
}
173+
174+
XrHandJointsMotionRangeEXT xr_motion_range;
175+
switch (motion_range) {
176+
case 0:
177+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
178+
break;
179+
case 1:
180+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
181+
break;
182+
default:
183+
xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
184+
break;
185+
}
186+
187+
openxr_api->set_motion_range(hand, xr_motion_range);
188+
}

src/openxr/OpenXRSkeleton.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ class OpenXRSkeleton : public Skeleton {
1515
private:
1616
OpenXRApi *openxr_api;
1717
int hand;
18+
int motion_range;
1819

1920
int64_t bones[XR_HAND_JOINT_COUNT_EXT];
21+
void _set_motion_range();
2022

2123
public:
2224
static void _register_methods();
@@ -30,6 +32,9 @@ class OpenXRSkeleton : public Skeleton {
3032

3133
int get_hand() const;
3234
void set_hand(int p_hand);
35+
36+
int get_motion_range() const;
37+
void set_motion_range(int p_motion_range);
3338
};
3439
} // namespace godot
3540

0 commit comments

Comments
 (0)