Compare commits
6 Commits
greasepenc
...
xr-world-n
Author | SHA1 | Date | |
---|---|---|---|
9976bd76d9 | |||
4449f53786 | |||
f700f6902a | |||
91323b6827 | |||
![]() |
149d4167a9 | ||
![]() |
8253dc47a6 |
@@ -158,7 +158,7 @@ def submodules_update(args, release_version, branch):
|
||||
branch = "master"
|
||||
|
||||
submodules = [
|
||||
("release/scripts/addons", branch),
|
||||
("release/scripts/addons", "xr-world-navigation"),
|
||||
("release/scripts/addons_contrib", branch),
|
||||
("release/datafiles/locale", branch),
|
||||
("source/tools", branch),
|
||||
|
@@ -654,6 +654,33 @@ typedef struct {
|
||||
void *exit_customdata;
|
||||
} GHOST_XrSessionBeginInfo;
|
||||
|
||||
typedef struct GHOST_XrControllersDataInfo {
|
||||
GHOST_XrPose left_pose;
|
||||
GHOST_XrPose right_pose;
|
||||
float left_trigger_value;
|
||||
float right_trigger_value;
|
||||
char left_trigger_touch;
|
||||
char right_trigger_touch;
|
||||
float left_grip_value;
|
||||
float right_grip_value;
|
||||
char left_primary_click;
|
||||
char left_primary_touch;
|
||||
char left_secondary_click;
|
||||
char left_secondary_touch;
|
||||
char right_primary_click;
|
||||
char right_primary_touch;
|
||||
char right_secondary_click;
|
||||
char right_secondary_touch;
|
||||
float left_thumbstick_x;
|
||||
float left_thumbstick_y;
|
||||
char left_thumbstick_click;
|
||||
char left_thumbstick_touch;
|
||||
float right_thumbstick_x;
|
||||
float right_thumbstick_y;
|
||||
char right_thumbstick_click;
|
||||
char right_thumbstick_touch;
|
||||
} GHOST_XrControllersDataInfo;
|
||||
|
||||
typedef struct GHOST_XrDrawViewInfo {
|
||||
int ofsx, ofsy;
|
||||
int width, height;
|
||||
@@ -668,6 +695,13 @@ typedef struct GHOST_XrDrawViewInfo {
|
||||
|
||||
/** Set if the buffer should be submitted with a srgb transfer applied. */
|
||||
char expects_srgb_buffer;
|
||||
|
||||
/** World transform */
|
||||
GHOST_XrPose world_pose;
|
||||
float world_scale;
|
||||
|
||||
/** Controllers poses and input states */
|
||||
GHOST_XrControllersDataInfo controllers_data;
|
||||
} GHOST_XrDrawViewInfo;
|
||||
|
||||
typedef struct GHOST_XrError {
|
||||
|
@@ -458,8 +458,15 @@ void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info)
|
||||
m_custom_funcs.session_exit_customdata = begin_info->exit_customdata;
|
||||
|
||||
if (m_session == nullptr) {
|
||||
if (isDebugMode()) printf("Create a new session object.\n");
|
||||
m_session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDebugMode()) printf("DONT Create a new session object, previous one is still != null.\n");
|
||||
}
|
||||
|
||||
if (isDebugMode()) printf("Start the session.\n");
|
||||
m_session->start(begin_info);
|
||||
}
|
||||
|
||||
@@ -467,9 +474,13 @@ void GHOST_XrContext::endSession()
|
||||
{
|
||||
if (m_session) {
|
||||
if (m_session->isRunning()) {
|
||||
if (isDebugMode())
|
||||
printf("Request Session End.\n");
|
||||
m_session->requestEnd();
|
||||
}
|
||||
else {
|
||||
if (isDebugMode())
|
||||
printf("Session state is IDLE, destroying it.\n");
|
||||
m_session = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -491,7 +502,7 @@ void GHOST_XrContext::drawSessionViews(void *draw_customdata)
|
||||
void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged *lifecycle)
|
||||
{
|
||||
if (m_session &&
|
||||
m_session->handleStateChangeEvent(lifecycle) == GHOST_XrSession::SESSION_DESTROY) {
|
||||
m_session->handleStateChangeEvent(lifecycle, isDebugMode()) == GHOST_XrSession::SESSION_DESTROY) {
|
||||
m_session = nullptr;
|
||||
}
|
||||
}
|
||||
|
@@ -24,13 +24,37 @@
|
||||
#include "GHOST_XrContext.h"
|
||||
#include "GHOST_Xr_intern.h"
|
||||
|
||||
static bool GHOST_XrEventPollNext(XrInstance instance, XrEventDataBuffer &r_event_data)
|
||||
static bool GHOST_XrEventPollNext(XrInstance instance, XrEventDataBuffer &r_event_data, bool debug)
|
||||
{
|
||||
/* (Re-)initialize as required by specification. */
|
||||
r_event_data.type = XR_TYPE_EVENT_DATA_BUFFER;
|
||||
r_event_data.next = nullptr;
|
||||
|
||||
return (xrPollEvent(instance, &r_event_data) == XR_SUCCESS);
|
||||
XrResult result = xrPollEvent(instance, &r_event_data);
|
||||
bool success = (result == XR_SUCCESS);
|
||||
if (!success) {
|
||||
switch (result) {
|
||||
case XR_EVENT_UNAVAILABLE:
|
||||
/* printf("FAIL Event received: XR_EVENT_UNAVAILABLE\n"); // spammy, no print here, we have this event every time nothing gets polled. */
|
||||
break;
|
||||
case XR_ERROR_INSTANCE_LOST:
|
||||
if (debug) printf("POLL Fail Event received: XR_ERROR_INSTANCE_LOST\n");
|
||||
break;
|
||||
case XR_ERROR_RUNTIME_FAILURE:
|
||||
if (debug) printf("POLL Fail Event received: XR_ERROR_RUNTIME_FAILURE\n");
|
||||
break;
|
||||
case XR_ERROR_HANDLE_INVALID:
|
||||
if (debug) printf("POLL Fail Event received: XR_ERROR_HANDLE_INVALID\n");
|
||||
break;
|
||||
case XR_ERROR_VALIDATION_FAILURE:
|
||||
if (debug) printf("POLL Fail Event received: XR_ERROR_VALIDATION_FAILURE\n");
|
||||
break;
|
||||
default:
|
||||
if (debug) printf("POLL Fail Event received(should not happen): %i\n", result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_contexthandle)
|
||||
@@ -42,21 +66,90 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_contexthandle)
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
while (GHOST_XrEventPollNext(xr_context->getInstance(), event_buffer)) {
|
||||
while (GHOST_XrEventPollNext(xr_context->getInstance(), event_buffer, xr_context->isDebugMode())) {
|
||||
XrEventDataBaseHeader *event = (XrEventDataBaseHeader *)&event_buffer;
|
||||
|
||||
switch (event->type) {
|
||||
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
|
||||
xr_context->handleSessionStateChange((XrEventDataSessionStateChanged *)event);
|
||||
return GHOST_kSuccess;
|
||||
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
|
||||
GHOST_XrContextDestroy(xr_contexthandle);
|
||||
return GHOST_kSuccess;
|
||||
default:
|
||||
if (xr_context->isDebugMode()) {
|
||||
printf("Unhandled event: %i\n", event->type);
|
||||
/*
|
||||
XR_TYPE_EVENT_DATA_EVENTS_LOST (XrEventDataEventsLost *)event .lostEventCount = number of removed events because of overflow of events.
|
||||
XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING (XrEventDataInstanceLossPending *)event .lossTime = application if about to loose the instance (occurs when software updates)
|
||||
XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED (XrEventDataInteractionProfileChanged *)event .session = bla bla bla
|
||||
XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING (XrEventDataReferenceSpaceChangePending *)event quand on recentre la vue. la struct contient la pose dans le precedent espace et le temps avant que l'api retourne des poses dans le nouvel espace.
|
||||
XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED (XrEventDataSessionStateChanged *)event lifecycle change of an XrSession, with a new XrSessionState
|
||||
XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT (...)
|
||||
XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR (...)
|
||||
XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX (...)
|
||||
*/
|
||||
case XR_TYPE_EVENT_DATA_EVENTS_LOST:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
XrEventDataEventsLost* e = (XrEventDataEventsLost*)event;
|
||||
printf("Event XR_TYPE_EVENT_DATA_EVENTS_LOST received. LostEventCount = %d\n", e->lostEventCount);
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
printf("Event XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED => ");
|
||||
}
|
||||
xr_context->handleSessionStateChange((XrEventDataSessionStateChanged *)event);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
XrEventDataInteractionProfileChanged *e = (XrEventDataInteractionProfileChanged *)event;
|
||||
printf("Event XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED received.\n");
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
XrEventDataReferenceSpaceChangePending *e = (XrEventDataReferenceSpaceChangePending *)event;
|
||||
printf("Event XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING received.\n");
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
XrEventDataInstanceLossPending *e = (XrEventDataInstanceLossPending *)event;
|
||||
printf("Event XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING received. LossTime: %d\n", e->lossTime);
|
||||
}
|
||||
GHOST_XrContextDestroy(xr_contexthandle);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
printf("Event XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT received.\n");
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
printf("Event XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR received.\n");
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (xr_context->isDebugMode())
|
||||
{
|
||||
printf("Unhandled event: %i\n", event->type);
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
@@ -35,6 +36,46 @@
|
||||
|
||||
#include "GHOST_XrSession.h"
|
||||
|
||||
/** Oculus Touch OpenXR profile data */
|
||||
struct OculusTouchProfile {
|
||||
bool valid;
|
||||
|
||||
XrActionSet actionSet;
|
||||
XrPath handPaths[2];
|
||||
XrSpace handSpaces[2];
|
||||
|
||||
/* Common actions for each hands */
|
||||
XrAction squeezeValueAction;
|
||||
XrAction triggerValueAction;
|
||||
XrAction triggerTouchAction;
|
||||
XrAction thumbstickXAction;
|
||||
XrAction thumbstickYAction;
|
||||
XrAction thumbstickClickAction;
|
||||
XrAction thumbstickTouchAction;
|
||||
XrAction thumbrestTouchAction;
|
||||
XrAction gripPoseAction;
|
||||
XrAction aimPoseAction;
|
||||
XrAction hapticAction;
|
||||
|
||||
/* Specific hand actions */
|
||||
XrAction leftXClickAction;
|
||||
XrAction leftXTouchAction;
|
||||
XrAction leftYClickAction;
|
||||
XrAction leftYTouchAction;
|
||||
XrAction leftMenuClickAction;
|
||||
|
||||
XrAction rightAClickAction;
|
||||
XrAction rightATouchAction;
|
||||
XrAction rightBClickAction;
|
||||
XrAction rightBTouchAction;
|
||||
XrAction rightSystemClickAction;
|
||||
};
|
||||
|
||||
enum class OpenXrProfile {
|
||||
UNKNOWN,
|
||||
OCULUS_TOUCH
|
||||
};
|
||||
|
||||
struct OpenXRSessionData {
|
||||
XrSystemId system_id = XR_NULL_SYSTEM_ID;
|
||||
XrSession session = XR_NULL_HANDLE;
|
||||
@@ -46,6 +87,9 @@ struct OpenXRSessionData {
|
||||
XrSpace view_space;
|
||||
std::vector<XrView> views;
|
||||
std::vector<GHOST_XrSwapchain> swapchains;
|
||||
|
||||
OpenXrProfile detectedProfile = OpenXrProfile::UNKNOWN;
|
||||
OculusTouchProfile oculusTouchProfile;
|
||||
};
|
||||
|
||||
struct GHOST_XrDrawInfo {
|
||||
@@ -57,6 +101,36 @@ struct GHOST_XrDrawInfo {
|
||||
std::list<double> last_frame_times;
|
||||
};
|
||||
|
||||
/* One structure for all devices */
|
||||
struct GHOST_XrControllersData {
|
||||
XrPosef left_pose;
|
||||
float left_trigger_value;
|
||||
bool left_trigger_touch;
|
||||
float left_grip_value;
|
||||
bool left_primary_click;
|
||||
bool left_primary_touch;
|
||||
bool left_secondary_click;
|
||||
bool left_secondary_touch;
|
||||
|
||||
XrPosef right_pose;
|
||||
float right_trigger_value;
|
||||
bool right_trigger_touch;
|
||||
float right_grip_value;
|
||||
bool right_primary_click;
|
||||
bool right_primary_touch;
|
||||
bool right_secondary_click;
|
||||
bool right_secondary_touch;
|
||||
|
||||
float left_thumbstick_x;
|
||||
float left_thumbstick_y;
|
||||
bool left_thumbstick_click;
|
||||
bool left_thumbstick_touch;
|
||||
float right_thumbstick_x;
|
||||
float right_thumbstick_y;
|
||||
bool right_thumbstick_click;
|
||||
bool right_thumbstick_touch;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Create, Initialize and Destruct
|
||||
*
|
||||
@@ -71,6 +145,13 @@ GHOST_XrSession::~GHOST_XrSession()
|
||||
{
|
||||
unbindGraphicsContext();
|
||||
|
||||
/* Destroy action set (which also destroy all handles of actions in that action set) */
|
||||
switch (m_oxr->detectedProfile) {
|
||||
case OpenXrProfile::OCULUS_TOUCH:
|
||||
xrDestroyActionSet(m_oxr->oculusTouchProfile.actionSet);
|
||||
break;
|
||||
}
|
||||
|
||||
m_oxr->swapchains.clear();
|
||||
|
||||
if (m_oxr->reference_space != XR_NULL_HANDLE) {
|
||||
@@ -104,6 +185,18 @@ void GHOST_XrSession::initSystem()
|
||||
|
||||
CHECK_XR(xrGetSystem(m_context->getInstance(), &system_info, &m_oxr->system_id),
|
||||
"Failed to get device information. Is a device plugged in?");
|
||||
|
||||
/* Get detected device */
|
||||
XrSystemProperties xrSystemProperties = {XR_TYPE_SYSTEM_PROPERTIES};
|
||||
xrSystemProperties.next = NULL;
|
||||
xrSystemProperties.graphicsProperties = {0};
|
||||
xrSystemProperties.trackingProperties = {0};
|
||||
CHECK_XR(xrGetSystemProperties(m_context->getInstance(), m_oxr->system_id, &xrSystemProperties),
|
||||
"Failed to get system properties.");
|
||||
|
||||
if (strcmp(xrSystemProperties.systemName, "Quest") == 0 || strcmp(xrSystemProperties.systemName, "Oculus Rift S") == 0) {
|
||||
m_oxr->detectedProfile = OpenXrProfile::OCULUS_TOUCH;
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */ /* Create, Initialize and Destruct */
|
||||
@@ -150,6 +243,458 @@ static void create_reference_spaces(OpenXRSessionData *oxr, const GHOST_XrPose *
|
||||
"Failed to create view reference space.");
|
||||
}
|
||||
|
||||
/* Helper function to create and bind an OpenXR action */
|
||||
static void create_and_bind_xr_action(XrInstance xrInstance,
|
||||
XrActionSet actionSet,
|
||||
const XrActionCreateInfo *actionInfo,
|
||||
XrAction *action,
|
||||
std::vector<XrActionSuggestedBinding> &bindings,
|
||||
const std::vector<std::string> &paths)
|
||||
{
|
||||
std::string error_msg = "failed to create \"";
|
||||
error_msg += actionInfo->actionName;
|
||||
error_msg += "\" action";
|
||||
CHECK_XR(xrCreateAction(actionSet, actionInfo, action), error_msg.c_str());
|
||||
for (int i = 0; i < paths.size(); ++i) {
|
||||
XrPath xrPaths;
|
||||
xrStringToPath(xrInstance, paths[i].c_str(), &xrPaths);
|
||||
bindings.push_back(XrActionSuggestedBinding{*action, xrPaths});
|
||||
}
|
||||
}
|
||||
|
||||
static void init_xr_oculus_touch_profile(OpenXRSessionData *oxr, XrInstance xrInstance)
|
||||
{
|
||||
OculusTouchProfile *profile = &oxr->oculusTouchProfile;
|
||||
|
||||
/* Create action set */
|
||||
XrActionSetCreateInfo actionSetInfo = {XR_TYPE_ACTION_SET_CREATE_INFO};
|
||||
actionSetInfo.next = NULL;
|
||||
actionSetInfo.priority = 0;
|
||||
strcpy(actionSetInfo.actionSetName, "actionset");
|
||||
strcpy(actionSetInfo.localizedActionSetName, "ActionSet");
|
||||
CHECK_XR(xrCreateActionSet(xrInstance, &actionSetInfo, &profile->actionSet),
|
||||
"Failed to create action set.");
|
||||
|
||||
/* Create common actions for each hand */
|
||||
int const handsCount = 2;
|
||||
xrStringToPath(xrInstance, "/user/hand/left", &profile->handPaths[0]);
|
||||
xrStringToPath(xrInstance, "/user/hand/right", &profile->handPaths[1]);
|
||||
|
||||
std::vector<XrActionSuggestedBinding> bindings;
|
||||
|
||||
XrActionCreateInfo actionInfo = {XR_TYPE_ACTION_CREATE_INFO};
|
||||
actionInfo.next = NULL;
|
||||
actionInfo.countSubactionPaths = handsCount;
|
||||
actionInfo.subactionPaths = profile->handPaths;
|
||||
|
||||
/* ...of type float */
|
||||
actionInfo.actionType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||
|
||||
strcpy(actionInfo.actionName, "trigger");
|
||||
strcpy(actionInfo.localizedActionName, "Trigger Value");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->triggerValueAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value"});
|
||||
|
||||
strcpy(actionInfo.actionName, "squeeze");
|
||||
strcpy(actionInfo.localizedActionName, "Squeeze Value");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->squeezeValueAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value"});
|
||||
|
||||
strcpy(actionInfo.actionName, "thumbstick_x");
|
||||
strcpy(actionInfo.localizedActionName, "Thumbstick X Value");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->thumbstickXAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/thumbstick/x", "/user/hand/right/input/thumbstick/x"});
|
||||
|
||||
strcpy(actionInfo.actionName, "thumbstick_y");
|
||||
strcpy(actionInfo.localizedActionName, "Thumbstick Y Value");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->thumbstickYAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/thumbstick/y", "/user/hand/right/input/thumbstick/y"});
|
||||
|
||||
/* ...of type bool */
|
||||
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
|
||||
|
||||
strcpy(actionInfo.actionName, "thumbstickclick");
|
||||
strcpy(actionInfo.localizedActionName, "Thumbstick Click");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->thumbstickClickAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click"});
|
||||
|
||||
strcpy(actionInfo.actionName, "thumbsticktouch");
|
||||
strcpy(actionInfo.localizedActionName, "Thumbstick Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->thumbstickTouchAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch"});
|
||||
|
||||
strcpy(actionInfo.actionName, "triggertouch");
|
||||
strcpy(actionInfo.localizedActionName, "Trigger Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->triggerTouchAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch"});
|
||||
|
||||
/* ...of type haptic */
|
||||
actionInfo.actionType = XR_ACTION_TYPE_VIBRATION_OUTPUT;
|
||||
|
||||
strcpy(actionInfo.actionName, "haptic");
|
||||
strcpy(actionInfo.localizedActionName, "Haptic");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->hapticAction,
|
||||
bindings,
|
||||
{"/user/hand/left/output/haptic", "/user/hand/right/output/haptic"});
|
||||
|
||||
/* ...of type pose */
|
||||
actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT;
|
||||
|
||||
strcpy(actionInfo.actionName, "handpose");
|
||||
strcpy(actionInfo.localizedActionName, "Hand Pose");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->gripPoseAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose"});
|
||||
|
||||
/* Create spaces for poses */
|
||||
XrActionSpaceCreateInfo actionSpaceInfo = {XR_TYPE_ACTION_SPACE_CREATE_INFO};
|
||||
actionSpaceInfo.next = NULL;
|
||||
actionSpaceInfo.action = profile->gripPoseAction;
|
||||
actionSpaceInfo.poseInActionSpace.orientation.w = 1.f;
|
||||
actionSpaceInfo.subactionPath = profile->handPaths[0];
|
||||
CHECK_XR(xrCreateActionSpace(oxr->session, &actionSpaceInfo, &profile->handSpaces[0]),
|
||||
"failed to create left hand pose space");
|
||||
|
||||
actionSpaceInfo.subactionPath = profile->handPaths[1];
|
||||
CHECK_XR(xrCreateActionSpace(oxr->session, &actionSpaceInfo, &profile->handSpaces[1]),
|
||||
"failed to create right hand pose space");
|
||||
|
||||
/* Create unique actions of each hand */
|
||||
actionInfo.countSubactionPaths = 0;
|
||||
actionInfo.subactionPaths = NULL;
|
||||
|
||||
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
|
||||
|
||||
strcpy(actionInfo.actionName, "leftxclick");
|
||||
strcpy(actionInfo.localizedActionName, "Left X Click");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->leftXClickAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/x/click"});
|
||||
|
||||
strcpy(actionInfo.actionName, "leftxtouch");
|
||||
strcpy(actionInfo.localizedActionName, "Left X Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->leftXTouchAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/x/touch"});
|
||||
|
||||
strcpy(actionInfo.actionName, "leftyclick");
|
||||
strcpy(actionInfo.localizedActionName, "Left Y Click");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->leftYClickAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/y/click"});
|
||||
|
||||
strcpy(actionInfo.actionName, "leftytouch");
|
||||
strcpy(actionInfo.localizedActionName, "Left Y Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->leftYTouchAction,
|
||||
bindings,
|
||||
{"/user/hand/left/input/y/touch"});
|
||||
|
||||
strcpy(actionInfo.actionName, "rightaclick");
|
||||
strcpy(actionInfo.localizedActionName, "Right A Click");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->rightAClickAction,
|
||||
bindings,
|
||||
{"/user/hand/right/input/a/click"});
|
||||
|
||||
strcpy(actionInfo.actionName, "rightatouch");
|
||||
strcpy(actionInfo.localizedActionName, "Right A Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->rightATouchAction,
|
||||
bindings,
|
||||
{"/user/hand/right/input/a/touch"});
|
||||
|
||||
strcpy(actionInfo.actionName, "rightbclick");
|
||||
strcpy(actionInfo.localizedActionName, "Right B Click");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->rightBClickAction,
|
||||
bindings,
|
||||
{"/user/hand/right/input/b/click"});
|
||||
|
||||
strcpy(actionInfo.actionName, "rightbtouch");
|
||||
strcpy(actionInfo.localizedActionName, "Right B Touch");
|
||||
create_and_bind_xr_action(xrInstance,
|
||||
profile->actionSet,
|
||||
&actionInfo,
|
||||
&profile->rightBTouchAction,
|
||||
bindings,
|
||||
{"/user/hand/right/input/b/touch"});
|
||||
|
||||
/* Create interaction profile */
|
||||
XrPath oculusInteractionProfilePath;
|
||||
CHECK_XR(xrStringToPath(xrInstance,
|
||||
"/interaction_profiles/oculus/touch_controller",
|
||||
&oculusInteractionProfilePath),
|
||||
"failed to get oculus interaction profile");
|
||||
|
||||
/* Suggest bindings */
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {
|
||||
XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING};
|
||||
suggestedBindings.interactionProfile = oculusInteractionProfilePath;
|
||||
suggestedBindings.countSuggestedBindings = bindings.size();
|
||||
suggestedBindings.suggestedBindings = bindings.data();
|
||||
CHECK_XR(xrSuggestInteractionProfileBindings(xrInstance, &suggestedBindings),
|
||||
"failed to suggest bindings");
|
||||
|
||||
/* Attach action set to session */
|
||||
XrSessionActionSetsAttachInfo attachInfo = {XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO};
|
||||
attachInfo.next = NULL;
|
||||
attachInfo.countActionSets = 1;
|
||||
attachInfo.actionSets = &profile->actionSet;
|
||||
CHECK_XR(xrAttachSessionActionSets(oxr->session, &attachInfo), "failed to attach action set");
|
||||
|
||||
profile->valid = true;
|
||||
}
|
||||
|
||||
static void init_xr_controllers(OpenXRSessionData* oxr, XrInstance xrInstance)
|
||||
{
|
||||
switch (oxr->detectedProfile) {
|
||||
case OpenXrProfile::OCULUS_TOUCH:
|
||||
init_xr_oculus_touch_profile(oxr, xrInstance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fetch_oculus_touch_xr_data(OpenXRSessionData *oxr,
|
||||
GHOST_XrDrawInfo *drawInfo,
|
||||
GHOST_XrControllersData &controllers_data)
|
||||
{
|
||||
OculusTouchProfile profile = oxr->oculusTouchProfile;
|
||||
if (!profile.valid) {
|
||||
throw GHOST_XrException(
|
||||
"Unable to fetch Oculus Touch controllers data: profile not initialized");
|
||||
}
|
||||
|
||||
/* Retrieve active action set */
|
||||
const XrActiveActionSet activeActionSet = {profile.actionSet, XR_NULL_PATH};
|
||||
|
||||
XrActionsSyncInfo syncInfo = {XR_TYPE_ACTIONS_SYNC_INFO};
|
||||
syncInfo.countActiveActionSets = 1;
|
||||
syncInfo.activeActionSets = &activeActionSet;
|
||||
CHECK_XR(xrSyncActions(oxr->session, &syncInfo), "failed to sync actions");
|
||||
|
||||
XrActionStateFloat floatState = {XR_TYPE_ACTION_STATE_FLOAT};
|
||||
floatState.next = NULL;
|
||||
XrActionStateBoolean boolState = {XR_TYPE_ACTION_STATE_BOOLEAN};
|
||||
boolState.next = NULL;
|
||||
|
||||
/* Retrieve hands common actions */
|
||||
const int hands = 2;
|
||||
for (int i = 0; i < hands; i++) {
|
||||
XrActionStateGetInfo getInfo = {XR_TYPE_ACTION_STATE_GET_INFO};
|
||||
getInfo.next = NULL;
|
||||
getInfo.subactionPath = profile.handPaths[i];
|
||||
|
||||
/* Trigger values & touch */
|
||||
getInfo.action = profile.triggerValueAction;
|
||||
CHECK_XR(xrGetActionStateFloat(oxr->session, &getInfo, &floatState),
|
||||
"failed to get trigger value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_trigger_value = floatState.currentState;
|
||||
else
|
||||
controllers_data.right_trigger_value = floatState.currentState;
|
||||
|
||||
getInfo.action = profile.triggerTouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get trigger touch!");
|
||||
if (i == 0)
|
||||
controllers_data.left_trigger_touch = boolState.currentState;
|
||||
else
|
||||
controllers_data.right_trigger_touch = boolState.currentState;
|
||||
|
||||
/* Squeeze values */
|
||||
getInfo.action = profile.squeezeValueAction;
|
||||
CHECK_XR(xrGetActionStateFloat(oxr->session, &getInfo, &floatState),
|
||||
"failed to get squeeze value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_grip_value = floatState.currentState;
|
||||
else
|
||||
controllers_data.right_grip_value = floatState.currentState;
|
||||
|
||||
/* Thumbstick X values */
|
||||
getInfo.action = profile.thumbstickXAction;
|
||||
CHECK_XR(xrGetActionStateFloat(oxr->session, &getInfo, &floatState),
|
||||
"failed to get thumb X value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_thumbstick_x = floatState.currentState;
|
||||
else
|
||||
controllers_data.right_thumbstick_x = floatState.currentState;
|
||||
|
||||
/* Thumbstick Y values */
|
||||
getInfo.action = profile.thumbstickYAction;
|
||||
CHECK_XR(xrGetActionStateFloat(oxr->session, &getInfo, &floatState),
|
||||
"failed to get thumb Y value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_thumbstick_y = floatState.currentState;
|
||||
else
|
||||
controllers_data.right_thumbstick_y = floatState.currentState;
|
||||
|
||||
/* Thumbstick click values & touch */
|
||||
getInfo.action = profile.thumbstickClickAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get thumb click value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_thumbstick_click = boolState.currentState;
|
||||
else
|
||||
controllers_data.right_thumbstick_click = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.thumbstickTouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get thumb touch value!");
|
||||
if (i == 0)
|
||||
controllers_data.left_thumbstick_touch = boolState.currentState;
|
||||
else
|
||||
controllers_data.right_thumbstick_touch = boolState.currentState;
|
||||
|
||||
/* Controller action poses */
|
||||
getInfo.action = profile.gripPoseAction;
|
||||
XrActionStatePose poseState = {XR_TYPE_ACTION_STATE_POSE};
|
||||
poseState.next = NULL;
|
||||
CHECK_XR(xrGetActionStatePose(oxr->session, &getInfo, &poseState),
|
||||
"failed to get pose value!");
|
||||
}
|
||||
|
||||
/* Left hand */
|
||||
XrActionStateGetInfo getInfo = {XR_TYPE_ACTION_STATE_GET_INFO};
|
||||
getInfo.next = NULL;
|
||||
getInfo.subactionPath = profile.handPaths[0];
|
||||
|
||||
getInfo.action = profile.leftXClickAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get left X click value!");
|
||||
controllers_data.left_primary_click = boolState.currentState;
|
||||
/*controllers_data.left_primary_onpress = boolState.changedSinceLastSync &&
|
||||
boolState.currentState;
|
||||
controllers_data.left_primary_onrelease = boolState.changedSinceLastSync &&
|
||||
!boolState.currentState;*/
|
||||
|
||||
getInfo.action = profile.leftXTouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get left X touch value!");
|
||||
controllers_data.left_primary_touch = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.leftYClickAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get left X click value!");
|
||||
controllers_data.left_secondary_click = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.leftYTouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get left Y touch value!");
|
||||
controllers_data.left_secondary_touch = boolState.currentState;
|
||||
|
||||
/* Right hand */
|
||||
getInfo.subactionPath = profile.handPaths[1];
|
||||
|
||||
getInfo.action = profile.rightAClickAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get right A click value!");
|
||||
controllers_data.right_primary_click = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.rightATouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get right A touch value!");
|
||||
controllers_data.right_primary_touch = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.rightBClickAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get right B click value!");
|
||||
controllers_data.right_secondary_click = boolState.currentState;
|
||||
|
||||
getInfo.action = profile.rightBTouchAction;
|
||||
CHECK_XR(xrGetActionStateBoolean(oxr->session, &getInfo, &boolState),
|
||||
"failed to get right B touch value!");
|
||||
controllers_data.right_secondary_touch = boolState.currentState;
|
||||
|
||||
/* Retrieve controller spaces */
|
||||
XrSpaceLocation spaceLocation[hands];
|
||||
bool spaceLocationValid[hands];
|
||||
for (int i = 0; i < hands; i++) {
|
||||
spaceLocation[i].type = XR_TYPE_SPACE_LOCATION;
|
||||
spaceLocation[i].next = NULL;
|
||||
|
||||
CHECK_XR(xrLocateSpace(profile.handSpaces[i],
|
||||
oxr->reference_space,
|
||||
drawInfo->frame_state.predictedDisplayTime,
|
||||
&spaceLocation[i]),
|
||||
"failed to locate space!");
|
||||
spaceLocationValid[i] =
|
||||
//(spaceLocation[i].locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0 &&
|
||||
(spaceLocation[i].locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) != 0;
|
||||
|
||||
if (spaceLocationValid[i]) {
|
||||
if (i == 0) {
|
||||
memcpy(&controllers_data.left_pose, &spaceLocation[i].pose, sizeof(XrPosef));
|
||||
}
|
||||
else {
|
||||
memcpy(&controllers_data.right_pose, &spaceLocation[i].pose, sizeof(XrPosef));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_xr_controllers_data(OpenXRSessionData *oxr,
|
||||
GHOST_XrDrawInfo *drawInfo,
|
||||
GHOST_XrControllersData& controllers_data)
|
||||
{
|
||||
switch (oxr->detectedProfile) {
|
||||
case OpenXrProfile::OCULUS_TOUCH:
|
||||
fetch_oculus_touch_xr_data(oxr, drawInfo, controllers_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
|
||||
{
|
||||
assert(m_context->getInstance() != XR_NULL_HANDLE);
|
||||
@@ -195,12 +740,15 @@ void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
|
||||
"detailed error information to the command line.");
|
||||
|
||||
prepareDrawing();
|
||||
|
||||
create_reference_spaces(m_oxr.get(), &begin_info->base_pose);
|
||||
|
||||
init_xr_controllers(m_oxr.get(), m_context->getInstance());
|
||||
}
|
||||
|
||||
void GHOST_XrSession::requestEnd()
|
||||
{
|
||||
xrRequestExitSession(m_oxr->session);
|
||||
CHECK_XR(xrRequestExitSession(m_oxr->session), "Failed to request the end of the session.");
|
||||
}
|
||||
|
||||
void GHOST_XrSession::beginSession()
|
||||
@@ -217,7 +765,8 @@ void GHOST_XrSession::endSession()
|
||||
}
|
||||
|
||||
GHOST_XrSession::LifeExpectancy GHOST_XrSession::handleStateChangeEvent(
|
||||
const XrEventDataSessionStateChanged *lifecycle)
|
||||
const XrEventDataSessionStateChanged *lifecycle,
|
||||
bool debug)
|
||||
{
|
||||
m_oxr->session_state = lifecycle->state;
|
||||
|
||||
@@ -225,16 +774,47 @@ GHOST_XrSession::LifeExpectancy GHOST_XrSession::handleStateChangeEvent(
|
||||
assert((m_oxr->session == XR_NULL_HANDLE) || (m_oxr->session == lifecycle->session));
|
||||
|
||||
switch (lifecycle->state) {
|
||||
case XR_SESSION_STATE_IDLE:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_IDLE.\n");
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_READY: {
|
||||
if (debug) printf("XR_SESSION_STATE_READY.\n");
|
||||
beginSession();
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_STOPPING:
|
||||
endSession();
|
||||
break;
|
||||
case XR_SESSION_STATE_SYNCHRONIZED:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_SYNCHRONIZED.\n");
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_VISIBLE:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_VISIBLE.\n");
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_FOCUSED:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_FOCUSED.\n");
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_STOPPING:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_STOPPING.\n");
|
||||
endSession();
|
||||
break;
|
||||
}
|
||||
case XR_SESSION_STATE_EXITING:
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_EXITING.\n");
|
||||
return SESSION_DESTROY;
|
||||
}
|
||||
case XR_SESSION_STATE_LOSS_PENDING:
|
||||
return SESSION_DESTROY;
|
||||
{
|
||||
if (debug) printf("XR_SESSION_STATE_LOSS_PENDING.\n");
|
||||
return SESSION_DESTROY;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -352,7 +932,7 @@ void GHOST_XrSession::draw(void *draw_customdata)
|
||||
endFrameDrawing(&layers);
|
||||
}
|
||||
|
||||
static void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose &r_ghost_pose)
|
||||
static void copy_openxr_pose_to_ghost_pose(GHOST_XrPose &r_ghost_pose, const XrPosef &oxr_pose)
|
||||
{
|
||||
/* Set and convert to Blender coodinate space. */
|
||||
r_ghost_pose.position[0] = oxr_pose.position.x;
|
||||
@@ -367,7 +947,7 @@ static void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose
|
||||
static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawViewInfo &r_info)
|
||||
{
|
||||
/* Set and convert to Blender coodinate space. */
|
||||
copy_openxr_pose_to_ghost_pose(view.pose, r_info.eye_pose);
|
||||
copy_openxr_pose_to_ghost_pose(r_info.eye_pose, view.pose);
|
||||
|
||||
r_info.fov.angle_left = view.fov.angleLeft;
|
||||
r_info.fov.angle_right = view.fov.angleRight;
|
||||
@@ -383,14 +963,49 @@ static bool ghost_xr_draw_view_expects_srgb_buffer(const GHOST_XrContext *contex
|
||||
return (context->getOpenXRRuntimeID() == OPENXR_RUNTIME_MONADO);
|
||||
}
|
||||
|
||||
static void copy_controllers_data_to_draw_view_info(GHOST_XrDrawViewInfo *draw_view_info, GHOST_XrControllersData const &controllers_data)
|
||||
{
|
||||
copy_openxr_pose_to_ghost_pose(draw_view_info->controllers_data.left_pose, controllers_data.left_pose);
|
||||
copy_openxr_pose_to_ghost_pose(draw_view_info->controllers_data.right_pose, controllers_data.right_pose);
|
||||
draw_view_info->controllers_data.left_grip_value = controllers_data.left_grip_value;
|
||||
draw_view_info->controllers_data.right_grip_value = controllers_data.right_grip_value;
|
||||
|
||||
draw_view_info->controllers_data.left_trigger_value = controllers_data.left_trigger_value;
|
||||
draw_view_info->controllers_data.left_trigger_touch = controllers_data.left_trigger_touch;
|
||||
draw_view_info->controllers_data.right_trigger_value = controllers_data.right_trigger_value;
|
||||
draw_view_info->controllers_data.right_trigger_touch = controllers_data.right_trigger_touch;
|
||||
|
||||
draw_view_info->controllers_data.left_thumbstick_x = controllers_data.left_thumbstick_x;
|
||||
draw_view_info->controllers_data.left_thumbstick_y = controllers_data.left_thumbstick_y;
|
||||
draw_view_info->controllers_data.left_thumbstick_click = controllers_data.left_thumbstick_click;
|
||||
draw_view_info->controllers_data.left_thumbstick_touch = controllers_data.left_thumbstick_touch;
|
||||
|
||||
draw_view_info->controllers_data.right_thumbstick_x = controllers_data.right_thumbstick_x;
|
||||
draw_view_info->controllers_data.right_thumbstick_y = controllers_data.right_thumbstick_y;
|
||||
draw_view_info->controllers_data.right_thumbstick_click = controllers_data.right_thumbstick_click;
|
||||
draw_view_info->controllers_data.right_thumbstick_touch = controllers_data.right_thumbstick_touch;
|
||||
|
||||
draw_view_info->controllers_data.left_primary_click = controllers_data.left_primary_click;
|
||||
draw_view_info->controllers_data.left_primary_touch = controllers_data.left_primary_touch;
|
||||
draw_view_info->controllers_data.left_secondary_click = controllers_data.left_secondary_click;
|
||||
draw_view_info->controllers_data.left_secondary_touch = controllers_data.left_secondary_touch;
|
||||
|
||||
draw_view_info->controllers_data.right_primary_click = controllers_data.right_primary_click;
|
||||
draw_view_info->controllers_data.right_primary_touch = controllers_data.right_primary_touch;
|
||||
draw_view_info->controllers_data.right_secondary_click = controllers_data.right_secondary_click;
|
||||
draw_view_info->controllers_data.right_secondary_touch = controllers_data.right_secondary_touch;
|
||||
}
|
||||
|
||||
void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
XrCompositionLayerProjectionView &r_proj_layer_view,
|
||||
XrSpaceLocation &view_location,
|
||||
XrView &view,
|
||||
GHOST_XrControllersData const& controllers_data,
|
||||
void *draw_customdata)
|
||||
{
|
||||
XrSwapchainImageBaseHeader *swapchain_image = swapchain.acquireDrawableSwapchainImage();
|
||||
GHOST_XrDrawViewInfo draw_view_info = {};
|
||||
copy_controllers_data_to_draw_view_info(&draw_view_info, controllers_data);
|
||||
|
||||
r_proj_layer_view.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
r_proj_layer_view.pose = view.pose;
|
||||
@@ -402,7 +1017,8 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
|
||||
draw_view_info.width = r_proj_layer_view.subImage.imageRect.extent.width;
|
||||
draw_view_info.height = r_proj_layer_view.subImage.imageRect.extent.height;
|
||||
copy_openxr_pose_to_ghost_pose(view_location.pose, draw_view_info.local_pose);
|
||||
copy_openxr_pose_to_ghost_pose(draw_view_info.local_pose, view_location.pose);
|
||||
|
||||
ghost_xr_draw_view_info_from_view(view, draw_view_info);
|
||||
|
||||
/* Draw! */
|
||||
@@ -415,6 +1031,9 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
XrCompositionLayerProjection GHOST_XrSession::drawLayer(
|
||||
std::vector<XrCompositionLayerProjectionView> &r_proj_layer_views, void *draw_customdata)
|
||||
{
|
||||
GHOST_XrControllersData controllersData = {};
|
||||
set_xr_controllers_data(m_oxr.get(), m_draw_info.get(), controllersData);
|
||||
|
||||
XrViewLocateInfo viewloc_info = {XR_TYPE_VIEW_LOCATE_INFO};
|
||||
XrViewState view_state = {XR_TYPE_VIEW_STATE};
|
||||
XrCompositionLayerProjection layer = {XR_TYPE_COMPOSITION_LAYER_PROJECTION};
|
||||
@@ -446,6 +1065,7 @@ XrCompositionLayerProjection GHOST_XrSession::drawLayer(
|
||||
r_proj_layer_views[view_idx],
|
||||
view_location,
|
||||
m_oxr->views[view_idx],
|
||||
controllersData,
|
||||
draw_customdata);
|
||||
}
|
||||
|
||||
@@ -500,6 +1120,7 @@ void GHOST_XrSession::bindGraphicsContext()
|
||||
{
|
||||
const GHOST_XrCustomFuncs &custom_funcs = m_context->getCustomFuncs();
|
||||
assert(custom_funcs.gpu_ctx_bind_fn);
|
||||
|
||||
m_gpu_ctx = static_cast<GHOST_Context *>(custom_funcs.gpu_ctx_bind_fn());
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@ class GHOST_XrContext;
|
||||
class GHOST_XrSwapchain;
|
||||
struct GHOST_XrDrawInfo;
|
||||
struct OpenXRSessionData;
|
||||
struct GHOST_XrControllersData;
|
||||
|
||||
class GHOST_XrSession {
|
||||
public:
|
||||
@@ -44,7 +45,7 @@ class GHOST_XrSession {
|
||||
void start(const GHOST_XrSessionBeginInfo *begin_info);
|
||||
void requestEnd();
|
||||
|
||||
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged *lifecycle);
|
||||
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged *lifecycle, bool debug = false);
|
||||
|
||||
bool isRunning() const;
|
||||
bool needsUpsideDownDrawing() const;
|
||||
@@ -80,6 +81,7 @@ class GHOST_XrSession {
|
||||
XrCompositionLayerProjectionView &r_proj_layer_view,
|
||||
XrSpaceLocation &view_location,
|
||||
XrView &view,
|
||||
GHOST_XrControllersData const& controllers_data,
|
||||
void *draw_customdata);
|
||||
void beginFrameDrawing();
|
||||
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> *layers);
|
||||
|
Submodule release/scripts/addons updated: 44c17b0116...b0b48e88b8
@@ -1634,10 +1634,14 @@ static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
|
||||
bsphere->center[0] = farcenter[0] * z / e;
|
||||
bsphere->center[1] = farcenter[1] * z / e;
|
||||
bsphere->center[2] = z;
|
||||
bsphere->radius = len_v3v3(bsphere->center, farpoint);
|
||||
|
||||
/* Transform to world space. */
|
||||
mul_m4_v3(viewinv, bsphere->center);
|
||||
|
||||
/* In order to compute sphere radius, the farpoint need to be transformed as well */
|
||||
/* (if viewinv contains scaling) */
|
||||
mul_m4_v3(viewinv, farpoint);
|
||||
bsphere->radius = len_v3v3(bsphere->center, farpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -92,6 +92,172 @@ static void rna_XrSessionState_viewer_pose_rotation_get(PointerRNA *ptr, float *
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_XrSessionState_world_location_get(PointerRNA *ptr, float *r_values)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
WM_xr_session_state_world_location_get(xr, r_values);
|
||||
# else
|
||||
UNUSED_VARS(ptr);
|
||||
zero_v3(r_values);
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_XrSessionState_world_location_set(PointerRNA *ptr, float* values)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
WM_xr_session_state_world_location_set(xr, values);
|
||||
# else
|
||||
UNUSED_VARS(ptr);
|
||||
UNUSED_VARS(values);
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_XrSessionState_world_rotation_get(PointerRNA *ptr, float *r_values)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
WM_xr_session_state_world_rotation_get(xr, r_values);
|
||||
# else
|
||||
UNUSED_VARS(ptr);
|
||||
unit_qt(r_values);
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_XrSessionState_world_rotation_set(PointerRNA *ptr, float *values)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
WM_xr_session_state_world_rotation_set(xr, values);
|
||||
#else
|
||||
UNUSED_VARS(ptr);
|
||||
UNUSED_VARS(values);
|
||||
# endif
|
||||
}
|
||||
|
||||
static float rna_XrSessionState_world_scale_get(PointerRNA *ptr)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
return WM_xr_session_state_world_scale_get(xr);
|
||||
# else
|
||||
return 1.f;
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_XrSessionState_world_scale_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
# ifdef WITH_XR_OPENXR
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr);
|
||||
WM_xr_session_state_world_scale_set(xr, value);
|
||||
# else
|
||||
UNUSED_VARS(ptr);
|
||||
UNUSED_VARS(value);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
# ifdef WITH_XR_OPENXR
|
||||
# define rna_XrSessionState(side, attribute, type, clearFn) \
|
||||
static void rna_XrSessionState_##side##_controller_##attribute##_get(PointerRNA * ptr, \
|
||||
type *r_values) \
|
||||
{ \
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr); \
|
||||
WM_xr_session_state_##side##_controller_##attribute##_get(xr, r_values); \
|
||||
}
|
||||
# else
|
||||
# define rna_XrSessionState(name, type, clearFn) \
|
||||
{ \
|
||||
static void rna_XrSessionState_##side##_controller_##attribute##_get(PointerRNA *ptr, \
|
||||
type *r_values) \
|
||||
{ \
|
||||
UNUSED_VARS(ptr); \
|
||||
clearFn(r_values); \
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/* rna_XrSessionState_left_controller_location_get */
|
||||
rna_XrSessionState(left, location, float, zero_v3)
|
||||
|
||||
/* rna_XrSessionState_left_controller_rotation_get */
|
||||
rna_XrSessionState(left, rotation, float, unit_qt)
|
||||
|
||||
/* rna_XrSessionState_right_controller_location_get */
|
||||
rna_XrSessionState(right, location, float, zero_v3)
|
||||
|
||||
/* rna_XrSessionState_right_controller_rotation_get */
|
||||
rna_XrSessionState(right, rotation, float, unit_qt)
|
||||
|
||||
|
||||
# ifdef WITH_XR_OPENXR
|
||||
# define rna_XrSessionControllerValue(side, attribute, type)\
|
||||
static type rna_XrSessionState_##side##_controller_##attribute##_get(PointerRNA *ptr) \
|
||||
{ \
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr); \
|
||||
return WM_xr_session_state_##side##_##attribute##_get(xr); \
|
||||
}
|
||||
# else
|
||||
# define rna_XrSessionControllerButton(side, attribute, type) \
|
||||
static type rna_XrSessionState_##side##_controller_##attribute##_get(PointerRNA *ptr) \
|
||||
{ \
|
||||
const wmXrData *xr = rna_XrSessionState_wm_xr_data_get(ptr); \
|
||||
return (type)0; \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* rna_XrSessionState_left_controller_trigger_value_get */
|
||||
rna_XrSessionControllerValue(left, trigger_value, float)
|
||||
/* rna_XrSessionState_Right_controller_trigger_value_get */
|
||||
rna_XrSessionControllerValue(right, trigger_value, float)
|
||||
/* rna_XrSessionState_left_controller_trigger_touch_get */
|
||||
rna_XrSessionControllerValue(left, trigger_touch, bool)
|
||||
/* rna_XrSessionState_Right_controller_trigger_touch_get */
|
||||
rna_XrSessionControllerValue(right, trigger_touch, bool)
|
||||
|
||||
/* rna_XrSessionState_left_controller_grip_value_get */
|
||||
rna_XrSessionControllerValue(left, grip_value, float)
|
||||
/* rna_XrSessionState_Right_controller_grip_value_get */
|
||||
rna_XrSessionControllerValue(right, grip_value, float)
|
||||
|
||||
/* rna_XrSessionState_left_controller_primary_click_get */
|
||||
rna_XrSessionControllerValue(left, primary_click, bool)
|
||||
/* rna_XrSessionState_left_controller_primary_touch_get */
|
||||
rna_XrSessionControllerValue(left, primary_touch, bool)
|
||||
/* rna_XrSessionState_left_controller_secondary_click_get */
|
||||
rna_XrSessionControllerValue(left, secondary_click, bool)
|
||||
/* rna_XrSessionState_left_controller_secondary_touch_get */
|
||||
rna_XrSessionControllerValue(left, secondary_touch, bool)
|
||||
|
||||
/* rna_XrSessionState_right_controller_primary_click_get */
|
||||
rna_XrSessionControllerValue(right, primary_click, bool)
|
||||
/* rna_XrSessionState_right_controller_primary_touch_get */
|
||||
rna_XrSessionControllerValue(right, primary_touch, bool)
|
||||
/* rna_XrSessionState_right_controller_secondary_click_get */
|
||||
rna_XrSessionControllerValue(right, secondary_click, bool)
|
||||
/* rna_XrSessionState_right_controller_secondary_touch_get */
|
||||
rna_XrSessionControllerValue(right, secondary_touch, bool)
|
||||
|
||||
/* rna_XrSessionState_left_controller_thumbstick_x_get */
|
||||
rna_XrSessionControllerValue(left, thumbstick_x, float)
|
||||
/* rna_XrSessionState_right_controller_thumbstick_x_get */
|
||||
rna_XrSessionControllerValue(right, thumbstick_x, float)
|
||||
|
||||
/* rna_XrSessionState_left_controller_thumbstick_y_get */
|
||||
rna_XrSessionControllerValue(left, thumbstick_y, float)
|
||||
/* rna_XrSessionState_right_controller_thumbstick_y_get */
|
||||
rna_XrSessionControllerValue(right, thumbstick_y, float)
|
||||
|
||||
/* rna_XrSessionState_left_controller_thumbstick_click_get */
|
||||
rna_XrSessionControllerValue(left, thumbstick_click, bool)
|
||||
/* rna_XrSessionState_right_controller_thumbstick_click_get */
|
||||
rna_XrSessionControllerValue(right, thumbstick_click, bool)
|
||||
/* rna_XrSessionState_left_controller_thumbstick_touch_get */
|
||||
rna_XrSessionControllerValue(left, thumbstick_touch, bool)
|
||||
/* rna_XrSessionState_right_controller_thumbstick_touch_get */
|
||||
rna_XrSessionControllerValue(right, thumbstick_touch, bool)
|
||||
|
||||
#else /* RNA_RUNTIME */
|
||||
|
||||
static void rna_def_xr_session_settings(BlenderRNA *brna)
|
||||
@@ -189,6 +355,22 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_xr_define_sized_property(StructRNA *srna,
|
||||
char *name,
|
||||
char *description,
|
||||
char *function_name,
|
||||
PropertySubType sub_type,
|
||||
PropertyType type,
|
||||
int array_size)
|
||||
{
|
||||
PropertyRNA *prop = RNA_def_property(srna, name, type, sub_type);
|
||||
RNA_def_property_array(prop, array_size);
|
||||
RNA_def_property_float_funcs(prop, function_name, NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, name, description);
|
||||
}
|
||||
|
||||
|
||||
static void rna_def_xr_session_state(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -230,6 +412,175 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
|
||||
prop,
|
||||
"Viewer Pose Rotation",
|
||||
"Last known rotation of the viewer pose (center between the eyes) in world space");
|
||||
|
||||
prop = RNA_def_property(srna, "world_location", PROP_FLOAT, PROP_TRANSLATION);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_XrSessionState_world_location_get",
|
||||
"rna_XrSessionState_world_location_set",
|
||||
NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"World Location",
|
||||
"Last known location of the world in world space");
|
||||
|
||||
prop = RNA_def_property(srna, "world_rotation", PROP_FLOAT, PROP_QUATERNION);
|
||||
RNA_def_property_array(prop, 4);
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_XrSessionState_world_rotation_get",
|
||||
"rna_XrSessionState_world_rotation_set",
|
||||
NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"World Rotation",
|
||||
"Last known rotation of the world in world space");
|
||||
|
||||
prop = RNA_def_property(srna, "world_scale", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(
|
||||
prop, "rna_XrSessionState_world_scale_get", "rna_XrSessionState_world_scale_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "World Scale", "Get World Scale Value");
|
||||
|
||||
rna_def_xr_define_sized_property(srna,
|
||||
"left_controller_location",
|
||||
"Last known location of the left controller in world space",
|
||||
"rna_XrSessionState_left_controller_location_get",
|
||||
PROP_TRANSLATION,
|
||||
PROP_FLOAT,
|
||||
3);
|
||||
|
||||
rna_def_xr_define_sized_property(srna,
|
||||
"left_controller_rotation",
|
||||
"Last known rotation of the left controller in world space",
|
||||
"rna_XrSessionState_left_controller_rotation_get",
|
||||
PROP_QUATERNION,
|
||||
PROP_FLOAT,
|
||||
4);
|
||||
|
||||
rna_def_xr_define_sized_property(srna,
|
||||
"right_controller_location",
|
||||
"Last known location of the right controller in world space",
|
||||
"rna_XrSessionState_right_controller_location_get",
|
||||
PROP_TRANSLATION,
|
||||
PROP_FLOAT,
|
||||
3);
|
||||
|
||||
rna_def_xr_define_sized_property(srna,
|
||||
"right_controller_rotation",
|
||||
"Last known rotation of the right controller in world space",
|
||||
"rna_XrSessionState_right_controller_rotation_get",
|
||||
PROP_QUATERNION,
|
||||
PROP_FLOAT,
|
||||
4);
|
||||
|
||||
prop = RNA_def_property(srna, "left_trigger_value", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_left_controller_trigger_value_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Trigger", "Get Left Trigger Value");
|
||||
|
||||
prop = RNA_def_property(srna, "left_trigger_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_trigger_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Trigger Touch", "Get Left Trigger Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "right_trigger_value", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_right_controller_trigger_value_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Trigger", "Get Right Trigger Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_trigger_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_trigger_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Trigger Touch", "Get Right Trigger Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "left_grip_value", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_left_controller_grip_value_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Grip", "Get Left Grip Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_grip_value", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_right_controller_grip_value_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Grip", "Get Right Grip Value");
|
||||
|
||||
prop = RNA_def_property(srna, "left_primary_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_primary_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Primary Click", "Get Left Primary Click");
|
||||
|
||||
prop = RNA_def_property(srna, "left_primary_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_primary_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Primary Touch", "Get Left Primary Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "left_secondary_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_secondary_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Secondary Click", "Get Left Secondary Click");
|
||||
|
||||
prop = RNA_def_property(srna, "left_secondary_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_secondary_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Secondary Touch", "Get Left Secondary Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "right_primary_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_primary_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Primary Click", "Get Right Primary Click");
|
||||
|
||||
prop = RNA_def_property(srna, "right_primary_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_primary_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Primary Touch", "Get Right Primary Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "right_secondary_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_secondary_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Secondary Click", "Get Right Secondary Click");
|
||||
|
||||
prop = RNA_def_property(srna, "right_secondary_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_secondary_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Secondary Touch", "Get Right Secondary Touch");
|
||||
|
||||
prop = RNA_def_property(srna, "left_thumbstick_x", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_left_controller_thumbstick_x_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Thumbstick X", "Get Left Thumbstick X Value");
|
||||
|
||||
prop = RNA_def_property(srna, "left_thumbstick_y", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_left_controller_thumbstick_y_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Thumbstick Y", "Get Left Thumbstick Y Value");
|
||||
|
||||
prop = RNA_def_property(srna, "left_thumbstick_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_thumbstick_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Thumbstick Click", "Get Left Thumbstick Click Value");
|
||||
|
||||
prop = RNA_def_property(srna, "left_thumbstick_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_left_controller_thumbstick_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Left Thumbstick Touch", "Get Left Thumbstick Touch Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_thumbstick_x", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_right_controller_thumbstick_x_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Thumbstick X", "Get Right Thumbstick X Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_thumbstick_y", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_XrSessionState_right_controller_thumbstick_y_get", NULL, NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Thumbstick Y", "Get Right Thumbstick Y Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_thumbstick_click", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_thumbstick_click_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Thumbstick Click", "Get Right Thumbstick Click Value");
|
||||
|
||||
prop = RNA_def_property(srna, "right_thumbstick_touch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_XrSessionState_right_controller_thumbstick_touch_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Right Thumbstick Touch", "Get Right Thumbstick Touch Value");
|
||||
}
|
||||
|
||||
void RNA_def_xr(BlenderRNA *brna)
|
||||
|
@@ -881,6 +881,48 @@ bool WM_xr_session_state_viewer_pose_rotation_get(const wmXrData *xr, float r_ro
|
||||
bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
|
||||
float r_viewmat[4][4],
|
||||
float *r_focal_len);
|
||||
|
||||
/* world */
|
||||
bool WM_xr_session_state_world_location_get(const wmXrData* xr, float r_location[3]);
|
||||
bool WM_xr_session_state_world_location_set(const wmXrData* xr, const float r_location[3]);
|
||||
bool WM_xr_session_state_world_rotation_get(const wmXrData* xr, float r_rotation[4]);
|
||||
bool WM_xr_session_state_world_rotation_set(const wmXrData* xr, const float r_rotation[4]);
|
||||
float WM_xr_session_state_world_scale_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_world_scale_set(const wmXrData* xr, const float scale);
|
||||
bool WM_xr_session_state_world_matrix_get(const wmXrData* xr, float world_matrix[4][4]);
|
||||
|
||||
/* controllers */
|
||||
bool WM_xr_session_state_left_controller_location_get(const wmXrData* xr, float r_location[3]);
|
||||
bool WM_xr_session_state_left_controller_rotation_get(const wmXrData* xr, float r_rotation[4]);
|
||||
bool WM_xr_session_state_right_controller_location_get(const wmXrData* xr, float r_location[3]);
|
||||
bool WM_xr_session_state_right_controller_rotation_get(const wmXrData* xr, float r_rotation[4]);
|
||||
|
||||
float WM_xr_session_state_left_trigger_value_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_trigger_touch_get(const wmXrData* xr);
|
||||
float WM_xr_session_state_right_trigger_value_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_trigger_touch_get(const wmXrData* xr);
|
||||
|
||||
float WM_xr_session_state_left_grip_value_get(const wmXrData* xr);
|
||||
float WM_xr_session_state_right_grip_value_get(const wmXrData* xr);
|
||||
|
||||
bool WM_xr_session_state_left_primary_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_primary_touch_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_secondary_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_secondary_touch_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_primary_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_primary_touch_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_secondary_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_secondary_touch_get(const wmXrData* xr);
|
||||
|
||||
float WM_xr_session_state_left_thumbstick_x_get(const wmXrData* xr);
|
||||
float WM_xr_session_state_left_thumbstick_y_get(const wmXrData* xr);
|
||||
float WM_xr_session_state_right_thumbstick_x_get(const wmXrData* xr);
|
||||
float WM_xr_session_state_right_thumbstick_y_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_thumbstick_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_thumbstick_click_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_left_thumbstick_touch_get(const wmXrData* xr);
|
||||
bool WM_xr_session_state_right_thumbstick_touch_get(const wmXrData* xr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -40,6 +40,8 @@
|
||||
#include "wm_surface.h"
|
||||
#include "wm_xr_intern.h"
|
||||
|
||||
#include "BLI_math_rotation.h"
|
||||
|
||||
typedef struct {
|
||||
wmWindowManager *wm;
|
||||
} wmXrErrorHandlerData;
|
||||
@@ -105,6 +107,13 @@ bool wm_xr_init(wmWindowManager *wm)
|
||||
if (!wm->xr.runtime) {
|
||||
wm->xr.runtime = wm_xr_runtime_data_create();
|
||||
wm->xr.runtime->context = context;
|
||||
|
||||
/* Initialize the "world navigation" matrix */
|
||||
unit_qt(wm->xr.runtime->session_state.world_pose.orientation_quat);
|
||||
wm->xr.runtime->session_state.world_pose.position[0] = 0.f;
|
||||
wm->xr.runtime->session_state.world_pose.position[1] = 0.f;
|
||||
wm->xr.runtime->session_state.world_pose.position[2] = 0.f;
|
||||
wm->xr.runtime->session_state.world_scale = 1.f;
|
||||
}
|
||||
}
|
||||
BLI_assert(wm->xr.runtime && wm->xr.runtime->context);
|
||||
|
@@ -37,7 +37,7 @@
|
||||
#include "wm_surface.h"
|
||||
#include "wm_xr_intern.h"
|
||||
|
||||
void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4])
|
||||
void wm_xr_pose_to_viewmat(float r_viewmat[4][4], const GHOST_XrPose* pose)
|
||||
{
|
||||
float iquat[4];
|
||||
invert_qt_qt_normalized(iquat, pose->orientation_quat);
|
||||
@@ -48,6 +48,7 @@ void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4])
|
||||
static void wm_xr_draw_matrices_create(const wmXrDrawData *draw_data,
|
||||
const GHOST_XrDrawViewInfo *draw_view,
|
||||
const XrSessionSettings *session_settings,
|
||||
float scale,
|
||||
float r_view_mat[4][4],
|
||||
float r_proj_mat[4][4])
|
||||
{
|
||||
@@ -65,15 +66,15 @@ static void wm_xr_draw_matrices_create(const wmXrDrawData *draw_data,
|
||||
draw_view->fov.angle_right,
|
||||
draw_view->fov.angle_up,
|
||||
draw_view->fov.angle_down,
|
||||
session_settings->clip_start,
|
||||
session_settings->clip_end);
|
||||
session_settings->clip_start * scale,
|
||||
session_settings->clip_end * scale);
|
||||
|
||||
float eye_mat[4][4];
|
||||
float base_mat[4][4];
|
||||
|
||||
wm_xr_pose_to_viewmat(&eye_pose, eye_mat);
|
||||
wm_xr_pose_to_viewmat(eye_mat, &eye_pose);
|
||||
/* Calculate the base pose matrix (in world space!). */
|
||||
wm_xr_pose_to_viewmat(&draw_data->base_pose, base_mat);
|
||||
wm_xr_pose_to_viewmat(base_mat, &draw_data->base_pose);
|
||||
|
||||
mul_m4_m4m4(r_view_mat, eye_mat, base_mat);
|
||||
}
|
||||
@@ -95,6 +96,16 @@ static void wm_xr_draw_viewport_buffers_to_active_framebuffer(
|
||||
GPU_viewport_draw_to_screen_ex(surface_data->viewport, 0, &rect, draw_view->expects_srgb_buffer);
|
||||
}
|
||||
|
||||
void apply_world_transform(float viewmat[4][4], GHOST_XrPose world_pose, float scale)
|
||||
{
|
||||
float world[4][4];
|
||||
float scalev[3] = {scale, scale, scale};
|
||||
|
||||
loc_quat_size_to_mat4(world, world_pose.position, world_pose.orientation_quat, scalev);
|
||||
|
||||
mul_m4_m4m4(viewmat, viewmat, world);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draw a viewport for a single eye.
|
||||
*
|
||||
@@ -116,13 +127,19 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
|
||||
BLI_assert(WM_xr_session_is_ready(xr_data));
|
||||
|
||||
wm_xr_session_draw_data_update(session_state, settings, draw_view, draw_data);
|
||||
wm_xr_draw_matrices_create(draw_data, draw_view, settings, viewmat, winmat);
|
||||
wm_xr_session_state_update(settings, draw_data, draw_view, session_state);
|
||||
wm_xr_draw_matrices_create(
|
||||
draw_data, draw_view, settings, session_state->world_scale, viewmat, winmat);
|
||||
|
||||
apply_world_transform(viewmat, session_state->world_pose, session_state->world_scale);
|
||||
|
||||
wm_xr_session_state_update(settings, draw_data, draw_view, session_state, viewmat);
|
||||
|
||||
if (!wm_xr_session_surface_offscreen_ensure(surface_data, draw_view)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* In case a framebuffer is still bound from drawing the last eye. */
|
||||
GPU_framebuffer_restore();
|
||||
/* Some systems have drawing glitches without this. */
|
||||
@@ -138,8 +155,8 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
|
||||
display_flags,
|
||||
viewmat,
|
||||
winmat,
|
||||
settings->clip_start,
|
||||
settings->clip_end,
|
||||
settings->clip_start * session_state->world_scale,
|
||||
settings->clip_end * session_state->world_scale,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
|
@@ -25,6 +25,33 @@
|
||||
|
||||
#include "wm_xr.h"
|
||||
|
||||
typedef struct wmXrControllersData {
|
||||
GHOST_XrPose left_pose;
|
||||
GHOST_XrPose right_pose;
|
||||
float left_trigger_value;
|
||||
float right_trigger_value;
|
||||
bool left_trigger_touch;
|
||||
bool right_trigger_touch;
|
||||
float left_grip_value;
|
||||
float right_grip_value;
|
||||
bool left_primary_click;
|
||||
bool left_primary_touch;
|
||||
bool left_secondary_click;
|
||||
bool left_secondary_touch;
|
||||
bool right_primary_click;
|
||||
bool right_primary_touch;
|
||||
bool right_secondary_click;
|
||||
bool right_secondary_touch;
|
||||
float left_thumbstick_x;
|
||||
float left_thumbstick_y;
|
||||
bool left_thumbstick_click;
|
||||
bool left_thumbstick_touch;
|
||||
float right_thumbstick_x;
|
||||
float right_thumbstick_y;
|
||||
bool right_thumbstick_click;
|
||||
bool right_thumbstick_touch;
|
||||
} wmXrControllersData;
|
||||
|
||||
typedef struct wmXrSessionState {
|
||||
bool is_started;
|
||||
|
||||
@@ -38,6 +65,7 @@ typedef struct wmXrSessionState {
|
||||
* resetting to base pose. */
|
||||
char prev_base_pose_type; /* eXRSessionBasePoseType */
|
||||
Object *prev_base_pose_object;
|
||||
|
||||
/** Copy of XrSessionSettings.flag created on the last draw call, stored to detect changes. */
|
||||
int prev_settings_flag;
|
||||
/** Copy of wmXrDrawData.eye_position_ofs. */
|
||||
@@ -45,6 +73,13 @@ typedef struct wmXrSessionState {
|
||||
|
||||
bool force_reset_to_base_pose;
|
||||
bool is_view_data_set;
|
||||
|
||||
/** World */
|
||||
GHOST_XrPose world_pose;
|
||||
float world_scale;
|
||||
|
||||
/** Controllers */
|
||||
wmXrControllersData controllers_data;
|
||||
} wmXrSessionState;
|
||||
|
||||
typedef struct wmXrRuntimeData {
|
||||
@@ -84,13 +119,14 @@ void wm_xr_session_draw_data_update(const wmXrSessionState *state,
|
||||
void wm_xr_session_state_update(const XrSessionSettings *settings,
|
||||
const wmXrDrawData *draw_data,
|
||||
const GHOST_XrDrawViewInfo *draw_view,
|
||||
wmXrSessionState *state);
|
||||
wmXrSessionState *state,
|
||||
float viewmat[4][4]);
|
||||
bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data,
|
||||
const GHOST_XrDrawViewInfo *draw_view);
|
||||
void *wm_xr_session_gpu_binding_context_create(void);
|
||||
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle context);
|
||||
|
||||
void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4]);
|
||||
void wm_xr_pose_to_viewmat(float r_viewmat[4][4], const GHOST_XrPose* pose);
|
||||
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
|
||||
|
||||
#endif
|
||||
|
@@ -132,10 +132,20 @@ static void wm_xr_session_base_pose_calc(const Scene *scene,
|
||||
mat4_to_loc_quat(r_base_pose->position, tmp_quat, base_pose_object->obmat);
|
||||
|
||||
/* Only use rotation around Z-axis to align view with floor. */
|
||||
/*
|
||||
quat_to_eul(tmp_eul, tmp_quat);
|
||||
tmp_eul[0] = M_PI_2;
|
||||
tmp_eul[1] = 0;
|
||||
eul_to_quat(r_base_pose->orientation_quat, tmp_eul);
|
||||
*/
|
||||
|
||||
/* TODO: find out why we did it */
|
||||
|
||||
/* override quat */
|
||||
tmp_eul[0] = M_PI_2;
|
||||
tmp_eul[1] = 0;
|
||||
tmp_eul[2] = 0;
|
||||
eul_to_quat(r_base_pose->orientation_quat, tmp_eul);
|
||||
}
|
||||
else {
|
||||
copy_v3_fl(r_base_pose->position, 0.0f);
|
||||
@@ -203,6 +213,24 @@ void wm_xr_session_draw_data_update(const wmXrSessionState *state,
|
||||
}
|
||||
}
|
||||
|
||||
void wm_xr_session_controller_transform_update(GHOST_XrPose *dst_pose,
|
||||
const GHOST_XrPose *base_pose,
|
||||
const GHOST_XrPose *pose)
|
||||
{
|
||||
copy_v3_v3(dst_pose->position, base_pose->position);
|
||||
dst_pose->position[0] = base_pose->position[0] + pose->position[0];
|
||||
dst_pose->position[1] = base_pose->position[1] - pose->position[2];
|
||||
dst_pose->position[2] = base_pose->position[2] + pose->position[1];
|
||||
|
||||
mul_qt_qtqt(dst_pose->orientation_quat, base_pose->orientation_quat, pose->orientation_quat);
|
||||
|
||||
float invBaseRotation[4];
|
||||
copy_qt_qt(invBaseRotation, base_pose->orientation_quat);
|
||||
invert_qt(invBaseRotation);
|
||||
|
||||
mul_qt_qtqt(dst_pose->orientation_quat, dst_pose->orientation_quat, invBaseRotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update information that is only stored for external state queries. E.g. for Python API to
|
||||
* request the current (as in, last known) viewer pose.
|
||||
@@ -210,7 +238,8 @@ void wm_xr_session_draw_data_update(const wmXrSessionState *state,
|
||||
void wm_xr_session_state_update(const XrSessionSettings *settings,
|
||||
const wmXrDrawData *draw_data,
|
||||
const GHOST_XrDrawViewInfo *draw_view,
|
||||
wmXrSessionState *state)
|
||||
wmXrSessionState *state,
|
||||
float viewmat[4][4])
|
||||
{
|
||||
GHOST_XrPose viewer_pose;
|
||||
const bool use_position_tracking = settings->flag & XR_SESSION_USE_POSITION_TRACKING;
|
||||
@@ -221,6 +250,7 @@ void wm_xr_session_state_update(const XrSessionSettings *settings,
|
||||
copy_v3_v3(viewer_pose.position, draw_data->base_pose.position);
|
||||
/* The local pose and the eye pose (which is copied from an earlier local pose) both are view
|
||||
* space, so Y-up. In this case we need them in regular Z-up. */
|
||||
|
||||
viewer_pose.position[0] += draw_data->eye_position_ofs[0];
|
||||
viewer_pose.position[1] -= draw_data->eye_position_ofs[2];
|
||||
viewer_pose.position[2] += draw_data->eye_position_ofs[1];
|
||||
@@ -232,7 +262,14 @@ void wm_xr_session_state_update(const XrSessionSettings *settings,
|
||||
|
||||
copy_v3_v3(state->viewer_pose.position, viewer_pose.position);
|
||||
copy_qt_qt(state->viewer_pose.orientation_quat, viewer_pose.orientation_quat);
|
||||
wm_xr_pose_to_viewmat(&viewer_pose, state->viewer_viewmat);
|
||||
|
||||
/*
|
||||
wm_xr_pose_to_viewmat(state->viewer_viewmat, &viewer_pose);
|
||||
do not re-compute viewmat use the one that includes "world" transform
|
||||
*/
|
||||
memcpy(state->viewer_viewmat, viewmat, 16 * sizeof(float));
|
||||
|
||||
|
||||
/* No idea why, but multiplying by two seems to make it match the VR view more. */
|
||||
state->focal_len = 2.0f *
|
||||
fov_to_focallength(draw_view->fov.angle_right - draw_view->fov.angle_left,
|
||||
@@ -243,6 +280,42 @@ void wm_xr_session_state_update(const XrSessionSettings *settings,
|
||||
state->prev_base_pose_type = settings->base_pose_type;
|
||||
state->prev_base_pose_object = settings->base_pose_object;
|
||||
state->is_view_data_set = true;
|
||||
|
||||
/* Controllers states */
|
||||
wm_xr_session_controller_transform_update(&state->controllers_data.left_pose,
|
||||
&draw_data->base_pose,
|
||||
&draw_view->controllers_data.left_pose);
|
||||
wm_xr_session_controller_transform_update(&state->controllers_data.right_pose,
|
||||
&draw_data->base_pose,
|
||||
&draw_view->controllers_data.right_pose);
|
||||
state->controllers_data.left_trigger_value = draw_view->controllers_data.left_trigger_value;
|
||||
state->controllers_data.left_trigger_touch = draw_view->controllers_data.left_trigger_touch;
|
||||
|
||||
state->controllers_data.right_trigger_value = draw_view->controllers_data.right_trigger_value;
|
||||
state->controllers_data.right_trigger_touch = draw_view->controllers_data.right_trigger_touch;
|
||||
|
||||
state->controllers_data.left_grip_value = draw_view->controllers_data.left_grip_value;
|
||||
state->controllers_data.right_grip_value = draw_view->controllers_data.right_grip_value;
|
||||
|
||||
state->controllers_data.left_primary_click = draw_view->controllers_data.left_primary_click;
|
||||
state->controllers_data.left_primary_touch = draw_view->controllers_data.left_primary_touch;
|
||||
state->controllers_data.left_secondary_click = draw_view->controllers_data.left_secondary_click;
|
||||
state->controllers_data.left_secondary_touch = draw_view->controllers_data.left_secondary_touch;
|
||||
|
||||
state->controllers_data.right_primary_click = draw_view->controllers_data.right_primary_click;
|
||||
state->controllers_data.right_primary_touch = draw_view->controllers_data.right_primary_touch;
|
||||
state->controllers_data.right_secondary_click = draw_view->controllers_data.right_secondary_click;
|
||||
state->controllers_data.right_secondary_touch = draw_view->controllers_data.right_secondary_touch;
|
||||
|
||||
state->controllers_data.left_thumbstick_x = draw_view->controllers_data.left_thumbstick_x;
|
||||
state->controllers_data.left_thumbstick_y = draw_view->controllers_data.left_thumbstick_y;
|
||||
state->controllers_data.left_thumbstick_click = draw_view->controllers_data.left_thumbstick_click;
|
||||
state->controllers_data.left_thumbstick_touch = draw_view->controllers_data.left_thumbstick_touch;
|
||||
|
||||
state->controllers_data.right_thumbstick_x = draw_view->controllers_data.right_thumbstick_x;
|
||||
state->controllers_data.right_thumbstick_y = draw_view->controllers_data.right_thumbstick_y;
|
||||
state->controllers_data.right_thumbstick_click = draw_view->controllers_data.right_thumbstick_click;
|
||||
state->controllers_data.right_thumbstick_touch = draw_view->controllers_data.right_thumbstick_touch;
|
||||
}
|
||||
|
||||
wmXrSessionState *WM_xr_session_state_handle_get(const wmXrData *xr)
|
||||
@@ -272,6 +345,252 @@ bool WM_xr_session_state_viewer_pose_rotation_get(const wmXrData *xr, float r_ro
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_world_location_get(const wmXrData *xr, float r_location[3])
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
zero_v3(r_location);
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v3_v3(r_location, xr->runtime->session_state.world_pose.position);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_world_location_set(const wmXrData *xr, const float location[3])
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v3_v3(xr->runtime->session_state.world_pose.position, location);
|
||||
return true;
|
||||
}
|
||||
|
||||
float WM_xr_session_state_get_float(const wmXrData *xr, float value, float defaultValue)
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_get_bool(const wmXrData *xr, bool value, bool defaultValue)
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* World matrix */
|
||||
bool WM_xr_session_state_world_rotation_get(const wmXrData *xr, float r_rotation[4])
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
unit_qt(r_rotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v4_v4(r_rotation, xr->runtime->session_state.world_pose.orientation_quat);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_world_rotation_set(const wmXrData *xr, const float rotation[4])
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v4_v4(xr->runtime->session_state.world_pose.orientation_quat, rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
float WM_xr_session_state_world_scale_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_float(xr, xr->runtime->session_state.world_scale, 1.f);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_world_scale_set(const wmXrData *xr, const float scale)
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
xr->runtime->session_state.world_scale = scale;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Thumbsticks */
|
||||
float WM_xr_session_state_left_thumbstick_x_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_float(xr, xr->runtime->session_state.controllers_data.left_thumbstick_x, 0.f);
|
||||
}
|
||||
|
||||
float WM_xr_session_state_left_thumbstick_y_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_float(
|
||||
xr, xr->runtime->session_state.controllers_data.left_thumbstick_y, 0.f);
|
||||
}
|
||||
|
||||
float WM_xr_session_state_right_thumbstick_x_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_float(
|
||||
xr, xr->runtime->session_state.controllers_data.right_thumbstick_x, 0.f);
|
||||
}
|
||||
|
||||
float WM_xr_session_state_right_thumbstick_y_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_float(
|
||||
xr, xr->runtime->session_state.controllers_data.right_thumbstick_y, 0.f);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_thumbstick_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_thumbstick_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_thumbstick_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_thumbstick_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_thumbstick_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_thumbstick_touch, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_thumbstick_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_thumbstick_touch, false);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
bool WM_xr_session_state_left_primary_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_primary_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_primary_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_primary_touch, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_secondary_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_secondary_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_secondary_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.left_secondary_touch, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_primary_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_primary_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_primary_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_primary_touch, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_secondary_click_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_secondary_click, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_secondary_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return WM_xr_session_state_get_bool(
|
||||
xr, xr->runtime->session_state.controllers_data.right_secondary_touch, false);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_get_vector3(float dst[3], const wmXrData *xr, float *src)
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
|
||||
zero_v3(dst);
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v3_v3(dst, src);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_get_quaternion(float dst[4], const wmXrData *xr, float *src)
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
|
||||
unit_qt(dst);
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v4_v4(dst, src);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Poses */
|
||||
bool WM_xr_session_state_left_controller_location_get(const wmXrData *xr, float r_location[3])
|
||||
{
|
||||
return WM_xr_session_state_get_vector3(r_location, xr, xr->runtime->session_state.controllers_data.left_pose.position);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_controller_rotation_get(const wmXrData *xr, float r_rotation[4])
|
||||
{
|
||||
return WM_xr_session_state_get_quaternion(r_rotation, xr, xr->runtime->session_state.controllers_data.left_pose.orientation_quat);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_controller_location_get(const wmXrData *xr, float r_location[3])
|
||||
{
|
||||
return WM_xr_session_state_get_vector3(r_location, xr, xr->runtime->session_state.controllers_data.right_pose.position);
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_controller_rotation_get(const wmXrData *xr, float r_rotation[4])
|
||||
{
|
||||
return WM_xr_session_state_get_quaternion(r_rotation, xr, xr->runtime->session_state.controllers_data.right_pose.orientation_quat);
|
||||
}
|
||||
|
||||
/* Triggers */
|
||||
float WM_xr_session_state_left_trigger_value_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.left_trigger_value;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_left_trigger_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.left_trigger_touch;
|
||||
}
|
||||
|
||||
float WM_xr_session_state_right_trigger_value_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.right_trigger_value;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_right_trigger_touch_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.right_trigger_touch;
|
||||
}
|
||||
|
||||
/* Grips */
|
||||
float WM_xr_session_state_left_grip_value_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.left_grip_value;
|
||||
}
|
||||
|
||||
float WM_xr_session_state_right_grip_value_get(const wmXrData *xr)
|
||||
{
|
||||
return xr->runtime->session_state.controllers_data.right_grip_value;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
|
||||
float r_viewmat[4][4],
|
||||
float *r_focal_len)
|
||||
@@ -288,6 +607,26 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WM_xr_session_state_world_matrix_get(const wmXrData *xr,
|
||||
float world_matrix[4][4])
|
||||
{
|
||||
if (!WM_xr_session_is_ready(xr)) {
|
||||
unit_m4(world_matrix);
|
||||
return false;
|
||||
}
|
||||
|
||||
float scale[3] = {xr->runtime->session_state.world_scale,
|
||||
xr->runtime->session_state.world_scale,
|
||||
xr->runtime->session_state.world_scale};
|
||||
|
||||
loc_quat_size_to_mat4(world_matrix,
|
||||
xr->runtime->session_state.world_pose.position,
|
||||
xr->runtime->session_state.world_pose.orientation_quat,
|
||||
scale);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name XR-Session Surface
|
||||
*
|
||||
|
Reference in New Issue
Block a user