Compare commits

...

2 commits

Author SHA1 Message Date
rodolpheh e57b3cb5c0 Improvements in device management
Multiple improvements in device management:
* Working management of lost device
* Use deferred call instead of managing a queue of events for signals
* Clean some old code
* Safer open/subscribe/unsubscribe/close
* get_interpolated_frame now returns null if the device is not
  "interpolation_enabled"
2023-11-16 23:51:18 +00:00
rodolpheh 4ae392a7db Add bones list to digit and improve properties 2023-11-16 21:52:33 +00:00
9 changed files with 166 additions and 122 deletions

View file

@ -7,27 +7,12 @@ extends Node3D
@export var disconnected : CanvasLayer @export var disconnected : CanvasLayer
@export var no_device : CanvasLayer @export var no_device : CanvasLayer
signal view_size_changed(view_size : Vector2i)
signal current_device_tracking_mode_changed(tracking_mode : int)
signal presence_of_device_changed(is_present : bool) signal presence_of_device_changed(is_present : bool)
signal current_device_changed(device : UltraleapDevice) signal current_device_changed(device : UltraleapDevice)
var current_device : UltraleapDevice
var previous_tracking_mode : int var previous_tracking_mode : int
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if current_device == null:
return
if current_device.get_tracking_mode() != previous_tracking_mode:
emit_signal("current_device_tracking_mode_changed", current_device.get_tracking_mode())
previous_tracking_mode = current_device.get_tracking_mode()
func _on_device_selection(serial): func _on_device_selection(serial):
var dev : UltraleapDevice = _get_device_from_serial(serial) var dev : UltraleapDevice = _get_device_from_serial(serial)
var current_dev : UltraleapDevice = tracking.get_primary_device() var current_dev : UltraleapDevice = tracking.get_primary_device()
@ -38,36 +23,23 @@ func _on_device_selection(serial):
func _get_device_from_serial(serial : String): func _get_device_from_serial(serial : String):
for device in tracking.devices: for device in tracking.devices_list:
if device.serial == serial: if device.serial == serial:
return device return device
func _open_device():
current_device.open()
current_device.subscribe()
func _close_device():
current_device.unsubscribe()
current_device.close()
func _on_hand_tracking_device_added(device): func _on_hand_tracking_device_added(device):
if tracking.devices.size() > 0: if tracking.devices_list.size() > 0:
emit_signal("presence_of_device_changed", true) emit_signal("presence_of_device_changed", true)
no_device.hide() no_device.hide()
func _on_hand_tracking_device_removed(_device): func _on_hand_tracking_device_removed(_device : UltraleapDevice):
if tracking.devices.size() == 0: if tracking.devices_list.size() == 0:
emit_signal("presence_of_device_changed", false) emit_signal("presence_of_device_changed", false)
no_device.show() no_device.show()
if current_device == null: if tracking.devices_primary_device == null:
return current_device_changed.emit(null)
_close_device()
current_device = null
current_device_changed.emit(null)
func on_undistort_toggled(enabled): func on_undistort_toggled(enabled):

View file

