diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 95c45c6b..569220eb 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -34,7 +34,7 @@ jobs: run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - name: Build - run: cmake --build build --parallel + run: cmake --build build --parallel 4 - name: Run Native Tests run: ctest --test-dir build --output-on-failure --parallel diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a2466f..dd269493 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.20) project(TeleopCore VERSION 1.0.0 LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/examples/oxr/CMakeLists.txt b/examples/oxr/CMakeLists.txt index 553c391a..8d6671f7 100644 --- a/examples/oxr/CMakeLists.txt +++ b/examples/oxr/CMakeLists.txt @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20) -project(oxr_examples) # Build C++ examples add_subdirectory(cpp) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 299b804b..378ba4b7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20) -project(teleopcore_modules VERSION 1.0.0 LANGUAGES CXX) # Options option(BUILD_PYTHON_BINDINGS "Build Python bindings" ON) diff --git a/src/core/oxr/CMakeLists.txt b/src/core/oxr/CMakeLists.txt index 1a5840b8..cd2db18d 100644 --- a/src/core/oxr/CMakeLists.txt +++ b/src/core/oxr/CMakeLists.txt @@ -2,12 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20) -project(oxr_core VERSION 1.0.0 LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Build C++ library add_subdirectory(cpp) diff --git a/src/core/oxr/cpp/CMakeLists.txt b/src/core/oxr/cpp/CMakeLists.txt index 19529a08..3aa52ae3 100644 --- a/src/core/oxr/cpp/CMakeLists.txt +++ b/src/core/oxr/cpp/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required(VERSION 3.20) -# If this is being built standalone, declare a project -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - project(oxr_core VERSION 1.0.0 LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() - # Ensure OpenXR target is available (fetched via CMake FetchContent by parent) if(NOT TARGET openxr_loader) message(FATAL_ERROR "openxr_loader target not found. Make sure OpenXR SDK is fetched via FetchContent first.") diff --git a/src/core/oxr_utils/cpp/CMakeLists.txt b/src/core/oxr_utils/cpp/CMakeLists.txt index b6495f34..823774b6 100644 --- a/src/core/oxr_utils/cpp/CMakeLists.txt +++ b/src/core/oxr_utils/cpp/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required(VERSION 3.20) -# If this is being built standalone, declare a project -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - project(oxr_utils VERSION 1.0.0 LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() - # Ensure OpenXR headers target is available if(NOT TARGET OpenXR::headers) message(FATAL_ERROR "OpenXR::headers target not found. Make sure OpenXR SDK is configured first.") diff --git a/src/core/oxr_utils/cpp/inc/oxr_utils/oxr_funcs.hpp b/src/core/oxr_utils/cpp/inc/oxr_utils/oxr_funcs.hpp index 34cd8ee7..e8d2bee0 100644 --- a/src/core/oxr_utils/cpp/inc/oxr_utils/oxr_funcs.hpp +++ b/src/core/oxr_utils/cpp/inc/oxr_utils/oxr_funcs.hpp @@ -97,138 +97,44 @@ struct OpenXRCoreFunctions } }; -// Custom deleter for OpenXR handles -template -struct OpenXRHandleDeleter -{ - std::function destroy_func; - - void operator()(HandleType handle) const - { - if (handle != XR_NULL_HANDLE && destroy_func) - { - destroy_func(handle); - } - } -}; - -// Helper to wrap OpenXR handles in unique_ptr-like semantics -template -class OpenXRHandle -{ -public: - // Default constructor creates an empty/moved-from state - OpenXRHandle() : handle_(XR_NULL_HANDLE), deleter_(nullptr) - { - } - - OpenXRHandle(HandleType handle, std::function deleter) - : handle_(handle), deleter_(std::move(deleter)) - { - } - - ~OpenXRHandle() - { - reset(); - } - - // Move semantics only - OpenXRHandle(OpenXRHandle&& other) noexcept : handle_(other.handle_), deleter_(std::move(other.deleter_)) - { - other.handle_ = XR_NULL_HANDLE; - } - - OpenXRHandle& operator=(OpenXRHandle&& other) noexcept - { - if (this != &other) - { - reset(); - handle_ = other.handle_; - deleter_ = std::move(other.deleter_); - other.handle_ = XR_NULL_HANDLE; - } - return *this; - } - - // Disable copy - OpenXRHandle(const OpenXRHandle&) = delete; - OpenXRHandle& operator=(const OpenXRHandle&) = delete; - - // Convenience functions to get the handle. - HandleType get() const - { - return handle_; - } - HandleType operator*() const - { - return handle_; - } - explicit operator bool() const - { - return handle_ != XR_NULL_HANDLE; - } - - void reset() - { - if (handle_ != XR_NULL_HANDLE) - { - assert(deleter_); - deleter_(handle_); - handle_ = XR_NULL_HANDLE; - } - } - -private: - HandleType handle_; - std::function deleter_; -}; - // Smart pointer type aliases for OpenXR resources -using XrActionSetPtr = OpenXRHandle; -using XrSpacePtr = OpenXRHandle; +using XrActionSetPtr = std::unique_ptr, PFN_xrDestroyActionSet>; +using XrSpacePtr = std::unique_ptr, PFN_xrDestroySpace>; // Create an action set with automatic cleanup - throws on failure inline XrActionSetPtr createActionSet(const OpenXRCoreFunctions& funcs, XrInstance instance, - const XrActionSetCreateInfo* createInfo) + const XrActionSetCreateInfo& createInfo) { + assert(funcs.xrDestroyActionSet); + XrActionSet actionSet = XR_NULL_HANDLE; - XrResult result = funcs.xrCreateActionSet(instance, createInfo, &actionSet); + XrResult result = funcs.xrCreateActionSet(instance, &createInfo, &actionSet); if (XR_FAILED(result)) { throw std::runtime_error("Failed to create action set: " + std::to_string(result)); } - auto deleter = [destroyFunc = funcs.xrDestroyActionSet](XrActionSet handle) - { - assert(destroyFunc); - destroyFunc(handle); - }; - - return XrActionSetPtr(actionSet, deleter); + return XrActionSetPtr(actionSet, funcs.xrDestroyActionSet); } // Create a reference space with automatic cleanup - throws on failure inline XrSpacePtr createReferenceSpace(const OpenXRCoreFunctions& funcs, XrSession session, - const XrReferenceSpaceCreateInfo* createInfo) + const XrReferenceSpaceCreateInfo& createInfo) { + assert(funcs.xrDestroySpace); + XrSpace space = XR_NULL_HANDLE; - XrResult result = funcs.xrCreateReferenceSpace(session, createInfo, &space); + XrResult result = funcs.xrCreateReferenceSpace(session, &createInfo, &space); if (XR_FAILED(result)) { throw std::runtime_error("Failed to create reference space: " + std::to_string(result)); } - auto deleter = [destroyFunc = funcs.xrDestroySpace](XrSpace handle) - { - assert(destroyFunc); - destroyFunc(handle); - }; - - return XrSpacePtr(space, deleter); + return XrSpacePtr(space, funcs.xrDestroySpace); } // Create an action space with automatic cleanup - throws on failure @@ -236,6 +142,8 @@ inline XrSpacePtr createActionSpace(const OpenXRCoreFunctions& funcs, XrSession session, const XrActionSpaceCreateInfo* createInfo) { + assert(funcs.xrDestroySpace); + XrSpace space = XR_NULL_HANDLE; XrResult result = funcs.xrCreateActionSpace(session, createInfo, &space); @@ -244,13 +152,7 @@ inline XrSpacePtr createActionSpace(const OpenXRCoreFunctions& funcs, throw std::runtime_error("Failed to create action space: " + std::to_string(result)); } - auto deleter = [destroyFunc = funcs.xrDestroySpace](XrSpace handle) - { - assert(destroyFunc); - destroyFunc(handle); - }; - - return XrSpacePtr(space, deleter); + return XrSpacePtr(space, funcs.xrDestroySpace); } } // namespace core diff --git a/src/core/xrio/CMakeLists.txt b/src/core/xrio/CMakeLists.txt index 3594d47e..cd2db18d 100644 --- a/src/core/xrio/CMakeLists.txt +++ b/src/core/xrio/CMakeLists.txt @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20) -project(xrio_core VERSION 1.0.0 LANGUAGES CXX) # Build C++ library add_subdirectory(cpp) diff --git a/src/core/xrio/cpp/CMakeLists.txt b/src/core/xrio/cpp/CMakeLists.txt index c9f4e0ef..df5b29dc 100644 --- a/src/core/xrio/cpp/CMakeLists.txt +++ b/src/core/xrio/cpp/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required(VERSION 3.20) -# If this is being built standalone, declare a project -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - project(xrio_core VERSION 1.0.0 LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() - # XRIO only depends on oxr_utils (header-only library with OpenXR types) # It does NOT depend on or link to the OpenXR loader if(NOT TARGET oxr::oxr_utils) diff --git a/src/core/xrio/cpp/controllertracker.cpp b/src/core/xrio/cpp/controllertracker.cpp index 7d0d322d..2d8799cf 100644 --- a/src/core/xrio/cpp/controllertracker.cpp +++ b/src/core/xrio/cpp/controllertracker.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace core { @@ -16,6 +17,17 @@ namespace // Helper functions for getting OpenXR action states +XrPath xr_path_from_string(const OpenXRCoreFunctions& funcs, XrInstance instance, const char* s) +{ + XrPath path = XR_NULL_PATH; + XrResult res = funcs.xrStringToPath(instance, s, &path); + if (XR_FAILED(res)) + { + throw std::runtime_error(std::string("xrStringToPath failed for '") + s + "': " + std::to_string(res)); + } + return path; +} + bool get_boolean_action_state(XrSession session, const OpenXRCoreFunctions& core_funcs, XrAction action, XrPath subaction_path) { XrActionStateGetInfo get_info{ XR_TYPE_ACTION_STATE_GET_INFO }; @@ -69,6 +81,42 @@ bool get_vector2_action_state(XrSession session, return false; } +XrSpacePtr create_space(const OpenXRCoreFunctions& funcs, XrSession session, XrAction action, XrPath subaction_path) +{ + assert(action != XR_NULL_HANDLE); + assert(subaction_path != XR_NULL_PATH); + + XrActionSpaceCreateInfo space_info{ XR_TYPE_ACTION_SPACE_CREATE_INFO }; + space_info.action = action; + space_info.subactionPath = subaction_path; + space_info.poseInActionSpace.orientation = { 0.0f, 0.0f, 0.0f, 1.0f }; + space_info.poseInActionSpace.position = { 0.0f, 0.0f, 0.0f }; + + return createActionSpace(funcs, session, &space_info); +}; + +XrAction create_action(const OpenXRCoreFunctions& funcs, XrActionSet action_set, XrPath left_hand_path, XrPath right_hand_path, const char* name, const char* localized_name, XrActionType type) +{ + XrAction out_action; + + XrPath hand_paths[2] = { left_hand_path, right_hand_path }; + + XrActionCreateInfo action_info{ XR_TYPE_ACTION_CREATE_INFO }; + action_info.actionType = type; + strcpy(action_info.actionName, name); + strcpy(action_info.localizedActionName, localized_name); + action_info.countSubactionPaths = 2; // BOTH hands + action_info.subactionPaths = hand_paths; + + XrResult res = funcs.xrCreateAction(action_set, &action_info, &out_action); + if (XR_FAILED(res)) + { + throw std::runtime_error(std::string("Failed to create action ") + name + ": " + std::to_string(res)); + } + + return out_action; +}; + } // anonymous namespace // ============================================================================ @@ -80,62 +128,27 @@ ControllerTracker::Impl::Impl(const OpenXRSessionHandles& handles) : core_funcs_(OpenXRCoreFunctions::load(handles.instance, handles.xrGetInstanceProcAddr)), session_(handles.session), base_space_(handles.space), - grip_pose_action_(XR_NULL_HANDLE), - aim_pose_action_(XR_NULL_HANDLE), - primary_click_action_(XR_NULL_HANDLE), - secondary_click_action_(XR_NULL_HANDLE), - thumbstick_action_(XR_NULL_HANDLE), - thumbstick_click_action_(XR_NULL_HANDLE), - squeeze_value_action_(XR_NULL_HANDLE), - trigger_value_action_(XR_NULL_HANDLE), - left_hand_path_(XR_NULL_PATH), - right_hand_path_(XR_NULL_PATH) -{ - // Create action set for both controllers - XrActionSetCreateInfo action_set_info{ XR_TYPE_ACTION_SET_CREATE_INFO }; - strcpy(action_set_info.actionSetName, "controller_tracking"); - strcpy(action_set_info.localizedActionSetName, "Controller Tracking"); - action_set_info.priority = 0; - - action_set_ = createActionSet(core_funcs_, handles.instance, &action_set_info); - - // Create hand paths for BOTH hands - core_funcs_.xrStringToPath(handles.instance, "/user/hand/left", &left_hand_path_); - core_funcs_.xrStringToPath(handles.instance, "/user/hand/right", &right_hand_path_); - XrPath hand_paths[2] = { left_hand_path_, right_hand_path_ }; - - // Create actions with BOTH subaction paths - auto create_action = [&](const char* name, const char* localized_name, XrActionType type, XrAction& out_action) - { - XrActionCreateInfo action_info{ XR_TYPE_ACTION_CREATE_INFO }; - action_info.actionType = type; - strcpy(action_info.actionName, name); - strcpy(action_info.localizedActionName, localized_name); - action_info.countSubactionPaths = 2; // BOTH hands - action_info.subactionPaths = hand_paths; - - XrResult res = core_funcs_.xrCreateAction(*action_set_, &action_info, &out_action); - if (XR_FAILED(res)) - { - throw std::runtime_error(std::string("Failed to create action ") + name + ": " + std::to_string(res)); - } - }; - - // Create all actions - only the ones we care about - create_action("grip_pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT, grip_pose_action_); - create_action("aim_pose", "Aim Pose", XR_ACTION_TYPE_POSE_INPUT, aim_pose_action_); - create_action("primary_click", "Primary Click", XR_ACTION_TYPE_BOOLEAN_INPUT, primary_click_action_); - create_action("secondary_click", "Secondary Click", XR_ACTION_TYPE_BOOLEAN_INPUT, secondary_click_action_); - create_action("thumbstick", "Thumbstick", XR_ACTION_TYPE_VECTOR2F_INPUT, thumbstick_action_); - create_action("thumbstick_click", "Thumbstick Click", XR_ACTION_TYPE_BOOLEAN_INPUT, thumbstick_click_action_); - create_action("squeeze_value", "Squeeze Value", XR_ACTION_TYPE_FLOAT_INPUT, squeeze_value_action_); - create_action("trigger_value", "Trigger Value", XR_ACTION_TYPE_FLOAT_INPUT, trigger_value_action_); - - // Suggest bindings for Oculus Touch controller profile - XrPath interaction_profile_path; - core_funcs_.xrStringToPath( - handles.instance, "/interaction_profiles/oculus/touch_controller", &interaction_profile_path); + left_hand_path_(xr_path_from_string(core_funcs_, handles.instance, "/user/hand/left")), + right_hand_path_(xr_path_from_string(core_funcs_, handles.instance, "/user/hand/right")), + + action_set_(createActionSet(core_funcs_, handles.instance, { .type = XR_TYPE_ACTION_SET_CREATE_INFO, + .actionSetName = "controller_tracking", + .localizedActionSetName = "Controller Tracking" })), + grip_pose_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "grip_pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT)), + aim_pose_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "aim_pose", "Aim Pose", XR_ACTION_TYPE_POSE_INPUT)), + primary_click_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "primary_click", "Primary Click", XR_ACTION_TYPE_BOOLEAN_INPUT)), + secondary_click_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "secondary_click", "Secondary Click", XR_ACTION_TYPE_BOOLEAN_INPUT)), + thumbstick_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "thumbstick", "Thumbstick", XR_ACTION_TYPE_VECTOR2F_INPUT)), + thumbstick_click_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "thumbstick_click", "Thumbstick Click", XR_ACTION_TYPE_BOOLEAN_INPUT)), + squeeze_value_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "squeeze_value", "Squeeze Value", XR_ACTION_TYPE_FLOAT_INPUT)), + trigger_value_action_(create_action(core_funcs_, action_set_.get(), left_hand_path_, right_hand_path_, "trigger_value", "Trigger Value", XR_ACTION_TYPE_FLOAT_INPUT)), + + left_grip_space_(create_space(core_funcs_, session_, grip_pose_action_, left_hand_path_)), + right_grip_space_(create_space(core_funcs_, session_, grip_pose_action_, right_hand_path_)), + left_aim_space_(create_space(core_funcs_, session_, aim_pose_action_, left_hand_path_)), + right_aim_space_(create_space(core_funcs_, session_, aim_pose_action_, right_hand_path_)) +{ std::vector bindings; auto add_binding = [&](XrAction action, const char* path) { @@ -166,8 +179,10 @@ ControllerTracker::Impl::Impl(const OpenXRSessionHandles& handles) add_binding(primary_click_action_, "/user/hand/right/input/a/click"); // Right: A add_binding(secondary_click_action_, "/user/hand/right/input/b/click"); // Right: B + // Suggest bindings for Oculus Touch controller profile XrInteractionProfileSuggestedBinding suggested_bindings{ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING }; - suggested_bindings.interactionProfile = interaction_profile_path; + suggested_bindings.interactionProfile = xr_path_from_string( + core_funcs_, handles.instance, "/interaction_profiles/oculus/touch_controller"); suggested_bindings.countSuggestedBindings = static_cast(bindings.size()); suggested_bindings.suggestedBindings = bindings.data(); @@ -180,7 +195,7 @@ ControllerTracker::Impl::Impl(const OpenXRSessionHandles& handles) std::cout << "ControllerTracker: Using Oculus Touch Controller profile" << std::endl; // Attach action set to session - XrActionSet action_set_handle = *action_set_; + XrActionSet action_set_handle = action_set_.get(); XrSessionActionSetsAttachInfo attach_info{ XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO }; attach_info.countActionSets = 1; attach_info.actionSets = &action_set_handle; @@ -191,37 +206,15 @@ ControllerTracker::Impl::Impl(const OpenXRSessionHandles& handles) throw std::runtime_error("Failed to attach action sets: " + std::to_string(result)); } - // Create action spaces for both hands - auto create_space = [&](XrAction action, XrPath subaction_path, XrSpacePtr& out_space) - { - XrActionSpaceCreateInfo space_info{ XR_TYPE_ACTION_SPACE_CREATE_INFO }; - space_info.action = action; - space_info.subactionPath = subaction_path; - space_info.poseInActionSpace.orientation = { 0.0f, 0.0f, 0.0f, 1.0f }; - space_info.poseInActionSpace.position = { 0.0f, 0.0f, 0.0f }; - - out_space = createActionSpace(core_funcs_, handles.session, &space_info); - }; - - create_space(grip_pose_action_, left_hand_path_, left_grip_space_); - create_space(grip_pose_action_, right_hand_path_, right_grip_space_); - create_space(aim_pose_action_, left_hand_path_, left_aim_space_); - create_space(aim_pose_action_, right_hand_path_, right_aim_space_); - std::cout << "ControllerTracker initialized (left + right)" << std::endl; } -ControllerTracker::Impl::~Impl() -{ - // Smart pointers automatically clean up action_set_ and all spaces -} - // Override from ITrackerImpl bool ControllerTracker::Impl::update(XrTime time) { // Sync actions XrActionsSyncInfo sync_info{ XR_TYPE_ACTIONS_SYNC_INFO }; - XrActiveActionSet active_action_set{ *action_set_, XR_NULL_PATH }; + XrActiveActionSet active_action_set{ action_set_.get(), XR_NULL_PATH }; sync_info.countActiveActionSets = 1; sync_info.activeActionSets = &active_action_set; @@ -238,7 +231,7 @@ bool ControllerTracker::Impl::update(XrTime time) { // Update poses XrSpaceLocation grip_location{ XR_TYPE_SPACE_LOCATION }; - result = core_funcs_.xrLocateSpace(*grip_space, base_space_, time, &grip_location); + result = core_funcs_.xrLocateSpace(grip_space.get(), base_space_, time, &grip_location); if (XR_SUCCEEDED(result)) { snapshot.grip_pose.is_valid = (grip_location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) && @@ -256,7 +249,7 @@ bool ControllerTracker::Impl::update(XrTime time) } XrSpaceLocation aim_location{ XR_TYPE_SPACE_LOCATION }; - result = core_funcs_.xrLocateSpace(*aim_space, base_space_, time, &aim_location); + result = core_funcs_.xrLocateSpace(aim_space.get(), base_space_, time, &aim_location); if (XR_SUCCEEDED(result)) { snapshot.aim_pose.is_valid = (aim_location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) && diff --git a/src/core/xrio/cpp/headtracker.cpp b/src/core/xrio/cpp/headtracker.cpp index f0358f7c..7a4d214c 100644 --- a/src/core/xrio/cpp/headtracker.cpp +++ b/src/core/xrio/cpp/headtracker.cpp @@ -17,24 +17,12 @@ namespace core // Constructor - throws std::runtime_error on failure HeadTracker::Impl::Impl(const OpenXRSessionHandles& handles) : core_funcs_(OpenXRCoreFunctions::load(handles.instance, handles.xrGetInstanceProcAddr)), - base_space_(handles.space) + base_space_(handles.space), + view_space_(createReferenceSpace(core_funcs_, handles.session, { .type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO, + .referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW, + .poseInReferenceSpace = { .orientation = {0, 0, 0, 1} } })), + head_{} { - // Create VIEW space for head tracking (represents HMD pose) - XrReferenceSpaceCreateInfo create_info{ XR_TYPE_REFERENCE_SPACE_CREATE_INFO }; - create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW; - create_info.poseInReferenceSpace.orientation.w = 1.0f; - - view_space_ = createReferenceSpace(core_funcs_, handles.session, &create_info); - - head_.is_valid = false; - head_.timestamp = 0; - - std::cout << "HeadTracker initialized" << std::endl; -} - -HeadTracker::Impl::~Impl() -{ - // Smart pointer automatically cleans up view_space_ } // Override from ITrackerImpl @@ -42,7 +30,7 @@ bool HeadTracker::Impl::update(XrTime time) { // Locate the view space (head) relative to the base space XrSpaceLocation location{ XR_TYPE_SPACE_LOCATION }; - XrResult result = core_funcs_.xrLocateSpace(*view_space_, base_space_, time, &location); + XrResult result = core_funcs_.xrLocateSpace(view_space_.get(), base_space_, time, &location); if (XR_FAILED(result)) { diff --git a/src/core/xrio/cpp/inc/xrio/controllertracker.hpp b/src/core/xrio/cpp/inc/xrio/controllertracker.hpp index c04a7aeb..a517e162 100644 --- a/src/core/xrio/cpp/inc/xrio/controllertracker.hpp +++ b/src/core/xrio/cpp/inc/xrio/controllertracker.hpp @@ -84,11 +84,8 @@ class ControllerTracker : public ITracker class Impl : public ITrackerImpl { public: - // Constructor - throws std::runtime_error on failure explicit Impl(const OpenXRSessionHandles& handles); - ~Impl(); - // Override from ITrackerImpl bool update(XrTime time) override; @@ -100,6 +97,10 @@ class ControllerTracker : public ITracker XrSession session_; XrSpace base_space_; + // Paths for both hands + XrPath left_hand_path_; + XrPath right_hand_path_; + // Actions - simplified to only the inputs we care about XrActionSetPtr action_set_; XrAction grip_pose_action_; @@ -117,10 +118,6 @@ class ControllerTracker : public ITracker XrSpacePtr left_aim_space_; XrSpacePtr right_aim_space_; - // Paths for both hands - XrPath left_hand_path_; - XrPath right_hand_path_; - // Controller data for both hands ControllerSnapshot left_snapshot_; ControllerSnapshot right_snapshot_; diff --git a/src/core/xrio/cpp/inc/xrio/headtracker.hpp b/src/core/xrio/cpp/inc/xrio/headtracker.hpp index 86d42818..bf998d1b 100644 --- a/src/core/xrio/cpp/inc/xrio/headtracker.hpp +++ b/src/core/xrio/cpp/inc/xrio/headtracker.hpp @@ -42,11 +42,8 @@ class HeadTracker : public ITracker class Impl : public ITrackerImpl { public: - // Constructor - throws std::runtime_error on failure explicit Impl(const OpenXRSessionHandles& handles); - ~Impl(); - // Override from ITrackerImpl bool update(XrTime time) override; diff --git a/src/plugins/controller_synthetic_hands/CMakeLists.txt b/src/plugins/controller_synthetic_hands/CMakeLists.txt index 8ea3522a..146e511f 100644 --- a/src/plugins/controller_synthetic_hands/CMakeLists.txt +++ b/src/plugins/controller_synthetic_hands/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required(VERSION 3.20) -# If this is being built standalone, declare a project -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - project(controller_synthetic_hands VERSION 1.0.0 LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() - # Create executable add_executable(controller_synthetic_hands controller_synthetic_hands.cpp