diff --git a/assets/lang/en_GB.json b/assets/lang/en_GB.json index f796a4b..a63b6f6 100644 --- a/assets/lang/en_GB.json +++ b/assets/lang/en_GB.json @@ -5,8 +5,9 @@ "ipc_unavailable": "Failed to connect to Space Calibrator SteamVR driver. Please verify file integrity in properties, installed files, or re-install the app.", "steamvr_unavailable": "Failed to connect to SteamVR.", + "vr_troubleshooting_hmd_not_found": "Please connect your VR headset and launch SteamVR first.", "vr_troubleshooting_connect_steamlink": "Please open SteamLink on your VR headset and connect to SteamVR first.", - "vr_troubleshooting_generic": "Please connect your VR headset and launch SteamVR first.", + "vr_troubleshooting_generic": "Please connect your VR headset and launch SteamVR first. ({0} {1})", // space here refers to a tracking space / tracking system. "reference_space": "Reference space", diff --git a/src/overlay/localisation.h b/src/overlay/localisation.h index be2143c..c949d43 100644 --- a/src/overlay/localisation.h +++ b/src/overlay/localisation.h @@ -1,6 +1,7 @@ #pragma once #include "platform.h" +#include "log_formatters.h" #include #include #include diff --git a/src/overlay/user_interface.cpp b/src/overlay/user_interface.cpp index 58ef5a4..70ddaef 100644 --- a/src/overlay/user_interface.cpp +++ b/src/overlay/user_interface.cpp @@ -8,6 +8,20 @@ namespace spacecal { bool bIsRunningInOverlay = false; + inline std::string getTrackingSystemFriendlyName(const std::string& szTrackingSystemName) { + + // maps tracking system name to a unique entry per tracking device + if (szTrackingSystemName == "lighthouse") { + return "SteamVR Tracking"; // @NOTE: should this be localised? + } + if (szTrackingSystemName == "oculus") { + // @TODO: if vd then set as virtual desktop + // return "Virtual Desktop"; // @NOTE: should this be localised? + } + + return szTrackingSystemName; + } + inline void BuildVersionInfo() { ImGui::SetNextWindowPos(ImVec2(10.0f, ImGui::GetWindowHeight() - ImGui::GetFrameHeightWithSpacing())); ImGui::BeginChild("spacecal_version_box", ImVec2(ImGui::GetWindowWidth() - 20.0f, ImGui::GetFrameHeightWithSpacing() * 2), ImGuiChildFlags_None); @@ -19,9 +33,8 @@ namespace spacecal { ImGui::EndChild(); } - inline void BuildTrackingSystemSelection() { - if (VRState::getInstance()->getTrackingSystemCount() == 0) - { + inline void BuildTrackingSystemSelection(spacecal::TrackingSystemCalibration& calibration) { + if (VRState::getInstance()->getTrackingSystemCount() == 0) { ImGui::Text("%s", LOCALE_GET("tracking_system_no_systems").c_str()); // No tracked devices present. Please turn on a device to continue. return; } @@ -32,6 +45,59 @@ namespace spacecal { ImGui::TextWithWidth("ReferenceSystemLabel", LOCALE_GET("reference_space").c_str(), paneWidth); ImGui::SameLine(); ImGui::TextWithWidth("TargetSystemLabel", LOCALE_GET("target_space").c_str(), paneWidth); + + int currentReferenceSystem = -1; + int currentTargetSystem = -1; + int firstReferenceSystemNotTargetSystem = -1; + + // build ui table for ref tracking systems + std::vector referenceSystems; + std::vector referenceSystemsUi; + for (size_t i = 0; i < VRState::getInstance()->getTrackingSystemCount(); i++) { + const std::string szTrackingSystemName = VRState::getInstance()->getTrackingSystem(i); + const std::string szTrackingSystemUiName = getTrackingSystemFriendlyName(szTrackingSystemName); + + if (szTrackingSystemName == calibration.referenceDevice.trackingSystem) + currentReferenceSystem = (int)referenceSystems.size(); + else if (firstReferenceSystemNotTargetSystem == -1 && szTrackingSystemName != calibration.targetDevice.trackingSystem) + firstReferenceSystemNotTargetSystem = (int)referenceSystems.size(); + + referenceSystems.push_back(szTrackingSystemName.c_str()); + referenceSystemsUi.push_back(szTrackingSystemUiName.c_str()); + } + + ImGui::PushItemWidth(paneWidth); + ImGui::Combo("##ReferenceTrackingSystem", ¤tReferenceSystem, &referenceSystemsUi[0], (int)referenceSystemsUi.size()); + + // if we have an entry selected assign to reference + if (currentReferenceSystem != -1 && currentReferenceSystem < (int)referenceSystems.size()) { + calibration.referenceDevice.trackingSystem = std::string(referenceSystems[currentReferenceSystem]); + if (calibration.referenceDevice.trackingSystem == calibration.targetDevice.trackingSystem) + calibration.targetDevice.trackingSystem = ""; + } + + // target tracking system list is tracking system list EXCLUDING reference tracking system. one may NOT calibrate two devices of the same tracking system! + std::vector targetSystems; + std::vector targetSystemsUi; + for (size_t i = 0; i < VRState::getInstance()->getTrackingSystemCount(); i++) { + const std::string szTrackingSystemName = VRState::getInstance()->getTrackingSystem(i); + if (szTrackingSystemName != calibration.referenceDevice.trackingSystem) + { + if (szTrackingSystemName != "" && szTrackingSystemName == calibration.targetDevice.trackingSystem) + currentTargetSystem = (int)targetSystems.size(); + targetSystems.push_back(szTrackingSystemName.c_str()); + targetSystemsUi.push_back(getTrackingSystemFriendlyName(szTrackingSystemName).c_str()); + } + } + + ImGui::SameLine(); + ImGui::Combo("##TargetTrackingSystem", ¤tTargetSystem, &targetSystemsUi[0], (int)targetSystemsUi.size()); + + // if we have an entry selected assign to target + if (currentTargetSystem != -1 && currentTargetSystem < targetSystems.size()) + calibration.targetDevice.trackingSystem = std::string(targetSystems[currentTargetSystem]); + + ImGui::PopItemWidth(); } inline bool isSpacecalRunningStateOk() { @@ -41,12 +107,18 @@ namespace spacecal { inline void drawTroubleshootView() { if (!VRState::getInstance()->isSteamVrAvailable()) { ImGui::Text("%s", LOCALE_GET("steamvr_unavailable").c_str()); - switch (VRState::getInstance()->getVrInitError()) { + vr::EVRInitError eVrErr = VRState::getInstance()->getVrInitError(); + switch (eVrErr) { case vr::EVRInitError::VRInitError_Driver_WirelessHmdNotConnected: ImGui::Text("%s", LOCALE_GET("vr_troubleshooting_connect_steamlink").c_str()); break; + case vr::EVRInitError::VRInitError_Init_HmdNotFound: + ImGui::Text("%s", LOCALE_GET("vr_troubleshooting_hmd_not_found").c_str()); + break; default: - ImGui::Text("%s", LOCALE_GET("vr_troubleshooting_generic").c_str()); + // need to pass by ref, cant pass as literal value + uint32_t dwVrErr = (uint32_t)VRState::getInstance()->getVrInitError(); + ImGui::Text("%s", LOCALE_FORMAT("vr_troubleshooting_generic", dwVrErr, eVrErr).c_str()); break; } } else if (CalibrationManager::getInstance()->getIpcClient().IsConnected()) { @@ -91,7 +163,7 @@ namespace spacecal { } // @TODO: build ui - BuildTrackingSystemSelection(); + BuildTrackingSystemSelection(calibration); } } diff --git a/src/overlay/vr_core.h b/src/overlay/vr_core.h index de37aa8..009bd2e 100644 --- a/src/overlay/vr_core.h +++ b/src/overlay/vr_core.h @@ -3,6 +3,7 @@ #include #include #include +#include "protocol.h" namespace spacecal { struct VRDevice_t { @@ -26,6 +27,7 @@ namespace spacecal { const VRDevice_t getVrDevice(const size_t index) const; [[nodiscard]] size_t getTrackingSystemCount() const { return m_aTrackingSystems.size(); } + [[nodiscard]] const std::string& getTrackingSystem(size_t index) const { return m_aTrackingSystems[index]; } [[nodiscard]] vr::VROverlayHandle_t getOverlayHandle() const { return m_overlayMainHandle; } [[nodiscard]] vr::VROverlayHandle_t getOverlayThumbnailHandle() const { return m_overlayThumbnailHandle; } [[nodiscard]] static inline VRState* getInstance() { return s_instance; }