diff --git a/src/app.cpp b/src/app.cpp index cdf7552..222f888 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,5 +1,4 @@ #include "app.h" -#include "controller.h" #include "util.h" #include #include @@ -14,8 +13,6 @@ App::App() InitGLFW(); InitRootOverlay(); printf("\n"); - _controllers[0] = Controller(this, ControllerSide::Left); - _controllers[1] = Controller(this, ControllerSide::Right); glGenTextures(1, &_gl_frame); glBindTexture(GL_TEXTURE_2D, _gl_frame); @@ -125,18 +122,19 @@ void App::InitRootOverlay() // clang-format on _root_overlay.SetTransformWorld(&root_start_pose); - _root_overlay._GrabBeginCallback = [this](Controller *controller) { + _root_overlay._GrabBeginCallback = [this](TrackerID controller) { for (auto &panel : _panels) { panel.GetOverlay()->ControllerGrab(controller); } }; - _root_overlay._GrabEndCallback = [this]() { + _root_overlay._GrabEndCallback = [this](TrackerID controller) { for (auto &panel : _panels) { panel.GetOverlay()->ControllerRelease(); } }; + printf("Created root overlay instance\n"); } void App::Update() @@ -158,26 +156,44 @@ void App::UpdateInput() vr::VRActiveActionSet_t main; main.ulActionSet = _input_handles.set; main.ulRestrictedToDevice = 0; - main.nPriority = 10; - vr::EVRInputError err = vr_input->UpdateActionState(&main, sizeof(vr::VRActiveActionSet_t), 1); - if (err) - { - printf("Error: (update action state): %d\n", err); - } + vr_input->UpdateActionState(&main, sizeof(vr::VRActiveActionSet_t), 1); vr_sys->GetDeviceToAbsoluteTrackingPose(_tracking_origin, 0, _tracker_poses, MAX_TRACKERS); - if (IsInputJustPressed(_input_handles.toggle)) + for (unsigned int i = 0; i < MAX_TRACKERS; i++) { - _hidden = !_hidden; - _root_overlay.SetHidden(_hidden); - for (auto &panel : _panels) + if (IsInputJustPressed(i, _input_handles.toggle)) { - panel.SetHidden(_hidden); + _hidden = !_hidden; + _root_overlay.SetHidden(_hidden); + for (auto &panel : _panels) + { + panel.SetHidden(_hidden); + } + for (auto &laser : _lasers) + { + if (laser.has_value()) + { + laser->SetHidden(_hidden); + } + } + break; + } + auto type = vr_sys->GetTrackedDeviceClass(i); + if (type == vr::TrackedDeviceClass_Controller) + { + if (!_lasers[i].has_value()) + { + _lasers[i] = Laser(this, i); + } + _lasers[i]->SetHidden(_hidden); + _lasers[i]->Update(); + } + else if (_lasers[i].has_value()) + { + _lasers[i]->SetHidden(true); } } - _controllers[0]->Update(); - _controllers[1]->Update(); } void App::UpdateFramebuffer() @@ -207,23 +223,23 @@ glm::mat4 App::GetTrackerPose(TrackerID tracker) return ConvertMat(_tracker_poses[tracker].mDeviceToAbsoluteTracking); } -vr::InputDigitalActionData_t App::GetInputDigital(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) +vr::InputDigitalActionData_t App::GetControllerInputDigital(TrackerID controller, vr::VRActionHandle_t action) { vr::InputDigitalActionData_t state; - vr_input->GetDigitalActionData(action, &state, sizeof(vr::InputDigitalActionData_t), controller); + vr_input->GetDigitalActionData(action, &state, sizeof(vr::InputDigitalActionData_t), 0); return state; } -vr::InputAnalogActionData_t App::GetInputAnalog(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) +vr::InputAnalogActionData_t App::GetControllerInputAnalog(TrackerID controller, vr::VRActionHandle_t action) { vr::InputAnalogActionData_t state; - vr_input->GetAnalogActionData(action, &state, sizeof(vr::InputAnalogActionData_t), controller); + vr_input->GetAnalogActionData(action, &state, sizeof(vr::InputAnalogActionData_t), 0); return state; } -bool App::IsInputJustPressed(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) +bool App::IsInputJustPressed(TrackerID controller, vr::VRActionHandle_t action) { - auto data = GetInputDigital(action, controller); + auto data = GetControllerInputDigital(controller, action); return data.bState && data.bChanged; } diff --git a/src/app.h b/src/app.h index 9665051..7246d14 100644 --- a/src/app.h +++ b/src/app.h @@ -1,7 +1,7 @@ #pragma once #define GL_GLEXT_PROTOTYPES -#include "controller.h" +#include "laser.h" #include "overlay.h" #include "panel.h" #include "util.h" @@ -39,9 +39,9 @@ class App std::vector GetControllers(); glm::mat4 GetTrackerPose(TrackerID tracker); - vr::InputDigitalActionData_t GetInputDigital(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller = 0); - vr::InputAnalogActionData_t GetInputAnalog(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller = 0); - bool IsInputJustPressed(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller = 0); + vr::InputDigitalActionData_t GetControllerInputDigital(TrackerID controller, vr::VRActionHandle_t action); + vr::InputAnalogActionData_t GetControllerInputAnalog(TrackerID controller, vr::VRActionHandle_t action); + bool IsInputJustPressed(TrackerID controller, vr::VRActionHandle_t action); CursorPos GetCursorPosition(); Ray IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len); @@ -63,7 +63,7 @@ class App InputHandles _input_handles; vr::TrackedDevicePose_t _tracker_poses[MAX_TRACKERS]; - std::optional _controllers[2]; + std::optional _lasers[MAX_TRACKERS]; Overlay _root_overlay; std::vector _panels; diff --git a/src/controller.cpp b/src/controller.cpp deleted file mode 100644 index 3a6d14c..0000000 --- a/src/controller.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "controller.h" -#include "app.h" -#include "overlay.h" -#include "util.h" -#include - -const float width = 0.004f; - -Controller::Controller(App *app, ControllerSide side) -{ - _app = app; - _input_handle = 0; - _is_connected = false; - _side = side; - - std::string laser_name = "controller_laser_"; - if (side == ControllerSide::Left) - laser_name += "left"; - else if (side == ControllerSide::Right) - laser_name += "right"; - - _laser = Overlay(app, laser_name); - UpdateStatus(); - _laser.SetTextureToColor(255, 200, 255); - _laser.SetAlpha(0.2f); -} - -TrackerID Controller::DeviceIndex() -{ - return _device_index; -} - -vr::VRInputValueHandle_t Controller::InputHandle() -{ - return _input_handle; -} - -ControllerSide Controller::Side() -{ - return _side; -} - -bool Controller::IsConnected() -{ - return _is_connected; -} - -void Controller::Update() -{ - UpdateStatus(); - if (!_is_connected) - return; - - auto controller_pose = _app->GetTrackerPose(_device_index); - auto controller_pos = GetPos(controller_pose); - auto forward = -glm::vec3(controller_pose[2]); - auto ray = _app->IntersectRay(controller_pos, forward, 5.0f); - float len = ray.distance; - - auto hmd_global_pos = GetPos(_app->GetTrackerPose(0)); - auto hmd_local_pos = glm::inverse(controller_pose) * glm::vec4(hmd_global_pos - controller_pos, 0); - hmd_local_pos.z = 0; - auto hmd_dir = glm::normalize(hmd_local_pos); - - VRMat transform = {{{width * hmd_dir.y, 0, width * hmd_dir.x, 0}, {width * -hmd_dir.x, 0, width * hmd_dir.y, 0}, {0, len, 0, len * -0.5f}}}; - _laser.SetTransformTracker(_device_index, &transform); - - if (ray.overlay != nullptr) - { - if (_app->IsInputJustPressed(_app->_input_handles.grab, _input_handle)) - { - ray.overlay->ControllerGrab(this); - } - } -} - -void Controller::UpdateStatus() -{ - _is_connected = true; - - if (_side == ControllerSide::Left) - { - auto err = _app->vr_input->GetInputSourceHandle("/user/hand/left", &_input_handle); - _is_connected &= (err == 0); - _device_index = _app->vr_sys->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - } - else if (_side == ControllerSide::Right) - { - auto err = _app->vr_input->GetInputSourceHandle("/user/hand/right", &_input_handle); - _is_connected &= (err == 0); - _device_index = _app->vr_sys->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - } - _is_connected &= _device_index < MAX_TRACKERS; - _laser.SetHidden(!_is_connected); -} diff --git a/src/controller.h b/src/controller.h deleted file mode 100644 index 2e20983..0000000 --- a/src/controller.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "overlay.h" -#include "util.h" - -class App; - -enum class ControllerSide -{ - Left, - Right -}; - -class Controller -{ - public: - Controller(App *app, ControllerSide hand); - TrackerID DeviceIndex(); - vr::VRInputValueHandle_t InputHandle(); - ControllerSide Side(); - - bool IsConnected(); - - void Update(); - void UpdateStatus(); - - private: - App *_app; - Overlay _laser; - ControllerSide _side; - TrackerID _device_index; - vr::VRInputValueHandle_t _input_handle; - bool _is_connected; -}; diff --git a/src/laser.cpp b/src/laser.cpp new file mode 100644 index 0000000..ef466bd --- /dev/null +++ b/src/laser.cpp @@ -0,0 +1,45 @@ +#include "laser.h" +#include "app.h" +#include "util.h" +#include + +Laser::Laser(App *app, TrackerID index) + : _overlay(app, "laser_" + std::to_string(index)), + _app(app), + _controller(index) +{ + _overlay.SetHidden(true); + _overlay.SetTransformTracker(index, &VRMatIdentity); + _overlay.SetTextureToColor(255, 200, 255); + _overlay.SetAlpha(0.2f); +} + +void Laser::Update() +{ + if (_overlay.IsHidden()) + { + return; + } + const float width = 0.004f; + auto controller_pose = _app->GetTrackerPose(_controller); + auto origin = GetPos(controller_pose); + auto forward = -glm::vec3(controller_pose[2]); + auto ray = _app->IntersectRay(origin, forward, 5.0f); + float len = ray.distance; + + VRMat transform = {{{width, 0, 0, 0}, {0, 0, width, 0}, {0, len, 0, len * -0.5f}}}; + _overlay.SetTransformTracker(_controller, &transform); + + if (ray.overlay != nullptr) + { + if (_app->IsInputJustPressed(_controller, _app->_input_handles.grab)) + { + ray.overlay->ControllerGrab(_controller); + } + } +} + +void Laser::SetHidden(bool state) +{ + _overlay.SetHidden(state); +} \ No newline at end of file diff --git a/src/laser.h b/src/laser.h new file mode 100644 index 0000000..6e97b09 --- /dev/null +++ b/src/laser.h @@ -0,0 +1,20 @@ +#pragma once + +#include "overlay.h" +#include "util.h" + +class App; + +class Laser +{ + public: + Laser(App *app, TrackerID index); + + void Update(); + void SetHidden(bool state); + + private: + App *_app; + Overlay _overlay; + TrackerID _controller; +}; diff --git a/src/overlay.cpp b/src/overlay.cpp index 64022a9..3e61c4c 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -14,7 +14,8 @@ Overlay::Overlay(App *app, std::string name) _initialized = true; _name = name; _app = app; - _holding_controller = nullptr; + _is_held = false; + _active_hand = 0; _width_m = 1; _ratio = 1; @@ -45,12 +46,12 @@ OverlayID Overlay::Id() bool Overlay::IsHeld() { - return _holding_controller != nullptr; + return _is_held; } -Controller *Overlay::ActiveHand() +TrackerID Overlay::ActiveHand() { - return _holding_controller; + return _active_hand; } bool Overlay::IsHidden() @@ -167,14 +168,13 @@ float Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len glm::mat4x4 Overlay::GetTransformAbsolute() { - if (_holding_controller != nullptr) + if (_is_held) { VRMat pose; - TrackerID tracker; - auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &tracker, &pose); + auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_active_hand, &pose); assert(err == 0); auto offset = ConvertMat(pose); - auto controller = _app->GetTrackerPose(_holding_controller->DeviceIndex()); + auto controller = _app->GetTrackerPose(_active_hand); return controller * offset; } else @@ -206,31 +206,32 @@ void Overlay::Update() assert(_initialized); } - if (_holding_controller != nullptr) + if (_is_held) { - if (!_app->GetInputDigital(_app->_input_handles.grab, _holding_controller->InputHandle()).bState) + if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState) { ControllerRelease(); } } } -void Overlay::ControllerGrab(Controller *controller) +void Overlay::ControllerGrab(TrackerID controller) { _app->vr_overlay->SetOverlayColor(_id, 0.6f, 0.8f, 0.8f); auto abs_mat = GetTransformAbsolute(); - auto controller_mat = _app->GetTrackerPose(controller->DeviceIndex()); + auto controller_mat = _app->GetTrackerPose(controller); VRMat relative_pose = ConvertMat(glm::inverse(controller_mat) * abs_mat); - _app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller->DeviceIndex(), &relative_pose); + _app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller, &relative_pose); if (_GrabBeginCallback != nullptr) { _GrabBeginCallback(controller); } - _holding_controller = controller; + _is_held = true; + _active_hand = controller; } void Overlay::ControllerRelease() @@ -242,7 +243,8 @@ void Overlay::ControllerRelease() if (_GrabEndCallback != nullptr) { - _GrabEndCallback(); + _GrabEndCallback(_active_hand); } - _holding_controller = nullptr; + _is_held = false; + _active_hand = -1; } diff --git a/src/overlay.h b/src/overlay.h index 8cbc9e0..24879bf 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -5,7 +5,6 @@ #include class App; -class Controller; enum class TargetType { @@ -30,7 +29,7 @@ class Overlay OverlayID Id(); bool IsHeld(); bool IsHidden(); - Controller *ActiveHand(); + TrackerID ActiveHand(); float Alpha(); float Width(); float Ratio(); @@ -52,11 +51,11 @@ class Overlay float IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len); - std::function _GrabBeginCallback; - std::function _GrabEndCallback; + std::function _GrabBeginCallback; + std::function _GrabEndCallback; void ControllerRelease(); - void ControllerGrab(Controller *controller); + void ControllerGrab(TrackerID controller); private: bool _initialized; @@ -65,11 +64,12 @@ class Overlay OverlayID _id; std::string _name; + bool _is_held; bool _hidden; float _width_m; float _alpha; float _ratio; - Controller *_holding_controller; + TrackerID _active_hand; Target _target; }; \ No newline at end of file diff --git a/src/util.h b/src/util.h index bd29e39..4cac8c8 100644 --- a/src/util.h +++ b/src/util.h @@ -10,11 +10,6 @@ typedef vr::HmdMatrix34_t VRMat; const VRMat VRMatIdentity{{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}}}; const int MAX_TRACKERS = vr::k_unMaxTrackedDeviceCount; -inline void PrintVec(glm::vec3 v) -{ - printf("(%.2f, %.2f, %.2f)\n", v.x, v.y, v.z); -} - inline void PrintMat(VRMat m) { printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[0][0], m.m[0][1], m.m[0][2], m.m[0][3]);