Skip to content

Commit

Permalink
Add API for accessing tracking confidence
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Jan 30, 2022
1 parent bfac042 commit 0d2ea91
Show file tree
Hide file tree
Showing 14 changed files with 158 additions and 29 deletions.
17 changes: 17 additions & 0 deletions demo/ControllerInfo.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
extends Node2D

var controller : ARVRController = null;
var configuration

# Called when the node enters the scene tree for the first time.
func _ready():
# a little dirty but the parent of the parent of the parent should be the controller.
controller = get_node("../../../");

# we should be able to grab copy of our config
configuration = preload("res://addons/godot-openxr/config/OpenXRConfig.gdns")
if configuration:
configuration = configuration.new()

func _process(_delta : float):
if controller:
var trigger = controller.get_joystick_axis(JOY_VR_ANALOG_TRIGGER)
Expand All @@ -33,3 +39,14 @@ func _process(_delta : float):
$Container/SelectButton/Value.pressed = controller.is_button_pressed(JOY_BUTTON_4)
$Container/TriggerButton/Value.pressed = controller.is_button_pressed(JOY_VR_TRIGGER)
$Container/SideButton/Value.pressed = controller.is_button_pressed(JOY_VR_GRIP)

if configuration:
var confidence = configuration.get_tracking_confidence(controller.controller_id)
if confidence == 0:
$Container/Tracking.text = "Not tracking"
elif confidence == 1:
$Container/Tracking.text = "Low confidence"
elif confidence == 2:
$Container/Tracking.text = "High confidence"
else:
$Container/Tracking.text = "Unknown tracking status"
7 changes: 7 additions & 0 deletions demo/ControllerInfo.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,10 @@ margin_right = 198.0
margin_bottom = 32.0
custom_fonts/font = ExtResource( 2 )
text = "Side button/Grip"

[node name="Tracking" type="Label" parent="Container"]
margin_top = 310.0
margin_right = 500.0
margin_bottom = 342.0
custom_fonts/font = ExtResource( 2 )
text = "Tracking state"
14 changes: 14 additions & 0 deletions demo/Main.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ refresh_rate = 0.0
transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, -0.0187781, 0.103895 )
layers = 524288
mesh = SubResource( 1 )
material/0 = null

[node name="ShadowHMD" type="MeshInstance" parent="FPSController/ARVRCamera" index="1"]
transform = Transform( -1.62921e-07, 0, 1, 0, 1, 0, -1, 0, -1.62921e-07, 1.44924e-09, 0, 0.00889538 )
layers = 524288
mesh = SubResource( 2 )
material/0 = null

[node name="LeftHandController" parent="FPSController" index="2"]
visible = true
Expand Down Expand Up @@ -104,39 +106,51 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1, -0.5 )
[node name="Grip" type="MeshInstance" parent="FPSController/Left_grip_pose"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 0, 0 )
mesh = SubResource( 3 )
material/0 = null

[node name="Right_aim_pose" parent="FPSController" instance=ExtResource( 7 )]

[node name="Grip" type="MeshInstance" parent="FPSController/Right_aim_pose"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 0, 0 )
mesh = SubResource( 3 )
material/0 = null

[node name="LeftHand" parent="FPSController" instance=ExtResource( 14 )]
motion_range = 1

[node name="Skeleton" parent="FPSController/LeftHand/HandModel/Armature001" index="0"]
bones/9/bound_children = [ ]
motion_range = 1

[node name="vr_glove_left_slim" parent="FPSController/LeftHand/HandModel/Armature001/Skeleton" index="0"]
material/0 = null

[node name="IndexTip" parent="FPSController/LeftHand/HandModel/Armature001/Skeleton" index="1"]
transform = Transform( 0.19221, -0.669965, -0.717079, 0.977075, 0.19881, 0.076153, 0.0915428, -0.715277, 0.692819, 0.0345973, 0.0355402, -0.164767 )

[node name="ShowIndexTip" type="MeshInstance" parent="FPSController/LeftHand/HandModel/Armature001/Skeleton/IndexTip" index="0"]
visible = false
mesh = SubResource( 4 )
material/0 = null

[node name="RightHand" parent="FPSController" instance=ExtResource( 15 )]
motion_range = 1
albedo_texture = ExtResource( 5 )

[node name="Skeleton" parent="FPSController/RightHand/HandModel/Armature" index="0"]
bones/9/bound_children = [ ]
motion_range = 1

