Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add XR tracking state-change signals #81239

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/classes/XRNode3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,12 @@
Godot defines a number of standard trackers such as [code]left_hand[/code] and [code]right_hand[/code] but others may be configured within a given [XRInterface].
</member>
</members>
<signals>
<signal name="tracking_changed">
<param index="0" name="tracking" type="bool" />
<description>
Emitted when the [member tracker] starts or stops receiving updated tracking data for the [member pose] being tracked. The [param tracking] argument indicates whether the tracker is getting updated tracking data.
</description>
</signal>
</signals>
</class>
6 changes: 6 additions & 0 deletions doc/classes/XRPositionalTracker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@
Emitted when the state of a pose tracked by this tracker changes.
</description>
</signal>
<signal name="pose_lost_tracking">
<param index="0" name="pose" type="XRPose" />
<description>
Emitted when a pose tracked by this tracker stops getting updated tracking data.
</description>
</signal>
<signal name="profile_changed">
<param index="0" name="role" type="String" />
<description>
Expand Down
33 changes: 26 additions & 7 deletions scene/3d/xr_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ void XRNode3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRNode3D::get_has_tracking_data);
ClassDB::bind_method(D_METHOD("get_pose"), &XRNode3D::get_pose);
ClassDB::bind_method(D_METHOD("trigger_haptic_pulse", "action_name", "frequency", "amplitude", "duration_sec", "delay_sec"), &XRNode3D::trigger_haptic_pulse);

ADD_SIGNAL(MethodInfo("tracking_changed", PropertyInfo(Variant::BOOL, "tracking")));
};

void XRNode3D::_validate_property(PropertyInfo &p_property) const {
Expand Down Expand Up @@ -305,13 +307,7 @@ bool XRNode3D::get_is_active() const {
}

bool XRNode3D::get_has_tracking_data() const {
if (tracker.is_null()) {
return false;
} else if (!tracker->has_pose(pose_name)) {
return false;
} else {
return tracker->get_pose(pose_name)->get_has_tracking_data();
}
return has_tracking_data;
}

void XRNode3D::trigger_haptic_pulse(const String &p_action_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) {
Expand Down Expand Up @@ -346,19 +342,24 @@ void XRNode3D::_bind_tracker() {
}

tracker->connect("pose_changed", callable_mp(this, &XRNode3D::_pose_changed));
tracker->connect("pose_lost_tracking", callable_mp(this, &XRNode3D::_pose_lost_tracking));

Ref<XRPose> pose = get_pose();
if (pose.is_valid()) {
set_transform(pose->get_adjusted_transform());
_set_has_tracking_data(pose->get_has_tracking_data());
}
}
}

void XRNode3D::_unbind_tracker() {
Malcolmnixon marked this conversation as resolved.
Show resolved Hide resolved
if (tracker.is_valid()) {
tracker->disconnect("pose_changed", callable_mp(this, &XRNode3D::_pose_changed));
tracker->disconnect("pose_lost_tracking", callable_mp(this, &XRNode3D::_pose_lost_tracking));

tracker.unref();

_set_has_tracking_data(false);
}
}

Expand All @@ -382,9 +383,27 @@ void XRNode3D::_removed_tracker(const StringName p_tracker_name, int p_tracker_t
void XRNode3D::_pose_changed(const Ref<XRPose> &p_pose) {
if (p_pose.is_valid() && p_pose->get_name() == pose_name) {
set_transform(p_pose->get_adjusted_transform());
_set_has_tracking_data(p_pose->get_has_tracking_data());
}
}

void XRNode3D::_pose_lost_tracking(const Ref<XRPose> &p_pose) {
if (p_pose.is_valid() && p_pose->get_name() == pose_name) {
_set_has_tracking_data(false);
}
}

void XRNode3D::_set_has_tracking_data(bool p_has_tracking_data) {
// Ignore if the has_tracking_data state isn't changing.
if (p_has_tracking_data == has_tracking_data) {
return;
}

// Handle change of has_tracking_data.
has_tracking_data = p_has_tracking_data;
emit_signal(SNAME("tracking_changed"), has_tracking_data);
}

XRNode3D::XRNode3D() {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
Expand Down
4 changes: 3 additions & 1 deletion scene/3d/xr_nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class XRNode3D : public Node3D {
private:
StringName tracker_name;
StringName pose_name = "default";
bool is_active = true;
bool has_tracking_data = false;

protected:
Ref<XRPositionalTracker> tracker;
Expand All @@ -91,6 +91,8 @@ class XRNode3D : public Node3D {
void _removed_tracker(const StringName p_tracker_name, int p_tracker_type);

void _pose_changed(const Ref<XRPose> &p_pose);
void _pose_lost_tracking(const Ref<XRPose> &p_pose);
void _set_has_tracking_data(bool p_has_tracking_data);

public:
void _validate_property(PropertyInfo &p_property) const;
Expand Down
6 changes: 5 additions & 1 deletion servers/xr/xr_positional_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void XRPositionalTracker::_bind_methods() {
ClassDB::bind_method(D_METHOD("invalidate_pose", "name"), &XRPositionalTracker::invalidate_pose);
ClassDB::bind_method(D_METHOD("set_pose", "name", "transform", "linear_velocity", "angular_velocity", "tracking_confidence"), &XRPositionalTracker::set_pose);
ADD_SIGNAL(MethodInfo("pose_changed", PropertyInfo(Variant::OBJECT, "pose", PROPERTY_HINT_RESOURCE_TYPE, "XRPose")));
ADD_SIGNAL(MethodInfo("pose_lost_tracking", PropertyInfo(Variant::OBJECT, "pose", PROPERTY_HINT_RESOURCE_TYPE, "XRPose")));

ClassDB::bind_method(D_METHOD("get_input", "name"), &XRPositionalTracker::get_input);
ClassDB::bind_method(D_METHOD("set_input", "name", "value"), &XRPositionalTracker::set_input);
Expand Down Expand Up @@ -146,7 +147,10 @@ void XRPositionalTracker::invalidate_pose(const StringName &p_action_name) {
// only update this if we were tracking this pose
if (poses.has(p_action_name)) {
// We just set tracking data as invalid, we leave our current transform and velocity data as is so controllers don't suddenly jump to origin.
poses[p_action_name]->set_has_tracking_data(false);
Ref<XRPose> pose = poses[p_action_name];
pose->set_has_tracking_data(false);

emit_signal(SNAME("pose_lost_tracking"), pose);
}
}

Expand Down