Skip to content

Commit

Permalink
🐛 Use quad views layout for xrLocateViews() if quad views is active
Browse files Browse the repository at this point in the history
Spec:

> If an application gives a viewLocateInfo with a XrViewLocateInfo::viewConfigurationType that was not passed in the session’s call to xrBeginSession via the XrSessionBeginInfo::primaryViewConfigurationType, or enabled though an extension, then the runtime must return XR_ERROR_VALIDATION_FAILURE.

fixes #92
  • Loading branch information
fredemmott committed Dec 9, 2024
1 parent 99f431c commit f62d69f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
52 changes: 39 additions & 13 deletions src/APILayer/APILayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ using namespace DirectX::SimpleMath;

namespace HandTrackedCockpitClicking {

APILayer::APILayer(
XrInstance instance,
const std::shared_ptr<OpenXRNext>& next)
APILayer::APILayer(XrInstance instance, const std::shared_ptr<OpenXRNext>& next)
: mOpenXR(next), mInstance(instance) {
DebugPrint("{}()", __FUNCTION__);

}

// Report to higher layers and apps that OpenXR Hand Tracking is unavailable;
Expand Down Expand Up @@ -77,11 +74,33 @@ XrResult APILayer::xrGetSystemProperties(
return result;
}

XrResult APILayer::xrCreateSession(XrInstance instance, const XrSessionCreateInfo* createInfo, XrSession* session) {
XrResult APILayer::xrBeginSession(
XrSession session,
const XrSessionBeginInfo* beginInfo) {
const auto result = mOpenXR->xrBeginSession(session, beginInfo);
if (XR_FAILED(result)) [[unlikely]] {
return result;
}

switch (beginInfo->primaryViewConfigurationType) {
case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO:
case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO:
this->mPrimaryViewConfigurationType
= beginInfo->primaryViewConfigurationType;
};

return result;
}

XrResult APILayer::xrCreateSession(
XrInstance instance,
const XrSessionCreateInfo* createInfo,
XrSession* session) {
static uint32_t sCount = 0;
DebugPrint("{}(): #{}", __FUNCTION__, sCount);

const auto nextResult = mOpenXR->xrCreateSession(instance, createInfo, session);
const auto nextResult
= mOpenXR->xrCreateSession(instance, createInfo, session);
if (XR_FAILED(nextResult)) {
DebugPrint("Failed to create OpenXR session: {}", nextResult);
return nextResult;
Expand Down Expand Up @@ -209,7 +228,9 @@ XrResult APILayer::xrLocateSpace(
return mOpenXR->xrLocateSpace(space, baseSpace, time, location);
}

XrResult APILayer::xrAttachSessionActionSets(XrSession session, const XrSessionActionSetsAttachInfo* attachInfo) {
XrResult APILayer::xrAttachSessionActionSets(
XrSession session,
const XrSessionActionSetsAttachInfo* attachInfo) {
const auto result = mOpenXR->xrAttachSessionActionSets(session, attachInfo);
if (XR_FAILED(result)) {
return result;
Expand Down Expand Up @@ -259,17 +280,17 @@ XrResult APILayer::xrCreateAction(
XrActionSet actionSet,
const XrActionCreateInfo* createInfo,
XrAction* action) {
const auto result = mVirtualController ?
mVirtualController->xrCreateAction(actionSet, createInfo, action) :
mOpenXR->xrCreateAction(actionSet, createInfo, action);
const auto result = mVirtualController
? mVirtualController->xrCreateAction(actionSet, createInfo, action)
: mOpenXR->xrCreateAction(actionSet, createInfo, action);
if (XR_FAILED(result)) {
return result;
}

if (mActionSetActions.contains(actionSet)) {
mActionSetActions.at(actionSet).emplace(*action);
} else {
mActionSetActions[actionSet] = { *action };
mActionSetActions[actionSet] = {*action};
}

return result;
Expand Down Expand Up @@ -310,9 +331,14 @@ XrResult APILayer::xrWaitFrame(

if (
(!mVirtualTouchScreen)
&& (VirtualTouchScreenSink::IsActionSink() || VirtualTouchScreenSink::IsPointerSink())) {
&& (VirtualTouchScreenSink::IsActionSink() || VirtualTouchScreenSink::IsPointerSink())
&& mPrimaryViewConfigurationType.has_value()) {
mVirtualTouchScreen = std::make_unique<VirtualTouchScreenSink>(
mOpenXR, session, state->predictedDisplayTime, mViewSpace);
mOpenXR,
session,
mPrimaryViewConfigurationType.value(),
state->predictedDisplayTime,
mViewSpace);
}

InputState leftHand {XR_HAND_LEFT_EXT};
Expand Down
6 changes: 6 additions & 0 deletions src/APILayer/APILayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ XrResult xrGetSystemProperties(
const XrSessionCreateInfo* createInfo,
XrSession* session);

XrResult xrBeginSession(
XrSession session,
const XrSessionBeginInfo* beginInfo);

XrResult xrDestroySession(XrSession session);

XrResult xrCreateHandTrackerEXT(
Expand Down Expand Up @@ -135,6 +139,8 @@ XrResult xrGetSystemProperties(
XrSpace mViewSpace {};
XrSpace mLocalSpace {};

std::optional<XrViewConfigurationType> mPrimaryViewConfigurationType;

std::unordered_map<XrActionSet, std::unordered_set<XrAction>>
mActionSetActions;
std::unordered_set<XrAction> mAttachedActions;
Expand Down
1 change: 1 addition & 0 deletions src/lib/OpenXRNext.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
IT(xrGetSystemProperties) \
IT(xrCreateSession) \
IT(xrDestroySession) \
IT(xrBeginSession) \
IT(xrLocateSpace) \
IT(xrWaitFrame) \
IT(xrSuggestInteractionProfileBindings) \
Expand Down
17 changes: 13 additions & 4 deletions src/lib/VirtualTouchScreenSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,29 @@ VirtualTouchScreenSink::VirtualTouchScreenSink(
VirtualTouchScreenSink::VirtualTouchScreenSink(
const std::shared_ptr<OpenXRNext>& oxr,
XrSession session,
XrViewConfigurationType viewConfigurationType,
XrTime nextDisplayTime,
XrSpace viewSpace)
: VirtualTouchScreenSink(
CalibrationFromOpenXR(oxr, session, nextDisplayTime, viewSpace),
GetCurrentProcessId()) {
CalibrationFromOpenXR(
oxr,
session,
viewConfigurationType,
nextDisplayTime,
viewSpace),
GetCurrentProcessId()) {
}

std::optional<VirtualTouchScreenSink::Calibration>
VirtualTouchScreenSink::CalibrationFromOpenXR(
const std::shared_ptr<OpenXRNext>& oxr,
XrSession session,
XrViewConfigurationType viewConfigurationType,
XrTime nextDisplayTime,
XrSpace viewSpace) {
XrViewLocateInfo viewLocateInfo {
.type = XR_TYPE_VIEW_LOCATE_INFO,
.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
.viewConfigurationType = viewConfigurationType,
.displayTime = nextDisplayTime,
.space = viewSpace,
};
Expand Down Expand Up @@ -315,7 +322,9 @@ void VirtualTouchScreenSink::Update(const InputState& hand) {
const auto now = std::chrono::steady_clock::now();
const auto& rotation = hand.mDirection;
XrVector2f xy {};
if (IsPointerSink() && mCalibration && rotation && RotationToCartesian(*rotation, &xy)) {
if (
IsPointerSink() && mCalibration && rotation
&& RotationToCartesian(*rotation, &xy)) {
if (now - mLastWindowCheck > std::chrono::seconds(1)) {
UpdateMainWindow();
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/VirtualTouchScreenSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class VirtualTouchScreenSink final {
VirtualTouchScreenSink(
const std::shared_ptr<OpenXRNext>& oxr,
XrSession session,
XrViewConfigurationType viewConfigurationType,
XrTime nextDisplayTime,
XrSpace viewSpace);

Expand All @@ -55,6 +56,7 @@ class VirtualTouchScreenSink final {
static std::optional<Calibration> CalibrationFromOpenXR(
const std::shared_ptr<OpenXRNext>& oxr,
XrSession session,
XrViewConfigurationType viewConfigurationType,
XrTime nextDisplayTime,
XrSpace viewSpace);

Expand Down

0 comments on commit f62d69f

Please sign in to comment.