[node name="vr_glove_right_slim" parent="FPSController/RightHand/HandModel/Armature/Skeleton" index="0"]
material/0 = null

[node name="IndexTip" parent="FPSController/RightHand/HandModel/Armature/Skeleton" index="1"]
transform = Transform( 0.19221, 0.669966, 0.717078, -0.091543, -0.715277, 0.69282, 0.977075, -0.19881, -0.0761527, -0.0345978, -0.164767, -0.0355401 )

[node name="ShowIndexTip" type="MeshInstance" parent="FPSController/RightHand/HandModel/Armature/Skeleton/IndexTip" index="0"]
visible = false
mesh = SubResource( 4 )
material/0 = null

[node name="ShowBounds" parent="FPSController" instance=ExtResource( 16 )]
configuration = NodePath("../Configuration")
Expand Down
1 change: 1 addition & 0 deletions demo/addons/godot-openxr/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changes to the Godot OpenXR asset
- Added interaction profile for the HP Reverb G2 controllers.
- Removed deprecated `com.samsung.android.vr.application.mode` meta-data tag.
- Updated repo `README`.
- Added controller tracking confidence

1.1.1
-------------------
Expand Down
10 changes: 10 additions & 0 deletions src/gdclasses/OpenXRConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void OpenXRConfig::_register_methods() {

register_method("get_enabled_extensions", &OpenXRConfig::get_enabled_extensions);

register_method("get_tracking_confidence", &OpenXRConfig::get_tracking_confidence);

register_method("get_action_sets", &OpenXRConfig::get_action_sets);
register_method("set_action_sets", &OpenXRConfig::set_action_sets);
register_property<OpenXRConfig, String>("action_sets", &OpenXRConfig::set_action_sets, &OpenXRConfig::get_action_sets, String(OpenXRApi::default_action_sets_json), GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_MULTILINE_TEXT);
Expand Down Expand Up @@ -214,6 +216,14 @@ godot::Array OpenXRConfig::get_enabled_extensions() const {
}
}

int OpenXRConfig::get_tracking_confidence(const int p_godot_controller) const {
int confidence = 0;
if (openxr_api) {
confidence = int(openxr_api->get_controller_tracking_confidence(p_godot_controller));
}
return confidence;
}