@ -13,6 +13,11 @@
using namespace godot; using namespace godot;
UltraleapDevice::~UltraleapDevice() {
unsubscribe();
close();
}
void UltraleapDevice::_bind_methods() { void UltraleapDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_baseline", "baseline"), &UltraleapDevice::set_baseline); ClassDB::bind_method(D_METHOD("set_baseline", "baseline"), &UltraleapDevice::set_baseline);
ClassDB::bind_method(D_METHOD("get_baseline"), &UltraleapDevice::get_baseline); ClassDB::bind_method(D_METHOD("get_baseline"), &UltraleapDevice::get_baseline);
@ -136,21 +141,62 @@ void UltraleapDevice::tracking_mode_changed(UltraleapTypes::TrackingMode value)
} }
void UltraleapDevice::subscribe() { void UltraleapDevice::subscribe() {
LeapSubscribeEvents(connection, device); if (subscribed) {
UtilityFunctions::print("Device already subscribed to");
return;
}
eLeapRS result = LeapSubscribeEvents(connection, device);
if (result != eLeapRS_Success) {
UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result));
return;
}
subscribed = true;
} }
void UltraleapDevice::unsubscribe() { void UltraleapDevice::unsubscribe() {
LeapUnsubscribeEvents(connection, device); if (!subscribed) {
UtilityFunctions::print("Device not subscribed to");
return;
}
eLeapRS result = LeapUnsubscribeEvents(connection, device);
if (result != eLeapRS_Success) {
UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result));
return;
}
subscribed = false;
} }
void UltraleapDevice::open() { void UltraleapDevice::open() {
LeapOpenDevice(device_ref, &device); if (opened) {
LeapCreateClockRebaser(&rebaser); UtilityFunctions::print("Device already opened");
return;
}
eLeapRS result = LeapOpenDevice(device_ref, &device);
if (result != eLeapRS_Success) {
UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result));
return;
}
opened = true;
result = LeapCreateClockRebaser(&rebaser);
if (result != eLeapRS_Success) {
UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result));
return;
}
interpolation_available = true;
} }
void UltraleapDevice::close() { void UltraleapDevice::close() {
if (!opened) {
UtilityFunctions::print("Device already closed");
return;
}
LeapCloseDevice(device); LeapCloseDevice(device);
LeapDestroyClockRebaser(rebaser); opened = false;
if (rebaser != NULL) {
LeapDestroyClockRebaser(rebaser);
rebaser = NULL;
interpolation_available = false;
}
} }
void UltraleapDevice::on_frame_received(const LEAP_TRACKING_EVENT* frame) { void UltraleapDevice::on_frame_received(const LEAP_TRACKING_EVENT* frame) {
@ -187,6 +233,10 @@ Ref<UltraleapImage> UltraleapDevice::get_right_image() {
} }
Ref<UltraleapFrame> UltraleapDevice::get_interpolated_frame(int64_t time) { Ref<UltraleapFrame> UltraleapDevice::get_interpolated_frame(int64_t time) {
if (!interpolation_available) {
return NULL;
}
int64_t cpu_time = Time::get_singleton()->get_ticks_usec(); int64_t cpu_time = Time::get_singleton()->get_ticks_usec();
LeapUpdateRebase(rebaser, cpu_time, LeapGetNow()); LeapUpdateRebase(rebaser, cpu_time, LeapGetNow());
LeapRebaseClock(rebaser, cpu_time, &time); LeapRebaseClock(rebaser, cpu_time, &time);
@ -208,4 +258,9 @@ Ref<UltraleapFrame> UltraleapDevice::get_interpolated_frame(int64_t time) {
} }
return NULL; return NULL;
}
void UltraleapDevice::on_lost() {
unsubscribe();
close();
} }

View file

@ -23,6 +23,8 @@ class UltraleapDevice : public Resource {
GDCLASS(UltraleapDevice, Resource); GDCLASS(UltraleapDevice, Resource);
public: public:
~UltraleapDevice();
uint32_t baseline; uint32_t baseline;
String serial; String serial;
uint32_t id; uint32_t id;
@ -66,6 +68,10 @@ public:
void on_frame_received(const LEAP_TRACKING_EVENT* frame); void on_frame_received(const LEAP_TRACKING_EVENT* frame);
void on_image_received(const LEAP_IMAGE* image); void on_image_received(const LEAP_IMAGE* image);
void on_lost();
bool is_opened() { return opened; }
bool is_subscribed() { return subscribed; }
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -73,6 +79,10 @@ protected:
private: private:
std::mutex frame_mutex; std::mutex frame_mutex;
std::mutex image_mutex; std::mutex image_mutex;
bool opened = false;
bool subscribed = false;
bool interpolation_available = false;
}; };

View file

