diff --git a/src/HardwareSet/OpenXRSet/OpenXRInput.cpp b/src/HardwareSet/OpenXRSet/OpenXRInput.cpp index 6fb15a84c8d18491db4136ffdf53a3ea6abe6eab..7506fdb62fd88ac1c73003dfff570491a743f4df 100644 --- a/src/HardwareSet/OpenXRSet/OpenXRInput.cpp +++ b/src/HardwareSet/OpenXRSet/OpenXRInput.cpp @@ -240,7 +240,7 @@ void OpenXRInput::handleActions(OxrConnection& oxrConn) if (currentActionSet->dominantSetting != OxrDominantSetting::SINGLE) { OxrDigital selectButton {}; oxrGetFallingEdgeAction(oxrConn, actions["select-dominant-left-hand"], selectButton); - if (*selectButton) { + if (selectButton.value_or(false)) { oxrControllers.primaryIsLeft = true; std::string handedActionSetName = currentActionSet->prefixName + "-lh"; if (currentActionSet->name != handedActionSetName) { @@ -254,7 +254,7 @@ void OpenXRInput::handleActions(OxrConnection& oxrConn) } } oxrGetFallingEdgeAction(oxrConn, actions["select-dominant-right-hand"], selectButton); - if (*selectButton) { + if (selectButton.value_or(false)) { oxrControllers.primaryIsLeft = false; std::string handedActionSetName = currentActionSet->prefixName + "-rh"; if (currentActionSet->name != handedActionSetName) { diff --git a/src/HardwareSet/OpenXRSet/OpenXRInput.hpp b/src/HardwareSet/OpenXRSet/OpenXRInput.hpp index dd7e694f78486ffbb4a6912b0a1fe7292d6772dd..b31ceeb0a9e271ea699ba8e72bf9200e1e7095ec 100644 --- a/src/HardwareSet/OpenXRSet/OpenXRInput.hpp +++ b/src/HardwareSet/OpenXRSet/OpenXRInput.hpp @@ -29,23 +29,23 @@ enum HandType { struct OxrController { bool primaryIsLeft { true }; - OxrPose hands[OxrHand::COUNT] { 1.0f }; - OxrDigital interactionButton { false }; - OxrDigital secondInteractionButton { false }; - OxrDigital interactionAnalogActive { false }; - OxrAnalog interactionAnalog { 0.0f }; + OxrPose hands[OxrHand::COUNT] {}; + OxrDigital interactionButton {}; + OxrDigital secondInteractionButton {}; + OxrDigital interactionAnalogActive {}; + OxrAnalog interactionAnalog {}; enum AnalogState { WAS_TOUCHED, DISCARD_GARBAGE, WAIT_MOVE, READY } interactionAnalogState { WAS_TOUCHED }; - OxrAnalog2 navigationPad { 0.0f }; - OxrDigital useOnPlaneNav { false }; - OxrDigital useUpDownNav { false }; - OxrDigital useAlongNav { false }; - OxrDigital useScaleNav { false }; - OxrDigital usePenOnTable { false }; + OxrAnalog2 navigationPad {}; + OxrDigital useOnPlaneNav {}; + OxrDigital useUpDownNav {}; + OxrDigital useAlongNav {}; + OxrDigital useScaleNav {}; + OxrDigital usePenOnTable {}; }; class OpenXRInput diff --git a/src/HardwareSet/OpenXRSet/OpenXRSet.cpp b/src/HardwareSet/OpenXRSet/OpenXRSet.cpp index d38972b615ee9b40d2563877f227c0c0d5cace9b..275020b346dcd072a07ef33b2695a45fe53fdb10 100644 --- a/src/HardwareSet/OpenXRSet/OpenXRSet.cpp +++ b/src/HardwareSet/OpenXRSet/OpenXRSet.cpp @@ -902,16 +902,22 @@ void OpenXRSet::handleInput() oxrInput.handleActions(oxrConn); glm::mat4 refMat = navigator.getVirtualPoser().getInvMatrix(); - if (oxrInput.oxrControllers.hands[HandType::PRIMARY]) { + if (oxrInput.oxrControllers.hands[HandType::PRIMARY].has_value()) { primaryPoser->setMatrix(refMat * (*oxrInput.oxrControllers.hands[HandType::PRIMARY])); } - if (oxrInput.oxrControllers.hands[HandType::SECONDARY]) { + if (oxrInput.oxrControllers.hands[HandType::SECONDARY].has_value()) { secondaryPoser->setMatrix(refMat * (*oxrInput.oxrControllers.hands[HandType::SECONDARY])); } - setButtonState(*oxrInput.oxrControllers.interactionButton, frameTime); - setSecondButtonState(*oxrInput.oxrControllers.secondInteractionButton); - setPenOnTable(*oxrInput.oxrControllers.usePenOnTable); + if (oxrInput.oxrControllers.interactionButton.has_value()) { + setButtonState(*oxrInput.oxrControllers.interactionButton, frameTime); + } + if (oxrInput.oxrControllers.secondInteractionButton.has_value()) { + setSecondButtonState(*oxrInput.oxrControllers.secondInteractionButton); + } + if (oxrInput.oxrControllers.usePenOnTable.has_value()) { + setPenOnTable(*oxrInput.oxrControllers.usePenOnTable); + } if (oxrConn.handTrackingEnabled) { oxrHandTracking.handleInput(oxrConn); @@ -924,13 +930,13 @@ void OpenXRSet::handleInput() // TODO: The interactions used to trigger the navigation modes can possibly overlap. // We should analyze the input bindings to find the dependencies... // Meanwhile, we use a 'static' order of analyse. - if (*oxrInput.oxrControllers.useScaleNav) + if (oxrInput.oxrControllers.useScaleNav.value_or(false)) activeNavMode = CONTINUOUS_SCALE; - else if (*oxrInput.oxrControllers.useAlongNav) + else if (oxrInput.oxrControllers.useAlongNav.value_or(false)) activeNavMode = ALONG_VIEW; - else if (*oxrInput.oxrControllers.useUpDownNav) + else if (oxrInput.oxrControllers.useUpDownNav.value_or(false)) activeNavMode = UP_DOWN; - else if (*oxrInput.oxrControllers.useOnPlaneNav) + else if (oxrInput.oxrControllers.useOnPlaneNav.value_or(false)) activeNavMode = ON_PLANE; // reset speeder if nav mode changed, or when the nav pad is released @@ -941,13 +947,13 @@ void OpenXRSet::handleInput() if (activeNavMode == NO_NAV) { #if 1 - if (oxrInput.oxrControllers.interactionAnalog) { + if (oxrInput.oxrControllers.interactionAnalog.has_value()) { float padValue = (*oxrInput.oxrControllers.interactionAnalog + 1.0f) * 0.5f; interactionAnalog = padValue; interactionRelAnalog = padValue; } #else - if (*oxrInput.oxrControllers.interactionAnalogActive) { + if (oxrInput.oxrControllers.interactionAnalogActive.has_value()) { float padValue = (*oxrInput.oxrControllers.interactionAnalog + 1.0f) * 0.5f; switch (oxrInput.oxrControllers.interactionAnalogState) { case OxrController::WAS_TOUCHED: @@ -983,7 +989,7 @@ void OpenXRSet::handleInput() speeder.start(glfwGetTime()); resetSpeeder = false; } - if (oxrInput.oxrControllers.navigationPad) { + if (oxrInput.oxrControllers.navigationPad.has_value()) { float speed = speeder.getValue(glfwGetTime()); float speedX = +oxrInput.oxrControllers.navigationPad->x * speed; float speedZ = -oxrInput.oxrControllers.navigationPad->y * speed; @@ -1002,8 +1008,10 @@ void OpenXRSet::handleInput() // Move along Y axis if (activeNavMode == UP_DOWN) { - float speedY = +oxrInput.oxrControllers.navigationPad->y * moveFullSpeed * 10.0f; - navigator.moveUpDown(speedY); + if (oxrInput.oxrControllers.navigationPad.has_value()) { + float speedY = +oxrInput.oxrControllers.navigationPad->y * moveFullSpeed * 10.0f; + navigator.moveUpDown(speedY); + } return; } @@ -1014,28 +1022,30 @@ void OpenXRSet::handleInput() speeder.start(glfwGetTime()); resetSpeeder = false; } - float speed = speeder.getValue(glfwGetTime()); - float speedX = +oxrInput.oxrControllers.navigationPad->x * speed; - float speedZ = -oxrInput.oxrControllers.navigationPad->y * speed; - // separate axis, to ease navigation - if (std::abs(speedX) > std::abs(speedZ)) { - // Move laterally - navigator.moveOnPlane(glm::vec3(speedX, 0.0f, 0.0f)); - } else { - // Move along the view direction - navigator.moveAlongViewDirection(speedZ); + if (oxrInput.oxrControllers.navigationPad.has_value()) { + float speed = speeder.getValue(glfwGetTime()); + float speedX = +oxrInput.oxrControllers.navigationPad->x * speed; + float speedZ = -oxrInput.oxrControllers.navigationPad->y * speed; + // separate axis, to ease navigation + if (std::abs(speedX) > std::abs(speedZ)) { + // Move laterally + navigator.moveOnPlane(glm::vec3(speedX, 0.0f, 0.0f)); + } else { + // Move along the view direction + navigator.moveAlongViewDirection(speedZ); + } } - return; } // Continuous zoom (change the zoom value by 10%) if (activeNavMode == CONTINUOUS_SCALE) { - float value = oxrInput.oxrControllers.navigationPad->y; - // we want to avoid unwanted change, so we apply a large threshold - if (std::abs(value) >= 0.5f) navigator.applyScale((value < 0), 1.01); - + if (oxrInput.oxrControllers.navigationPad.has_value()) { + float value = oxrInput.oxrControllers.navigationPad->y; + // we want to avoid unwanted change, so we apply a large threshold + if (std::abs(value) >= 0.5f) navigator.applyScale((value < 0), 1.01); + } return; } } diff --git a/src/HardwareSet/OpenXRSet/OpenXR_helpers.cpp b/src/HardwareSet/OpenXRSet/OpenXR_helpers.cpp index 8683d05fde037b4b4888e9d9c5df04d685fa0c87..584fc6bbeced09a7a4d3218696a4231bbc67a7db 100644 --- a/src/HardwareSet/OpenXRSet/OpenXR_helpers.cpp +++ b/src/HardwareSet/OpenXRSet/OpenXR_helpers.cpp @@ -693,6 +693,8 @@ void oxrGetPoseAction(const OxrConnection& oxrConn, const OxrAction* action, Oxr void oxrGetFallingEdgeAction(const OxrConnection& oxrConn, const OxrAction* action, OxrDigital& data) { + data = std::nullopt; + XrActionStateBoolean booleanState = { .type = XR_TYPE_ACTION_STATE_BOOLEAN, .next = nullptr }; XrActionStateGetInfo getInfo = { .type = XR_TYPE_ACTION_STATE_GET_INFO, @@ -716,7 +718,7 @@ void oxrGetDigitalAction(const OxrConnection& oxrConn, const OxrAction* action, OxrAnalog analogValue {}; auto it = action->adapter->subactions.begin(); oxrGetAnalogAction(oxrConn, it->second, analogValue); - if (analogValue) { + if (analogValue.has_value()) { if (!action->adapter->currentState && (*analogValue) > action->adapter->thresholdH) { action->adapter->currentState = true; } else if (action->adapter->currentState && (*analogValue) <= action->adapter->thresholdL) { @@ -731,10 +733,12 @@ void oxrGetDigitalAction(const OxrConnection& oxrConn, const OxrAction* action, for (const auto& [subactionName, subAction] : action->adapter->subactions) { OxrDigital subValue {}; oxrGetDigitalAction(oxrConn, subAction, subValue); - if (action->adapter->combinerType == OxrActionAdapter::COMBINER_AND_TYPE) { - data = (*data) & (*subValue); - } else if (action->adapter->combinerType == OxrActionAdapter::COMBINER_OR_TYPE) { - data = (*data) | (*subValue); + if (subValue.has_value()) { + if (action->adapter->combinerType == OxrActionAdapter::COMBINER_AND_TYPE) { + data = (*data) & (*subValue); + } else if (action->adapter->combinerType == OxrActionAdapter::COMBINER_OR_TYPE) { + data = (*data) | (*subValue); + } } } return; @@ -768,7 +772,7 @@ void oxrGetAnalogAction(const OxrConnection& oxrConn, const OxrAction* action, O OxrAnalog analogValue {}; auto it = action->adapter->subactions.begin(); oxrGetAnalogAction(oxrConn, it->second, analogValue); - if (analogValue) { + if (analogValue.has_value()) { action->adapter->currentValue += (*analogValue) / 20.0f; action->adapter->currentValue = std::clamp(action->adapter->currentValue, -1.0f, 1.0f); data = action->adapter->currentValue; @@ -778,7 +782,7 @@ void oxrGetAnalogAction(const OxrConnection& oxrConn, const OxrAction* action, O OxrAnalog analogValue {}; auto it = action->adapter->subactions.begin(); oxrGetAnalogAction(oxrConn, it->second, analogValue); - if (analogValue) { + if (analogValue.has_value()) { action->adapter->currentValue += (*analogValue) / 20.0f; if (action->adapter->currentValue > 1.0f) action->adapter->currentValue = action->adapter->startLoop; data = action->adapter->currentValue; diff --git a/tools/cap_modder.cpp b/tools/cap_modder.cpp index 1dcc7a767357c0bbe4275181469b7c26e6c49be6..581c2643b91050eec8d928a9dfc2646bedce00db 100644 --- a/tools/cap_modder.cpp +++ b/tools/cap_modder.cpp @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: Copyright (c) 2023 CRIStAL/PIRVI. All rights reserved. -// SPDX-FileCopyrightText: Copyright (c) 2023 Samuel Degrande +// SPDX-FileCopyrightText: Copyright (c) 2023-2025 CRIStAL/PIRVI. All rights reserved. +// SPDX-FileCopyrightText: Copyright (c) 2023-2025 Samuel Degrande // SPDX-License-Identifier: BSD-3-Clause #include "CaptureLib/Modder.hpp" @@ -68,7 +68,7 @@ int main(int argc, char* argv[]) auto error = modder.apply(input, output, translation, rotation, rotationKind, scale, scaleKind); input.close(); output.close(); - if (error) { + if (error.has_value()) { std::cout << comment << "\nError when modding the _full.cap file:\n" << *error; return EXIT_FAILURE; } @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) auto error = modder.apply(input, output, translation, rotation, rotationKind, scale, scaleKind); input.close(); output.close(); - if (error) { + if (error.has_value()) { std::cout << comment << "\nError when modding the .cap file:\n" << *error; return EXIT_FAILURE; }