From 5f7b3e63e7bbfb98f13abf6c30611525b56d125a Mon Sep 17 00:00:00 2001 From: Unique One Date: Sat, 19 Jun 2021 00:15:58 +1000 Subject: [PATCH] Ability to offset real world player vs VR avatar heights, for hands, hip, and feet trackers. It is fairly basic but functional, posted as a reference for pushrax, if he wants it. --- OpenVR-SpaceCalibrator/Calibration.cpp | 99 ++++++++++++++++++++++-- OpenVR-SpaceCalibrator/Calibration.h | 14 ++++ OpenVR-SpaceCalibrator/UserInterface.cpp | 98 +++++++++++++++++++++++ 3 files changed, 204 insertions(+), 7 deletions(-) diff --git a/OpenVR-SpaceCalibrator/Calibration.cpp b/OpenVR-SpaceCalibrator/Calibration.cpp index 5472b8e..b948ed5 100644 --- a/OpenVR-SpaceCalibrator/Calibration.cpp +++ b/OpenVR-SpaceCalibrator/Calibration.cpp @@ -250,16 +250,81 @@ vr::HmdQuaternion_t VRRotationQuat(Eigen::Vector3d eulerdeg) return vrRotQuat; } -vr::HmdVector3d_t VRTranslationVec(Eigen::Vector3d transcm) +vr::HmdVector3d_t VRTranslationVec(Eigen::Vector3d transcm, Eigen::Vector3d adjustTranslation) { auto trans = transcm * 0.01; vr::HmdVector3d_t vrTrans; - vrTrans.v[0] = trans[0]; - vrTrans.v[1] = trans[1]; - vrTrans.v[2] = trans[2]; + vrTrans.v[0] = trans[0] + adjustTranslation[0]; + vrTrans.v[1] = trans[1] + adjustTranslation[1]; + vrTrans.v[2] = trans[2] + adjustTranslation[2]; return vrTrans; } +float GetOffsetForID(uint32_t id) +{ + float customScale = 1.0f - CalCtx.customScale; + + switch (CalCtx.offsetsEnabled) + { + case CalibrationContext::OFFSETS_NONE: + default: + break; + case CalibrationContext::OFFSETS_4_DEVICE_HANDS: + { + switch (id) + {// These are all messed up! Controllers use 2 devices each??? + case vr::k_unTrackedDeviceIndex_Hmd: // HMD + break; + case 1: // left hand - dev1 + case 2: // left hand - dev2 + case 3: // right hand - dev1 + case 4: // right hand - dev2 + return customScale * CalCtx.handsOffsetScale; + break; + case 5: // waist + return customScale * CalCtx.hipOffsetScale; + break; + case 6: // left foot + return customScale * CalCtx.feetOffsetScale; + break; + case 7: // right foot + return customScale * CalCtx.feetOffsetScale; + break; + default: + return customScale * CalCtx.feetOffsetScale; + break; + } + } + break; + case CalibrationContext::OFFSETS_2_DEVICE_HANDS: + { + switch (id) + { + case vr::k_unTrackedDeviceIndex_Hmd: // HMD + break; + case 1: // left hand + case 2: // right hand + return customScale * CalCtx.handsOffsetScale; + break; + case 3: // waist + return customScale * CalCtx.hipOffsetScale; + break; + case 4: // left foot + return customScale * CalCtx.feetOffsetScale; + break; + case 5: // right foot + return customScale * CalCtx.feetOffsetScale; + break; + default: + return customScale * CalCtx.feetOffsetScale; + break; + } + } + } + + return 0.0f; +} + void ResetAndDisableOffsets(uint32_t id) { vr::HmdVector3d_t zeroV; @@ -267,9 +332,22 @@ void ResetAndDisableOffsets(uint32_t id) vr::HmdQuaternion_t zeroQ; zeroQ.x = 0; zeroQ.y = 0; zeroQ.z = 0; zeroQ.w = 1; + + Eigen::Vector3d adjustTranslation; + adjustTranslation[0] = adjustTranslation[1] = adjustTranslation[2] = 0; + adjustTranslation[1] += GetOffsetForID(id); + + Eigen::Vector3d zeroTranslation; + zeroTranslation[0] = zeroTranslation[1] = zeroTranslation[2] = 0; protocol::Request req(protocol::RequestSetDeviceTransform); - req.setDeviceTransform = { id, false, zeroV, zeroQ }; + //req.setDeviceTransform = { id, false, zeroV, zeroQ }; + req.setDeviceTransform = { + id, + true, + VRTranslationVec(zeroTranslation, adjustTranslation), + zeroQ + }; Driver.SendBlocking(req); } @@ -333,11 +411,15 @@ void ScanAndApplyProfile(CalibrationContext &ctx) continue; } + Eigen::Vector3d adjustTranslation; + adjustTranslation[0] = adjustTranslation[1] = adjustTranslation[2] = 0; + adjustTranslation[1] += GetOffsetForID(id); + protocol::Request req(protocol::RequestSetDeviceTransform); req.setDeviceTransform = { id, true, - VRTranslationVec(ctx.calibratedTranslation), + VRTranslationVec(ctx.calibratedTranslation, adjustTranslation), VRRotationQuat(ctx.calibratedRotation) }; Driver.SendBlocking(req); @@ -477,7 +559,10 @@ void CalibrationTick(double time) { ctx.calibratedTranslation = CalibrateTranslation(samples); - auto vrTrans = VRTranslationVec(ctx.calibratedTranslation); + Eigen::Vector3d adjustTranslation; + adjustTranslation[0] = adjustTranslation[1] = adjustTranslation[2] = 0; + + auto vrTrans = VRTranslationVec(ctx.calibratedTranslation, adjustTranslation); protocol::Request req(protocol::RequestSetDeviceTransform); req.setDeviceTransform = { ctx.targetID, true, vrTrans }; diff --git a/OpenVR-SpaceCalibrator/Calibration.h b/OpenVR-SpaceCalibrator/Calibration.h index 3a49f5c..452fe88 100644 --- a/OpenVR-SpaceCalibrator/Calibration.h +++ b/OpenVR-SpaceCalibrator/Calibration.h @@ -37,6 +37,20 @@ struct CalibrationContext }; Speed calibrationSpeed = FAST; + enum OffsetMode + { + OFFSETS_NONE = 0, + OFFSETS_2_DEVICE_HANDS = 1, + OFFSETS_4_DEVICE_HANDS = 2, + }; + OffsetMode offsetsEnabled = OFFSETS_NONE; + + float customScale = 1.0f; + float handsOffsetScale = 0.65f; + float hipOffsetScale = 1.1f; + float feetOffsetScale = 1.25f; + + vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount]; struct Chaperone diff --git a/OpenVR-SpaceCalibrator/UserInterface.cpp b/OpenVR-SpaceCalibrator/UserInterface.cpp index c19f6af..83c452c 100644 --- a/OpenVR-SpaceCalibrator/UserInterface.cpp +++ b/OpenVR-SpaceCalibrator/UserInterface.cpp @@ -11,6 +11,9 @@ #define VERSION_STRING "1.2" +bool ENABLE_OFFSETS_2_DEVICE_HANDS = false; +bool ENABLE_OFFSETS_4_DEVICE_HANDS = false; + struct VRDevice { int id = -1; @@ -155,6 +158,101 @@ void BuildMenu(bool runningInOverlay) CalCtx.calibrationSpeed = CalibrationContext::VERY_SLOW; ImGui::Columns(1); + + // + // UQ1: Offsets... TODO: These should really be saved, or have profiles for quick startup??? + // + ImGui::Text(""); + ImGui::Text(""); + ImGui::Text(""); + auto offsetMethod = CalCtx.offsetsEnabled; + + ImGui::Text("Player Height Adjustment"); + ImGui::Text("IMPORTANT: This system assumes you start devices in order:"); + ImGui::Text(" 1. Hand controllers."); + ImGui::Text(" 2. Hip tracker."); + ImGui::Text(" 3. Feet trackers."); + ImGui::Text(" 4. Any other trackers (these will share the feet offsets - untested)."); + ImGui::Text(""); + + ImGui::Text("Offsets"); + ImGui::Text(" No Offsets - disables offsets"); + ImGui::Text(" 2 Devices - If your hardware uses 2 devices for hand controllers (Quest 2 using Virtual Desktop etc)"); + ImGui::Text(" 4 Devices - If your hardware uses 4 devices for hand controllers (Vive, etc)"); + ImGui::Text(""); + ImGui::Text("You can freely switch between these options to work out which is correct for your hardware without loosing setting changes below."); + ImGui::Text(""); + + ImGui::Columns(3, NULL, false); + /* + ImGui::Columns(4, NULL, false); + ImGui::Text("Offsets"); + + ImGui::NextColumn(); + */ + + if (ImGui::RadioButton(" No Offsets ", offsetMethod == CalibrationContext::OFFSETS_NONE)) + CalCtx.offsetsEnabled = CalibrationContext::OFFSETS_NONE; + + ImGui::NextColumn(); + if (ImGui::RadioButton(" 2 Devices ", offsetMethod == CalibrationContext::OFFSETS_2_DEVICE_HANDS)) + CalCtx.offsetsEnabled = CalibrationContext::OFFSETS_2_DEVICE_HANDS; + + ImGui::NextColumn(); + if (ImGui::RadioButton(" 4 Devices ", offsetMethod == CalibrationContext::OFFSETS_4_DEVICE_HANDS)) + CalCtx.offsetsEnabled = CalibrationContext::OFFSETS_4_DEVICE_HANDS; + + ImGui::Text(""); + ImGui::Columns(1); + + ImGui::Text(""); + auto offsetScale = CalCtx.customScale; + + if (ImGui::DragFloat(" Scale ", &offsetScale, 0.0001f, 0.001f, 2.000f, "%.3f", 1.0f)) + CalCtx.customScale = offsetScale; + + ImGui::Text(""); + ImGui::Text("Fine Tune Custom Offsets"); + ImGui::Text("These are strengths of offsets of each tracked body part type. Use these to customize as needed."); + auto handsOffsetScale = CalCtx.handsOffsetScale; + auto hipOffsetScale = CalCtx.hipOffsetScale; + auto feetOffsetScale = CalCtx.feetOffsetScale; + + if (ImGui::DragFloat(" Hands ", &handsOffsetScale, 0.0001f, 0.001f, 2.000f, "%.3f", 1.0f)) + CalCtx.handsOffsetScale = handsOffsetScale; + + if (ImGui::DragFloat(" Hip ", &hipOffsetScale, 0.0001f, 0.001f, 2.000f, "%.3f", 1.0f)) + CalCtx.hipOffsetScale = hipOffsetScale; + + if (ImGui::DragFloat(" Feet ", &feetOffsetScale, 0.0001f, 0.001f, 2.000f, "%.3f", 1.0f)) + CalCtx.feetOffsetScale = feetOffsetScale; + + ImGui::Text(""); + + // + // + // + /* + ImGui::Text(""); + + char buffer[vr::k_unMaxPropertyStringSize]; + + for (uint32_t id = 0; id < vr::k_unMaxTrackedDeviceCount; ++id) + { + auto deviceClass = vr::VRSystem()->GetTrackedDeviceClass(id); + if (deviceClass == vr::TrackedDeviceClass_Invalid) + continue; + + vr::ETrackedPropertyError err = vr::TrackedProp_Success; + vr::VRSystem()->GetStringTrackedDeviceProperty(id, vr::Prop_TrackingSystemName_String, buffer, vr::k_unMaxPropertyStringSize, &err); + + if (err != vr::TrackedProp_Success) + { + continue; + } + + ImGui::Text("Device %u - class %u\n", id, deviceClass); + }*/ } else if (CalCtx.state == CalibrationState::Editing) {