String OpenXRConfig::get_action_sets() const {
if (openxr_api == NULL) {
return String();
Expand Down
2 changes: 2 additions & 0 deletions src/gdclasses/OpenXRConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class OpenXRConfig : public Node {

godot::Array get_enabled_extensions() const;

int get_tracking_confidence(const int p_godot_controller) const;

String get_action_sets() const;
void set_action_sets(const String p_action_sets);

Expand Down
3 changes: 2 additions & 1 deletion src/gdclasses/OpenXRHand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ void OpenXRHand::_physics_process(float delta) {

if (hand_tracker->is_initialised && hand_tracker->locations.isActive) {
for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
Transform t = openxr_api->transform_from_space_location(hand_tracker->joint_locations[i], ws);
Transform t;
openxr_api->transform_from_location(hand_tracker->joint_locations[i], ws, t);
// store the inverse to make live easier later on
inv_transforms[i] = t.inverse();

Expand Down
16 changes: 13 additions & 3 deletions src/gdclasses/OpenXRPose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,19 @@ void OpenXRPose::_physics_process(float delta) {
if (action == "SkeletonBase") {
if (path == "/user/hand/left") {
const HandTracker *hand_tracker = hand_tracking_wrapper->get_hand_tracker(0);
set_transform(reference_frame * openxr_api->transform_from_space_location(hand_tracker->joint_locations[XR_HAND_JOINT_PALM_EXT], ws));
Transform t;
confidence = openxr_api->transform_from_location(hand_tracker->joint_locations[XR_HAND_JOINT_PALM_EXT], ws, t);
set_transform(reference_frame * t);
} else if (path == "/user/hand/right") {
const HandTracker *hand_tracker = hand_tracking_wrapper->get_hand_tracker(1);
set_transform(reference_frame * openxr_api->transform_from_space_location(hand_tracker->joint_locations[XR_HAND_JOINT_PALM_EXT], ws));
Transform t;
confidence = openxr_api->transform_from_location(hand_tracker->joint_locations[XR_HAND_JOINT_PALM_EXT], ws, t);
set_transform(reference_frame * t);
}
} else if (check_action_and_path()) {
set_transform(reference_frame * _action->get_as_pose(_path, ws));
Transform t;
confidence = _action->get_as_pose(_path, ws, t);
set_transform(reference_frame * t);
}
}

Expand Down Expand Up @@ -196,3 +202,7 @@ void OpenXRPose::set_path(const String p_path) {
_path = XR_NULL_PATH;
fail_cache = false;
}

int OpenXRPose::get_tracking_confidence() const {
return int(confidence);
}
3 changes: 3 additions & 0 deletions src/gdclasses/OpenXRPose.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class OpenXRPose : public Spatial {

private:
OpenXRApi *openxr_api;
TrackingConfidence confidence = TRACKING_CONFIDENCE_NONE;
XRExtHandTrackingExtensionWrapper *hand_tracking_wrapper = nullptr;
bool invisible_if_inactive = true;
String action;
Expand Down Expand Up @@ -44,6 +45,8 @@ class OpenXRPose : public Spatial {

String get_path() const;
void set_path(const String p_path);

int get_tracking_confidence() const;
};
} // namespace godot

Expand Down
2 changes: 1 addition & 1 deletion src/gdclasses/OpenXRSkeleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void OpenXRSkeleton::_physics_process(float delta) {
if (hand_tracker->is_initialised && hand_tracker->locations.isActive) {
// get our transforms
for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
transforms[i] = openxr_api->transform_from_space_location(hand_tracker->joint_locations[i], ws);
openxr_api->transform_from_location(hand_tracker->joint_locations[i], ws, transforms[i]);
inv_transforms[i] = transforms[i].inverse();
}

Expand Down
69 changes: 60 additions & 9 deletions src/openxr/OpenXRApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2151,6 +2151,16 @@ godot::Array OpenXRApi::get_enabled_extensions() const {
return arr;
}

TrackingConfidence OpenXRApi::get_controller_tracking_confidence(const int p_godot_controller) const {
for (int i = 0; i < USER_INPUT_MAX; i++) {
if (inputmaps[i].godot_controller == p_godot_controller) {
return inputmaps[i].tracking_confidence;
}
}

return TRACKING_CONFIDENCE_NONE;
}

godot::String OpenXRApi::get_action_sets_json() const {
return action_sets_json;
}
Expand Down Expand Up @@ -2738,7 +2748,7 @@ void OpenXRApi::update_actions() {
// Start with our pose, we put our ARVRController on our aim pose (may need to change this to our grip pose...)
godot_transform controller_transform;
Transform *t = (Transform *)&controller_transform;
*t = default_actions[ACTION_AIM_POSE].action->get_as_pose(input_path, ws);
inputmaps[i].tracking_confidence = default_actions[ACTION_AIM_POSE].action->get_as_pose(input_path, ws, *t);

arvr_api->godot_arvr_set_controller_transform(godot_controller, &controller_transform, true, true);

Expand Down Expand Up @@ -3207,24 +3217,65 @@ Transform OpenXRApi::transform_from_pose(const XrPosef &p_pose, float p_world_sc
}

template <typename T>
Transform _transform_from_space_location(OpenXRApi &api, const T &p_location, float p_world_scale) {
TrackingConfidence _transform_from_location(const T &p_location, Transform &r_transform) {
Basis basis;
Vector3 origin;
TrackingConfidence confidence = TRACKING_CONFIDENCE_NONE;
const auto &pose = p_location.pose;

// Check orientation
if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
Quat q(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w);
basis = Basis(q);
r_transform.basis = Basis(q);

if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) {
// Fully valid orientation, so either 3DOF or 6DOF tracking with high confidence so default to HIGH_TRACKING
confidence = TRACKING_CONFIDENCE_HIGH;
} else {
// Orientation is being tracked but we're using old/predicted data, so low tracking confidence
confidence = TRACKING_CONFIDENCE_LOW;
}
} else {
r_transform.basis = Basis();
}

// Check location
if (p_location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) {
origin = Vector3(pose.position.x, pose.position.y, pose.position.z) * p_world_scale;
r_transform.origin = Vector3(pose.position.x, pose.position.y, pose.position.z);

if (!(p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT)) {
// Location is being tracked but we're using old/predicted data, so low tracking confidence
confidence = TRACKING_CONFIDENCE_LOW;
} else if (confidence == TRACKING_CONFIDENCE_NONE) {
// Position tracking without orientation tracking?
confidence = TRACKING_CONFIDENCE_HIGH;
}
} else {
// No tracking or 3DOF I guess..
r_transform.origin = Vector3();
}
return Transform(basis, origin);

return confidence;
}

Transform OpenXRApi::transform_from_space_location(const XrSpaceLocation &p_location, float p_world_scale) {
return _transform_from_space_location(*this, p_location, p_world_scale);
TrackingConfidence OpenXRApi::transform_from_location(const XrSpaceLocation &p_location, float p_world_scale, Transform &r_transform) {
Transform t;
TrackingConfidence confidence = _transform_from_location(p_location, t);
if (confidence != TRACKING_CONFIDENCE_NONE) {
// only update if we have tracking data
t.basis *= p_world_scale;
r_transform = t;
}
return confidence;
}

Transform OpenXRApi::transform_from_space_location(const XrHandJointLocationEXT &p_location, float p_world_scale) {
return _transform_from_space_location(*this, p_location, p_world_scale);
TrackingConfidence OpenXRApi::transform_from_location(const XrHandJointLocationEXT &p_location, float p_world_scale, Transform &r_transform) {
Transform t;
TrackingConfidence confidence = _transform_from_location(p_location, t);
if (confidence != TRACKING_CONFIDENCE_NONE) {
// only update if we have tracking data
t.basis *= p_world_scale;
r_transform = t;
}
return confidence;
}
23 changes: 16 additions & 7 deletions src/openxr/OpenXRApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
// forward declare this
class OpenXRApi;

enum TrackingConfidence {
TRACKING_CONFIDENCE_NONE,
TRACKING_CONFIDENCE_LOW,
TRACKING_CONFIDENCE_HIGH
};

#include "openxr/actions/action.h"
#include "openxr/actions/actionset.h"

Expand All @@ -72,15 +78,16 @@ class OpenXRApi {
XrPath toplevel_path;
godot_int godot_controller;
XrPath active_profile; // note, this can be a profile added in the OpenXR runtime unknown to our default mappings
TrackingConfidence tracking_confidence;
};

InputMap inputmaps[USER_INPUT_MAX] = {
{ "/user/hand/left", XR_NULL_PATH, -1, XR_NULL_PATH },
{ "/user/hand/right", XR_NULL_PATH, -1, XR_NULL_PATH },
{ "/user/hand/left", XR_NULL_PATH, -1, XR_NULL_PATH, TRACKING_CONFIDENCE_NONE },
{ "/user/hand/right", XR_NULL_PATH, -1, XR_NULL_PATH, TRACKING_CONFIDENCE_NONE },
// gamepad is already supported in Godots own joystick handling, head we're using directly
// { "/user/foot/left", XR_NULL_PATH, -1, XR_NULL_PATH },
// { "/user/foot/right", XR_NULL_PATH, -1, XR_NULL_PATH },
// { "/user/treadmill", XR_NULL_PATH, -1, XR_NULL_PATH },
// { "/user/foot/left", XR_NULL_PATH, -1, XR_NULL_PATH, TRACKING_CONFIDENCE_NONE },
// { "/user/foot/right", XR_NULL_PATH, -1, XR_NULL_PATH, TRACKING_CONFIDENCE_NONE },
// { "/user/treadmill", XR_NULL_PATH, -1, XR_NULL_PATH, TRACKING_CONFIDENCE_NONE },
};

// Default actions we support so we can mimic our old ARVRController handling
Expand Down Expand Up @@ -341,6 +348,8 @@ class OpenXRApi {

godot::Array get_enabled_extensions() const;

TrackingConfidence get_controller_tracking_confidence(const int p_godot_controller) const;

static const char *default_action_sets_json;
godot::String get_action_sets_json() const;
void set_action_sets_json(const godot::String &p_action_sets_json);
Expand Down Expand Up @@ -384,8 +393,8 @@ class OpenXRApi {
godot::Transform transform_from_pose(const XrPosef &p_pose, float p_world_scale);

// helper method to get a valid transform from an openxr space location
godot::Transform transform_from_space_location(const XrSpaceLocation &p_location, float p_world_scale);
godot::Transform transform_from_space_location(const XrHandJointLocationEXT &p_location, float p_world_scale);
TrackingConfidence transform_from_location(const XrSpaceLocation &p_location, float p_world_scale, Transform &r_transform);
TrackingConfidence transform_from_location(const XrHandJointLocationEXT &p_location, float p_world_scale, Transform &r_transform);
};

#endif /* !OPENXR_API_H */
Loading

0 comments on commit 0d2ea91

Please sign in to comment.