@ -33,6 +33,8 @@ void UltraleapDigit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_is_extended"), &UltraleapDigit::get_is_extended); ClassDB::bind_method(D_METHOD("get_is_extended"), &UltraleapDigit::get_is_extended);
ClassDB::bind_method(D_METHOD("set_is_extended", "is_extended"), &UltraleapDigit::set_is_extended); ClassDB::bind_method(D_METHOD("set_is_extended", "is_extended"), &UltraleapDigit::set_is_extended);
ClassDB::bind_method(D_METHOD("get_bones"), &UltraleapDigit::get_bones);
ClassDB::add_property( ClassDB::add_property(
"UltraleapDigit", "UltraleapDigit",
PropertyInfo( PropertyInfo(
@ -102,6 +104,19 @@ void UltraleapDigit::_bind_methods() {
"set_is_extended", "set_is_extended",
"get_is_extended" "get_is_extended"
); );
ClassDB::add_property(
"UltraleapDigit",
PropertyInfo(
Variant::ARRAY,
"bones",
PROPERTY_HINT_ARRAY_TYPE,
"UltraleapBone",
PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR
),
"",
"get_bones"
);
} }
void UltraleapDigit::fill_digit_data(Ref<UltraleapDigit> ul_digit, LEAP_DIGIT* digit, FingerType type) { void UltraleapDigit::fill_digit_data(Ref<UltraleapDigit> ul_digit, LEAP_DIGIT* digit, FingerType type) {

View file

@ -2,7 +2,7 @@
#define ULTRALEAP_DIGIT_H #define ULTRALEAP_DIGIT_H
#include <godot_cpp/classes/global_constants.hpp> #include <godot_cpp/classes/global_constants.hpp>
#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/core/binder_common.hpp> #include <godot_cpp/core/binder_common.hpp>
#include <godot_cpp/core/object.hpp> #include <godot_cpp/core/object.hpp>
@ -53,6 +53,19 @@ public:
bool get_is_extended() { return is_extended; } bool get_is_extended() { return is_extended; }
void set_is_extended(bool value) { is_extended = value; } void set_is_extended(bool value) { is_extended = value; }
Array get_bones() {
if (bones == Variant::NIL) {
bones = Array();
}
if (bones.size() == 0) {
bones.append(metacarpal_ref);
bones.append(proximal_ref);
bones.append(intermediate_ref);
bones.append(distal_ref);
}
return bones;
}
static void fill_digit_data(Ref<UltraleapDigit> ul_digit, LEAP_DIGIT* digit, FingerType type); static void fill_digit_data(Ref<UltraleapDigit> ul_digit, LEAP_DIGIT* digit, FingerType type);
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -62,6 +75,7 @@ private:
Ref<UltraleapBone> proximal_ref; Ref<UltraleapBone> proximal_ref;
Ref<UltraleapBone> intermediate_ref; Ref<UltraleapBone> intermediate_ref;
Ref<UltraleapBone> distal_ref; Ref<UltraleapBone> distal_ref;
Array bones;
}; };
VARIANT_ENUM_CAST(UltraleapDigit::FingerType); VARIANT_ENUM_CAST(UltraleapDigit::FingerType);

View file

@ -53,7 +53,6 @@ void UltraleapHand::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_palm", "palm"), &UltraleapHand::set_palm); ClassDB::bind_method(D_METHOD("set_palm", "palm"), &UltraleapHand::set_palm);
ClassDB::bind_method(D_METHOD("get_palm"), &UltraleapHand::get_palm); ClassDB::bind_method(D_METHOD("get_palm"), &UltraleapHand::get_palm);
ClassDB::bind_method(D_METHOD("set_digits", "digits"), &UltraleapHand::set_digits);
ClassDB::bind_method(D_METHOD("get_digits"), &UltraleapHand::get_digits); ClassDB::bind_method(D_METHOD("get_digits"), &UltraleapHand::get_digits);
ClassDB::add_property( ClassDB::add_property(
@ -216,18 +215,16 @@ void UltraleapHand::_bind_methods() {
"UltraleapHand", "UltraleapHand",
PropertyInfo( PropertyInfo(
Variant::ARRAY, Variant::ARRAY,
"digits" "digits",
PROPERTY_HINT_ARRAY_TYPE,
"UltraleapDigit",
PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR
), ),
"set_digits", "",
"get_digits" "get_digits"
); );
}; };
void UltraleapHand::set_digits(Array digits) {
for (int i = 0; i < digits.size(); i++) {
}
}
void UltraleapHand::fill_hand_data(Ref<UltraleapHand> ul_hand, LEAP_HAND* hand) { void UltraleapHand::fill_hand_data(Ref<UltraleapHand> ul_hand, LEAP_HAND* hand) {
// For now we just check if the arm ref is not set // For now we just check if the arm ref is not set
if (ul_hand->arm_ref == NULL) { if (ul_hand->arm_ref == NULL) {

View file

@ -74,7 +74,9 @@ public:
void set_palm(Ref<UltraleapPalm> value) { palm_ref = value; } void set_palm(Ref<UltraleapPalm> value) { palm_ref = value; }
Array get_digits() { Array get_digits() {
Array digits_array = Array(); if (digits_array == Variant::NIL) {
digits_array = Array();
}
if (digits_array.size() == 0) { if (digits_array.size() == 0) {
digits_array.append(thumb); digits_array.append(thumb);
digits_array.append(index); digits_array.append(index);
@ -84,7 +86,6 @@ public:
} }
return digits_array; return digits_array;
} }
void set_digits(Array digits);
static void fill_hand_data(Ref<UltraleapHand> ul_hand, LEAP_HAND* hand); static void fill_hand_data(Ref<UltraleapHand> ul_hand, LEAP_HAND* hand);
protected: protected:
@ -93,7 +94,7 @@ protected:
private: private:
Ref<UltraleapBone> arm_ref; Ref<UltraleapBone> arm_ref;
Ref<UltraleapPalm> palm_ref; Ref<UltraleapPalm> palm_ref;
Array digits_array = Array(); Array digits_array;
Ref<UltraleapDigit> thumb; Ref<UltraleapDigit> thumb;
Ref<UltraleapDigit> index; Ref<UltraleapDigit> index;

View file

@ -85,16 +85,14 @@ void UltraleapHandTracking::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_connected"), &UltraleapHandTracking::is_connected); ClassDB::bind_method(D_METHOD("is_connected"), &UltraleapHandTracking::is_connected);
ClassDB::bind_method(D_METHOD("is_started"), &UltraleapHandTracking::is_started); ClassDB::bind_method(D_METHOD("is_started"), &UltraleapHandTracking::is_started);
//ClassDB::bind_method(D_METHOD("set_last_frame", "last_frame"), &UltraleapHandTracking::set_last_frame);
ClassDB::bind_method(D_METHOD("get_last_frame"), &UltraleapHandTracking::get_last_frame); ClassDB::bind_method(D_METHOD("get_last_frame"), &UltraleapHandTracking::get_last_frame);
ClassDB::bind_method(D_METHOD("set_tracking_mode", "tracking_mode"), &UltraleapHandTracking::set_tracking_mode, DEFVAL(0)); ClassDB::bind_method(D_METHOD("set_tracking_mode", "tracking_mode"), &UltraleapHandTracking::set_tracking_mode);
ClassDB::bind_method(D_METHOD("get_tracking_mode"), &UltraleapHandTracking::get_tracking_mode); ClassDB::bind_method(D_METHOD("get_tracking_mode"), &UltraleapHandTracking::get_tracking_mode);
ClassDB::bind_method(D_METHOD("get_left_image"), &UltraleapHandTracking::get_left_image); ClassDB::bind_method(D_METHOD("get_left_image"), &UltraleapHandTracking::get_left_image);
ClassDB::bind_method(D_METHOD("get_right_image"), &UltraleapHandTracking::get_right_image); ClassDB::bind_method(D_METHOD("get_right_image"), &UltraleapHandTracking::get_right_image);
ClassDB::bind_method(D_METHOD("set_devices", "devices"), &UltraleapHandTracking::set_devices);
ClassDB::bind_method(D_METHOD("get_devices"), &UltraleapHandTracking::get_devices); ClassDB::bind_method(D_METHOD("get_devices"), &UltraleapHandTracking::get_devices);
ClassDB::bind_method(D_METHOD("set_service_ip", "service_ip"), &UltraleapHandTracking::set_service_ip); ClassDB::bind_method(D_METHOD("set_service_ip", "service_ip"), &UltraleapHandTracking::set_service_ip);
@ -137,19 +135,38 @@ void UltraleapHandTracking::_bind_methods() {
"get_tracking_mode" "get_tracking_mode"
); );
ClassDB::add_property_group(
"UltraleapHandTracking",
"Devices",
"devices"
);
ClassDB::add_property( ClassDB::add_property(
"UltraleapHandTracking", "UltraleapHandTracking",
PropertyInfo( PropertyInfo(
Variant::ARRAY, Variant::ARRAY,
"devices", "devices_list",
PROPERTY_HINT_ARRAY_TYPE, PROPERTY_HINT_ARRAY_TYPE,
"UltraleapDevice", "UltraleapDevice",
PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR
), ),
"set_devices", "",
"get_devices" "get_devices"
); );
ClassDB::add_property(
"UltraleapHandTracking",
PropertyInfo(
Variant::OBJECT,
"devices_primary_device",
PROPERTY_HINT_RESOURCE_TYPE,
"UltraleapDevice",
PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR
),
"set_primary_device",
"get_primary_device"
);
ClassDB::add_property_group( ClassDB::add_property_group(
"UltraleapHandTracking", "UltraleapHandTracking",
"Connection", "Connection",
@ -369,12 +386,12 @@ void UltraleapHandTracking::stop() {
} }
void UltraleapHandTracking::handle_connection_event(const LEAP_CONNECTION_EVENT *evt) { void UltraleapHandTracking::handle_connection_event(const LEAP_CONNECTION_EVENT *evt) {
events.push({ "connection_status_changed", true }); call_deferred_thread_group("emit_signal", "connection_status_changed", true);
connected = true; connected = true;
} }
void UltraleapHandTracking::handle_connection_lost_event(const LEAP_CONNECTION_LOST_EVENT *event) { void UltraleapHandTracking::handle_connection_lost_event(const LEAP_CONNECTION_LOST_EVENT *event) {
events.push({ "connection_status_changed", false }); call_deferred_thread_group("emit_signal", "connection_status_changed", true);
connected = false; connected = false;
// TODO: write something more pretty // TODO: write something more pretty
@ -538,10 +555,7 @@ bool UltraleapHandTracking::get_policy(UltraleapTypes::PolicyFlag flag) {
void UltraleapHandTracking::set_pause(bool value) { void UltraleapHandTracking::set_pause(bool value) {
eLeapRS result = LeapSetPause(connectionHandle, value); eLeapRS result = LeapSetPause(connectionHandle, value);
if (result == eLeapRS_Success) { if (result != eLeapRS_Success) {
// Maybe send a signal here ?
}
else {
UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result)); UtilityFunctions::print(UltraleapTypes::ultraleap_result_to_string(result));
} }
} }
@ -559,12 +573,6 @@ void UltraleapHandTracking::handle_tracking_event(const LEAP_TRACKING_EVENT* eve
} }
dev->on_frame_received(event); dev->on_frame_received(event);
// Commenting for now, might remove later. The getter now get the frame
// from the primary device instead of storing it.
// if (primary_device != NULL && primary_device->id == device_id) {
// last_frame_ref = primary_device->get_last_frame();
// }
} }
void UltraleapHandTracking::handle_image_event(const LEAP_IMAGE_EVENT* event, uint32_t device_id) { void UltraleapHandTracking::handle_image_event(const LEAP_IMAGE_EVENT* event, uint32_t device_id) {
@ -582,13 +590,6 @@ void UltraleapHandTracking::handle_image_event(const LEAP_IMAGE_EVENT* event, ui
} }
dev->on_image_received(event->image); dev->on_image_received(event->image);
// Commenting for now, might remove later. The getters now get the images
// from the primary device instead of storing them.
// if (primary_device != NULL && primary_device->id == device_id) {
// left_image_ref = primary_device->left_image_ref;
// right_image_ref = primary_device->right_image_ref;
// }
} }
void UltraleapHandTracking::handle_policy_change_event(const LEAP_POLICY_EVENT* event) { void UltraleapHandTracking::handle_policy_change_event(const LEAP_POLICY_EVENT* event) {
@ -622,19 +623,19 @@ void UltraleapHandTracking::handle_policy_change_event(const LEAP_POLICY_EVENT*
bool current_allow_pause_resume_policy = UltraleapTypes::read_policy_flag(flags, UltraleapTypes::PolicyFlag::AllowPauseResume); bool current_allow_pause_resume_policy = UltraleapTypes::read_policy_flag(flags, UltraleapTypes::PolicyFlag::AllowPauseResume);
if (current_images_policy != previous_images_policy) { if (current_images_policy != previous_images_policy) {
events.push({ "images_policy_changed", current_images_policy }); call_deferred_thread_group("emit_signal", "images_policy_changed", current_images_policy);
} }
if (current_background_frames_policy != previous_background_frames_policy) { if (current_background_frames_policy != previous_background_frames_policy) {
events.push({ "background_frames_policy_changed", current_background_frames_policy }); call_deferred_thread_group("emit_signal", "background_frames_policy_changed", current_background_frames_policy);
} }
if (current_map_points_policy != previous_map_points_policy) { if (current_map_points_policy != previous_map_points_policy) {
events.push({ "map_points_policy_changed", current_map_points_policy }); call_deferred_thread_group("emit_signal", "map_points_policy_changed", current_map_points_policy);
} }
if (current_allow_pause_resume_policy != previous_allow_pause_resume_policy) { if (current_allow_pause_resume_policy != previous_allow_pause_resume_policy) {
events.push({ "allow_pause_resume_policy_changed", current_allow_pause_resume_policy }); call_deferred_thread_group("emit_signal", "allow_pause_resume_policy_changed", current_allow_pause_resume_policy);
} }
policy_flags = flags; policy_flags = flags;
@ -658,7 +659,7 @@ void UltraleapHandTracking::handle_tracking_mode_event(const LEAP_TRACKING_MODE_
if (primary_device != NULL && device_id == primary_device->id) { if (primary_device != NULL && device_id == primary_device->id) {
if (primary_device->tracking_mode != tm) { if (primary_device->tracking_mode != tm) {
events.push({ "tracking_mode_changed", tm }); call_deferred_thread_group("emit_signal", "tracking_mode_changed", tm);
} }
} }
@ -672,23 +673,26 @@ void UltraleapHandTracking::handle_device_event(const LEAP_DEVICE_EVENT* event)
Ref<UltraleapDevice> dev = create_device(event->device); Ref<UltraleapDevice> dev = create_device(event->device);
if (!devices->has_device(dev)) { if (!devices->has_device(dev)) {
devices->add_device(dev); devices->add_device(dev);
events.push({ "device_added", dev });
} }
else { else {
UtilityFunctions::print("Device was already in the list, updating"); UtilityFunctions::print("Device was already in the list, updating");
devices->remove_device(dev); devices->remove_device(dev);
devices->add_device(dev); devices->add_device(dev);
events.push({ "device_added", dev });
} }
call_deferred_thread_group("emit_signal", "device_added", dev);
} }
void UltraleapHandTracking::handle_device_lost_event(const LEAP_DEVICE_EVENT* event) { void UltraleapHandTracking::handle_device_lost_event(const LEAP_DEVICE_EVENT* event) {
UtilityFunctions::print("Device lost"); UtilityFunctions::print("Device lost with ID ", event->device.id);
Ref<UltraleapDevice> dev = create_device(event->device); Ref<UltraleapDevice> dev = devices->find_by_id(event->device.id);
if (devices->has_device(dev)) { if (dev != NULL) {
if (dev == primary_device) {
primary_device = Variant::NIL;
}
devices->remove_device(dev); devices->remove_device(dev);
events.push({ "device_removed", dev }); call_deferred_thread_group("emit_signal", "device_removed", dev);
} }
else { else {
UtilityFunctions::print("Device was not in the list"); UtilityFunctions::print("Device was not in the list");
@ -762,19 +766,11 @@ Ref<UltraleapDevice> UltraleapHandTracking::create_device(LEAP_DEVICE_REF ref) {
void UltraleapHandTracking::_notification(int p_what) { void UltraleapHandTracking::_notification(int p_what) {
//UtilityFunctions::print(p_what); //UtilityFunctions::print(p_what);
if (p_what == Node::NOTIFICATION_ENTER_TREE) { if (p_what == Node::NOTIFICATION_ENTER_TREE) {
set_process_internal(true);
// For now we will also start automatically if we're in the editor, so that we can have data for tool scripts // For now we will also start automatically if we're in the editor, so that we can have data for tool scripts
if (autostart || Engine::get_singleton()->is_editor_hint()) { if (autostart || Engine::get_singleton()->is_editor_hint()) {
start(); start();
} }
} }
else if (p_what == Node::NOTIFICATION_INTERNAL_PROCESS) {
while (!events.empty()) {
event ev = events.front();
emit_signal(ev.signal, ev.arg);
events.pop();
}
}
else if (p_what == Node::NOTIFICATION_EXIT_TREE) { else if (p_what == Node::NOTIFICATION_EXIT_TREE) {
stop(); stop();
} }
@ -790,17 +786,15 @@ String UltraleapHandTracking::generate_connection_payload() {
} }
void UltraleapHandTracking::set_primary_device(Ref<UltraleapDevice> device) { void UltraleapHandTracking::set_primary_device(Ref<UltraleapDevice> device) {
if (primary_device == NULL || primary_device->id != device->id) { if (primary_device != NULL) {
if (primary_device != NULL && primary_device->id != device->id) { if (!primary_device->is_opened()) {
LeapCloseDevice(primary_device->device); primary_device->close();
} }
// Pretty hack-ish, we open the device and re-store the handle in the UltraleapDevice object
LeapOpenDevice(device->device_ref, &(device->device));
primary_device = device;
LeapSetPrimaryDevice(connectionHandle, device->device, false);
} }
device->open();
primary_device = device;
LeapSetPrimaryDevice(connectionHandle, device->device, false);
} }
Ref<UltraleapDevice> UltraleapHandTracking::get_primary_device() { Ref<UltraleapDevice> UltraleapHandTracking::get_primary_device() {
@ -808,27 +802,24 @@ Ref<UltraleapDevice> UltraleapHandTracking::get_primary_device() {
} }
Ref<UltraleapFrame> UltraleapHandTracking::get_last_frame() { Ref<UltraleapFrame> UltraleapHandTracking::get_last_frame() {
// Uuuuh... don't like this part
if (primary_device == NULL) { if (primary_device == NULL) {
return last_frame_ref; return NULL;
} }
return primary_device->get_last_frame(); return primary_device->get_last_frame();
} }
Ref<UltraleapImage> UltraleapHandTracking::get_left_image() { Ref<UltraleapImage> UltraleapHandTracking::get_left_image() {
// Uuuuh... don't like this part
if (primary_device == NULL) { if (primary_device == NULL) {
return left_image_ref; return NULL;
} }
return primary_device->get_left_image(); return primary_device->get_left_image();
} }
Ref<UltraleapImage> UltraleapHandTracking::get_right_image() { Ref<UltraleapImage> UltraleapHandTracking::get_right_image() {
// Uuuuh... don't like this part
if (primary_device == NULL) { if (primary_device == NULL) {
return right_image_ref; return NULL;
} }
return primary_device->get_right_image(); return primary_device->get_right_image();

View file

@ -42,22 +42,16 @@ public:
Ref<UltraleapDeviceList> devices = Ref<UltraleapDeviceList>(memnew(UltraleapDeviceList)); Ref<UltraleapDeviceList> devices = Ref<UltraleapDeviceList>(memnew(UltraleapDeviceList));
Ref<UltraleapFrame> last_frame_ref;
Ref<UltraleapImage> left_image_ref;
Ref<UltraleapImage> right_image_ref;
String service_ip = String("127.0.0.1"); String service_ip = String("127.0.0.1");
uint16_t service_port = 12345; uint16_t service_port = 12345;
bool autostart = true; bool autostart = true;
bool enable_images = true; bool enable_images = true;
Ref<UltraleapFrame> get_last_frame();
void set_last_frame(Ref<UltraleapFrame> value) { return; }
UltraleapTypes::TrackingMode get_tracking_mode(); UltraleapTypes::TrackingMode get_tracking_mode();
void set_tracking_mode(UltraleapTypes::TrackingMode value); void set_tracking_mode(UltraleapTypes::TrackingMode value);
Ref<UltraleapFrame> get_last_frame();
Ref<UltraleapImage> get_left_image(); Ref<UltraleapImage> get_left_image();
Ref<UltraleapImage> get_right_image(); Ref<UltraleapImage> get_right_image();
@ -112,12 +106,7 @@ private:
bool opened = false; /* Indicate an opened connection */ bool opened = false; /* Indicate an opened connection */
bool connected = false; /* We have confirmed connection */ bool connected = false; /* We have confirmed connection */
Ref<UltraleapDevice> primary_device = NULL; Ref<UltraleapDevice> primary_device;
typedef struct {
StringName signal;
Variant arg;
} event;
std::queue<event> events;
void serviceMessageLoop(); void serviceMessageLoop();
void dispose_ultraleap(); void dispose_ultraleap();