diff --git a/.gitmodules b/.gitmodules index c3b3e5b45234cb4b36b4367c5b112ffbc3ac8b4b..9143dac8256b5a96ac64722ba8af10b707a14898 100644 --- a/.gitmodules +++ b/.gitmodules @@ -82,3 +82,6 @@ [submodule "modules/shader_compiler/lib/json-c"] path = modules/shader_compiler/lib/json-c url = https://github.com/json-c/json-c.git +[submodule "modules/camera/lib/OpenXR-SDK"] + path = modules/camera/lib/OpenXR-SDK + url = https://github.com/KhronosGroup/OpenXR-SDK.git diff --git a/modules/camera/CMakeLists.txt b/modules/camera/CMakeLists.txt index 4cf68f9c4171dbd29e7b29fa2b73d20e333b2531..ac137434370f9d0e5351856d18c53370ae0114fd 100644 --- a/modules/camera/CMakeLists.txt +++ b/modules/camera/CMakeLists.txt @@ -22,6 +22,9 @@ set(vkcv_camera_sources ${vkcv_camera_include}/vkcv/camera/TrackballCameraController.hpp ${vkcv_camera_source}/vkcv/camera/TrackballCameraController.cpp + + ${vkcv_camera_include}/vkcv/camera/XRCameraController.hpp + ${vkcv_camera_source}/vkcv/camera/XRCameraController.cpp ) filter_headers(vkcv_camera_sources ${vkcv_camera_include} vkcv_camera_headers) @@ -34,6 +37,9 @@ set_target_properties(vkcv_camera PROPERTIES PUBLIC_HEADER "${vkcv_camera_header set(vkcv_camera_lib lib) set(vkcv_camera_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_camera_lib}) +# Check and load OpenXR-SDK +include(config/OPEN_XR_SDK.cmake) + target_link_libraries(vkcv_camera PUBLIC ${vkcv_camera_libraries} vkcv diff --git a/modules/camera/config/OPEN_XR_SDK.cmake b/modules/camera/config/OPEN_XR_SDK.cmake new file mode 100644 index 0000000000000000000000000000000000000000..b38aa10a314f9fe56c6826cbc9dd4892c4dbeb3c --- /dev/null +++ b/modules/camera/config/OPEN_XR_SDK.cmake @@ -0,0 +1,10 @@ + +use_git_submodule("${vkcv_camera_lib_path}/OpenXR-SDK" open_xr_status) + +if (${open_xr_status}) + list(APPEND vkcv_camera_includes ${vkcv_camera_lib}/OpenXR-SDK/include) + + add_subdirectory(${vkcv_camera_lib}/OpenXR-SDK) + + list(APPEND vkcv_camera_definitions XR_USE_GRAPHICS_API_VULKAN) +endif () diff --git a/modules/camera/include/vkcv/camera/XRCameraController.hpp b/modules/camera/include/vkcv/camera/XRCameraController.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9b51b4eea165d7ea3bd3dff75bf46bceaa6e3c02 --- /dev/null +++ b/modules/camera/include/vkcv/camera/XRCameraController.hpp @@ -0,0 +1,98 @@ +#pragma once +/** + * @authors Tobias Frisch + * @file include/vkcv/camera/XRCameraController.hpp + * @brief XRCameraController class of the camera module for the vkcv framework. This class inherits from the base + * class @#CameraController and enables camera objects to be orbited around a specific center point. + */ + +#include "CameraController.hpp" + +#include <openxr/openxr.h> + +namespace vkcv::camera { + + /** + * @addtogroup vkcv_camera + * @{ + */ + + /** + * @brief Used to control the camera via an HMD. + */ + class XRCameraController final : public CameraController { + private: + XrInstance m_instance; + XrSystemId m_system_id; + XrSession m_session; + + public: + + /** + * @brief The default constructor of the #XRCameraController. + */ + XRCameraController(); + + /** + * @brief The destructor of the #XRCameraController (default behavior). + */ + ~XRCameraController(); + + /** + * @brief Updates @p camera in respect to @p deltaTime. + * @param[in] deltaTime The time that has passed since last update. + * @param[in] camera The camera object + */ + void updateCamera(double deltaTime, Camera &camera) override; + + /** + * @brief A callback function for key events. Currently, the trackball camera does not support camera movement. + * It can only orbit around its center point. + * @param[in] key The keyboard key. + * @param[in] scancode The platform-specific scancode. + * @param[in] action The key action. + * @param[in] mods The modifier bits. + * @param[in] camera The camera object. + */ + void keyCallback(int key, int scancode, int action, int mods, Camera &camera) override; + + /** + * @brief A callback function for mouse scrolling events. Currently, this leads to changes in the field of view + * of the camera object. + * @param[in] offsetX The offset in horizontal direction. + * @param[in] offsetY The offset in vertical direction. + * @param[in] camera The camera object. + */ + void scrollCallback(double offsetX, double offsetY, Camera &camera) override; + + /** + * @brief A callback function for mouse movement events. Currently, this leads to panning the view of the + * camera, if #mouseButtonCallback(int button, int action, int mods) enabled panning. + * @param[in] xoffset The horizontal mouse position. + * @param[in] yoffset The vertical mouse position. + * @param[in] camera The camera object. + */ + void mouseMoveCallback(double xoffset, double yoffset, Camera &camera) override; + + /** + * @brief A callback function for mouse button events. Currently, the right mouse button enables panning the + * view of the camera as long as it is pressed. + * @param[in] button The mouse button. + * @param[in] action The button action. + * @param[in] mods The modifier bits. + * @param[in] camera The camera object. + */ + void mouseButtonCallback(int button, int action, int mods, Camera &camera) override; + + /** + * @brief A callback function for gamepad input events. + * @param gamepadIndex The gamepad index. + * @param camera The camera object. + * @param frametime The current frametime. + */ + void gamepadCallback(int gamepadIndex, Camera &camera, double frametime) override; + }; + + /** @} */ + +} \ No newline at end of file diff --git a/modules/camera/lib/OpenXR-SDK b/modules/camera/lib/OpenXR-SDK new file mode 160000 index 0000000000000000000000000000000000000000..67cfb6a4bc5496451efcf5d35af017f4f1761648 --- /dev/null +++ b/modules/camera/lib/OpenXR-SDK @@ -0,0 +1 @@ +Subproject commit 67cfb6a4bc5496451efcf5d35af017f4f1761648 diff --git a/modules/camera/src/vkcv/camera/XRCameraController.cpp b/modules/camera/src/vkcv/camera/XRCameraController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57109a31fd1c88d4bd3c7fa7b3ed8001760e8589 --- /dev/null +++ b/modules/camera/src/vkcv/camera/XRCameraController.cpp @@ -0,0 +1,72 @@ + +#include "vkcv/camera/XRCameraController.hpp" + +namespace vkcv::camera { + + XRCameraController::XRCameraController() : + m_instance(XR_NULL_HANDLE), + m_system_id(XR_NULL_SYSTEM_ID), + m_session(XR_NULL_HANDLE) + { + XrInstanceCreateInfo instanceInfo {XR_TYPE_INSTANCE_CREATE_INFO}; + instanceInfo.next = nullptr; + instanceInfo.enabledExtensionCount = 0; + instanceInfo.enabledExtensionNames = nullptr; + + strcpy(instanceInfo.applicationInfo.applicationName, VKCV_FRAMEWORK_NAME); + + if (XR_SUCCESS != xrCreateInstance(&instanceInfo, &m_instance)) { + vkcv::log(vkcv::LogLevel::ERROR, "Creating an XR instance failed"); + } + + XrSystemGetInfo systemInfo {XR_TYPE_SYSTEM_GET_INFO}; + systemInfo.formFactor = m_options->Parsed.FormFactor; + + if (XR_SUCCESS != xrGetSystem(m_instance, &systemInfo, &m_system_id)) { + vkcv::log(vkcv::LogLevel::ERROR, "Getting an XR system id failed"); + } + + XrSessionCreateInfo sessionInfo {XR_TYPE_SESSION_CREATE_INFO}; + sessionInfo.next = nullptr; + sessionInfo.systemId = m_system_id; + + if (XR_SUCCESS != xrCreateSession(m_instance, &sessionInfo, &m_session)) { + vkcv::log(vkcv::LogLevel::ERROR, "Creating an XR session failed"); + } + } + + XRCameraController::~XRCameraController() { + if (m_session) { + xrDestroySession(m_session); + } + + if (m_instance) { + xrDestroyInstance(m_instance); + } + } + + void XRCameraController::updateCamera(double deltaTime, Camera &camera) { + // TODO + } + + void XRCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) { + // TODO + } + + void XRCameraController::scrollCallback(double offsetX, double offsetY, Camera &camera) { + // TODO + } + + void XRCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) { + // TODO + } + + void XRCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) { + // TODO + } + + void XRCameraController::gamepadCallback(int gamepadIndex, Camera &camera, double frametime) { + // TODO + } + +}