@@ -159,6 +159,9 @@ bool LunarWM_init(LunarWM *wm)
|
|||||||
wm->xr.local_space = wm->xr.view_space = XR_NULL_HANDLE;
|
wm->xr.local_space = wm->xr.view_space = XR_NULL_HANDLE;
|
||||||
wm->xr.hand_tracking_system_properties.type
|
wm->xr.hand_tracking_system_properties.type
|
||||||
= XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT;
|
= XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT;
|
||||||
|
wm->xr.hand_tracking_system_properties.next = NULL;
|
||||||
|
wm->xr.hand_tracking_system_properties.supportsHandTracking = XR_FALSE;
|
||||||
|
wm->xr.hand_tracking_enabled = false;
|
||||||
wm->renderer.camera.position = (Vector3) { 0, 0, 0 };
|
wm->renderer.camera.position = (Vector3) { 0, 0, 0 };
|
||||||
wm->renderer.camera.target = (Vector3) { 0, 0, 1 };
|
wm->renderer.camera.target = (Vector3) { 0, 0, 1 };
|
||||||
wm->renderer.camera.up = (Vector3) { 0, 1, 0 };
|
wm->renderer.camera.up = (Vector3) { 0, 1, 0 };
|
||||||
@@ -340,10 +343,14 @@ void LunarWM_run(LunarWM *wm)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wm->xr.hand_tracking_system_properties.supportsHandTracking) {
|
if (wm->xr.hand_tracking_enabled) {
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (size_t i = 0; i < 2; i++) {
|
||||||
LunarWM_Hand *hand = &wm->xr.hands[i];
|
LunarWM_Hand *hand = &wm->xr.hands[i];
|
||||||
bool const unobstructed = true;
|
bool const unobstructed = true;
|
||||||
|
if (!wm->xr.LocateHandJointsEXT
|
||||||
|
|| hand->hand_tracker == XR_NULL_HANDLE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
XrHandJointsMotionRangeInfoEXT mri = {
|
XrHandJointsMotionRangeInfoEXT mri = {
|
||||||
.type = XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT,
|
.type = XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT,
|
||||||
|
|||||||
@@ -353,8 +353,10 @@ static void render_3d(LunarWM *this, float /*dt*/)
|
|||||||
{
|
{
|
||||||
LunarWM_render_windows(this, true);
|
LunarWM_render_windows(this, true);
|
||||||
|
|
||||||
for (int h = 0; h < 2; ++h) {
|
for (int h = 0; this->xr.hand_tracking_enabled && h < 2; ++h) {
|
||||||
auto *hand_info = &this->xr.hands[h];
|
auto *hand_info = &this->xr.hands[h];
|
||||||
|
if (hand_info->hand_tracker == XR_NULL_HANDLE)
|
||||||
|
continue;
|
||||||
for (size_t k = 0; k < XR_HAND_JOINT_COUNT_EXT; ++k) {
|
for (size_t k = 0; k < XR_HAND_JOINT_COUNT_EXT; ++k) {
|
||||||
auto const *jl = &hand_info->joint_locations[k];
|
auto const *jl = &hand_info->joint_locations[k];
|
||||||
Vector3 pos = {
|
Vector3 pos = {
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ typedef struct LunarWM {
|
|||||||
PFN_xrCreateHandTrackerEXT CreateHandTrackerEXT;
|
PFN_xrCreateHandTrackerEXT CreateHandTrackerEXT;
|
||||||
PFN_xrDestroyHandTrackerEXT DestroyHandTrackerEXT;
|
PFN_xrDestroyHandTrackerEXT DestroyHandTrackerEXT;
|
||||||
PFN_xrLocateHandJointsEXT LocateHandJointsEXT;
|
PFN_xrLocateHandJointsEXT LocateHandJointsEXT;
|
||||||
|
bool hand_tracking_enabled;
|
||||||
|
|
||||||
Quaternion recenter_rot;
|
Quaternion recenter_rot;
|
||||||
Vector3 recenter_trans;
|
Vector3 recenter_trans;
|
||||||
|
|||||||
114
src/LunarWM_xr.c
114
src/LunarWM_xr.c
@@ -13,7 +13,6 @@ GLuint LunarWM_xr_get_swapchain_image(
|
|||||||
return wm->xr.swapchain_images[swapchain_images_i].a_imgs[index].image;
|
return wm->xr.swapchain_images[swapchain_images_i].a_imgs[index].image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LunarWM_xr_init(LunarWM *this)
|
bool LunarWM_xr_init(LunarWM *this)
|
||||||
{
|
{
|
||||||
XrResult res = XR_SUCCESS;
|
XrResult res = XR_SUCCESS;
|
||||||
@@ -28,12 +27,15 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
strncpy(
|
strncpy(
|
||||||
(char *)app_info.engineName, "LunarWM Engine", XR_MAX_ENGINE_NAME_SIZE);
|
(char *)app_info.engineName, "LunarWM Engine", XR_MAX_ENGINE_NAME_SIZE);
|
||||||
|
|
||||||
char const *instance_extensions[] = {
|
char const *required_instance_extensions[] = {
|
||||||
XR_EXT_DEBUG_UTILS_EXTENSION_NAME,
|
XR_EXT_DEBUG_UTILS_EXTENSION_NAME,
|
||||||
XR_MNDX_EGL_ENABLE_EXTENSION_NAME,
|
XR_MNDX_EGL_ENABLE_EXTENSION_NAME,
|
||||||
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
|
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
|
||||||
|
};
|
||||||
|
char const *optional_instance_extensions[] = {
|
||||||
XR_EXT_HAND_TRACKING_EXTENSION_NAME,
|
XR_EXT_HAND_TRACKING_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
|
bool hand_tracking_ext_available = false;
|
||||||
char const **v_active_instance_extensions = vector_create();
|
char const **v_active_instance_extensions = vector_create();
|
||||||
|
|
||||||
uint32_t extension_properties_count = 0;
|
uint32_t extension_properties_count = 0;
|
||||||
@@ -61,8 +63,9 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_SZ(instance_extensions); i++) {
|
for (size_t i = 0; i < ARRAY_SZ(required_instance_extensions); i++) {
|
||||||
char const *requested_instance_extension = instance_extensions[i];
|
char const *requested_instance_extension
|
||||||
|
= required_instance_extensions[i];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int j = 0; j < extension_properties_count; j++) {
|
for (int j = 0; j < extension_properties_count; j++) {
|
||||||
if (strcmp(requested_instance_extension,
|
if (strcmp(requested_instance_extension,
|
||||||
@@ -84,6 +87,33 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ARRAY_SZ(optional_instance_extensions); i++) {
|
||||||
|
char const *requested_instance_extension
|
||||||
|
= optional_instance_extensions[i];
|
||||||
|
bool found = false;
|
||||||
|
for (int j = 0; j < extension_properties_count; j++) {
|
||||||
|
if (strcmp(requested_instance_extension,
|
||||||
|
extension_properties[j].extensionName)
|
||||||
|
!= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector_add(
|
||||||
|
&v_active_instance_extensions, requested_instance_extension);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
wlr_log(WLR_INFO, "Optional OpenXR instance extension missing: %s",
|
||||||
|
requested_instance_extension);
|
||||||
|
} else if (strcmp(requested_instance_extension,
|
||||||
|
XR_EXT_HAND_TRACKING_EXTENSION_NAME)
|
||||||
|
== 0) {
|
||||||
|
hand_tracking_ext_available = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
XrInstanceCreateInfo const ci = {
|
XrInstanceCreateInfo const ci = {
|
||||||
.type = XR_TYPE_INSTANCE_CREATE_INFO,
|
.type = XR_TYPE_INSTANCE_CREATE_INFO,
|
||||||
@@ -104,26 +134,45 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
}
|
}
|
||||||
this->xr.instance = instance;
|
this->xr.instance = instance;
|
||||||
|
|
||||||
res = xrGetInstanceProcAddr(this->xr.instance, "xrCreateHandTrackerEXT",
|
this->xr.CreateHandTrackerEXT = NULL;
|
||||||
|
this->xr.DestroyHandTrackerEXT = NULL;
|
||||||
|
this->xr.LocateHandJointsEXT = NULL;
|
||||||
|
|
||||||
|
if (hand_tracking_ext_available) {
|
||||||
|
res = xrGetInstanceProcAddr(this->xr.instance,
|
||||||
|
"xrCreateHandTrackerEXT",
|
||||||
(PFN_xrVoidFunction *)&this->xr.CreateHandTrackerEXT);
|
(PFN_xrVoidFunction *)&this->xr.CreateHandTrackerEXT);
|
||||||
if (res != XR_SUCCESS) {
|
if (res != XR_SUCCESS) {
|
||||||
wlr_log(
|
wlr_log(WLR_ERROR,
|
||||||
WLR_ERROR, "Failed to get proc addr xrCreateHandTrackerEXT");
|
"Failed to get proc addr xrCreateHandTrackerEXT "
|
||||||
return false;
|
"(optional): %d",
|
||||||
|
res);
|
||||||
|
hand_tracking_ext_available = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (hand_tracking_ext_available) {
|
||||||
res = xrGetInstanceProcAddr(this->xr.instance,
|
res = xrGetInstanceProcAddr(this->xr.instance,
|
||||||
"xrDestroyHandTrackerEXT",
|
"xrDestroyHandTrackerEXT",
|
||||||
(PFN_xrVoidFunction *)&this->xr.DestroyHandTrackerEXT);
|
(PFN_xrVoidFunction *)&this->xr.DestroyHandTrackerEXT);
|
||||||
if (res != XR_SUCCESS) {
|
if (res != XR_SUCCESS) {
|
||||||
wlr_log(
|
wlr_log(WLR_ERROR,
|
||||||
WLR_ERROR, "Failed to get proc addr xrDestroyHandTrackerEXT");
|
"Failed to get proc addr xrDestroyHandTrackerEXT "
|
||||||
return false;
|
"(optional): %d",
|
||||||
|
res);
|
||||||
|
hand_tracking_ext_available = false;
|
||||||
}
|
}
|
||||||
res = xrGetInstanceProcAddr(this->xr.instance, "xrLocateHandJointsEXT",
|
}
|
||||||
|
if (hand_tracking_ext_available) {
|
||||||
|
res = xrGetInstanceProcAddr(this->xr.instance,
|
||||||
|
"xrLocateHandJointsEXT",
|
||||||
(PFN_xrVoidFunction *)&this->xr.LocateHandJointsEXT);
|
(PFN_xrVoidFunction *)&this->xr.LocateHandJointsEXT);
|
||||||
if (res != XR_SUCCESS) {
|
if (res != XR_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "Failed to get proc addr xrLocateHandJointsEXT");
|
wlr_log(WLR_ERROR,
|
||||||
return false;
|
"Failed to get proc addr xrLocateHandJointsEXT (optional): "
|
||||||
|
"%d",
|
||||||
|
res);
|
||||||
|
hand_tracking_ext_available = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +204,12 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
this->xr.hand_tracking_enabled = hand_tracking_ext_available;
|
||||||
XrSystemProperties system_props = {
|
XrSystemProperties system_props = {
|
||||||
.type = XR_TYPE_SYSTEM_PROPERTIES,
|
.type = XR_TYPE_SYSTEM_PROPERTIES,
|
||||||
.next = &this->xr.hand_tracking_system_properties,
|
.next = this->xr.hand_tracking_enabled
|
||||||
|
? &this->xr.hand_tracking_system_properties
|
||||||
|
: NULL,
|
||||||
};
|
};
|
||||||
res = xrGetSystemProperties(
|
res = xrGetSystemProperties(
|
||||||
this->xr.instance, this->xr.system_id, &system_props);
|
this->xr.instance, this->xr.system_id, &system_props);
|
||||||
@@ -165,6 +217,13 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
wlr_log(WLR_ERROR, "xrGetSystemProperties failed: %d", res);
|
wlr_log(WLR_ERROR, "xrGetSystemProperties failed: %d", res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (this->xr.hand_tracking_enabled
|
||||||
|
&& !this->xr.hand_tracking_system_properties.supportsHandTracking) {
|
||||||
|
wlr_log(WLR_INFO,
|
||||||
|
"Hand tracking extension present but system does not support "
|
||||||
|
"it");
|
||||||
|
this->xr.hand_tracking_enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XrGraphicsRequirementsOpenGLESKHR reqs = {
|
XrGraphicsRequirementsOpenGLESKHR reqs = {
|
||||||
@@ -609,7 +668,8 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Create hand trackers
|
if (this->xr.hand_tracking_enabled && this->xr.CreateHandTrackerEXT) {
|
||||||
|
bool hand_trackers_created = true;
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (size_t i = 0; i < 2; i++) {
|
||||||
auto *hand = &this->xr.hands[i];
|
auto *hand = &this->xr.hands[i];
|
||||||
|
|
||||||
@@ -623,9 +683,29 @@ bool LunarWM_xr_init(LunarWM *this)
|
|||||||
this->xr.session, &ci, &hand->hand_tracker);
|
this->xr.session, &ci, &hand->hand_tracker);
|
||||||
if (res != XR_SUCCESS) {
|
if (res != XR_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create hand tracker: %d", res);
|
wlr_log(WLR_ERROR, "Failed to create hand tracker: %d", res);
|
||||||
return false;
|
hand_trackers_created = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!hand_trackers_created) {
|
||||||
|
if (this->xr.DestroyHandTrackerEXT) {
|
||||||
|
for (size_t i = 0; i < 2; i++) {
|
||||||
|
auto *hand = &this->xr.hands[i];
|
||||||
|
if (hand->hand_tracker != XR_NULL_HANDLE) {
|
||||||
|
this->xr.DestroyHandTrackerEXT(hand->hand_tracker);
|
||||||
|
hand->hand_tracker = XR_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->xr.hand_tracking_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this->xr.hand_tracking_enabled) {
|
||||||
|
for (size_t i = 0; i < 2; i++) {
|
||||||
|
this->xr.hands[i].hand_tracker = XR_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
this->xr.hand_tracking_system_properties.supportsHandTracking
|
||||||
|
= XR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(extension_properties);
|
free(extension_properties);
|
||||||
|
|||||||
Reference in New Issue
Block a user