diff --git a/src/app.cpp b/src/app.cpp index 222f888..6cb55da 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,4 +1,5 @@ #include "app.h" +#include "controller.h" #include "util.h" #include #include @@ -13,6 +14,8 @@ 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); @@ -122,13 +125,13 @@ void App::InitRootOverlay() // clang-format on _root_overlay.SetTransformWorld(&root_start_pose); - _root_overlay._GrabBeginCallback = [this](TrackerID controller) { + _root_overlay._GrabBeginCallback = [this](Controller *controller) { for (auto &panel : _panels) { panel.GetOverlay()->ControllerGrab(controller); } }; - _root_overlay._GrabEndCallback = [this](TrackerID controller) { + _root_overlay._GrabEndCallback = [this]() { for (auto &panel : _panels) { panel.GetOverlay()->ControllerRelease(); @@ -156,44 +159,26 @@ void App::UpdateInput() vr::VRActiveActionSet_t main; main.ulActionSet = _input_handles.set; main.ulRestrictedToDevice = 0; - vr_input->UpdateActionState(&main, sizeof(vr::VRActiveActionSet_t), 1); + 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_sys->GetDeviceToAbsoluteTrackingPose(_tracking_origin, 0, _tracker_poses, MAX_TRACKERS); - for (unsigned int i = 0; i < MAX_TRACKERS; i++) + if (IsInputJustPressed(_input_handles.toggle)) { - if (IsInputJustPressed(i, _input_handles.toggle)) + _hidden = !_hidden; + _root_overlay.SetHidden(_hidden); + for (auto &panel : _panels) { - _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); + panel.SetHidden(_hidden); } } + _controllers[0]->Update(); + _controllers[1]->Update(); } void App::UpdateFramebuffer() @@ -223,23 +208,23 @@ glm::mat4 App::GetTrackerPose(TrackerID tracker) return ConvertMat(_tracker_poses[tracker].mDeviceToAbsoluteTracking); } -vr::InputDigitalActionData_t App::GetControllerInputDigital(TrackerID controller, vr::VRActionHandle_t action) +vr::InputDigitalActionData_t App::GetInputDigital(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) { vr::InputDigitalActionData_t state; - vr_input->GetDigitalActionData(action, &state, sizeof(vr::InputDigitalActionData_t), 0); + vr_input->GetDigitalActionData(action, &state, sizeof(vr::InputDigitalActionData_t), controller); return state; } -vr::InputAnalogActionData_t App::GetControllerInputAnalog(TrackerID controller, vr::VRActionHandle_t action) +vr::InputAnalogActionData_t App::GetInputAnalog(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) { vr::InputAnalogActionData_t state; - vr_input->GetAnalogActionData(action, &state, sizeof(vr::InputAnalogActionData_t), 0); + vr_input->GetAnalogActionData(action, &state, sizeof(vr::InputAnalogActionData_t), controller); return state; } -bool App::IsInputJustPressed(TrackerID controller, vr::VRActionHandle_t action) +bool App::IsInputJustPressed(vr::VRActionHandle_t action, vr::VRInputValueHandle_t controller) { - auto data = GetControllerInputDigital(controller, action); + auto data = GetInputDigital(action, controller); return data.bState && data.bChanged; } diff --git a/src/app.h b/src/app.h index 7246d14..9665051 100644 --- a/src/app.h +++ b/src/app.h @@ -1,7 +1,7 @@ #pragma once #define GL_GLEXT_PROTOTYPES -#include "laser.h" +#include "controller.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 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); + 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); 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 _lasers[MAX_TRACKERS]; + std::optional _controllers[2]; Overlay _root_overlay; std::vector _panels; diff --git a/src/controller.cpp b/src/controller.cpp new file mode 100644 index 0000000..8928517 --- /dev/null +++ b/src/controller.cpp @@ -0,0 +1,90 @@ +#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 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}}}; + _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 new file mode 100644 index 0000000..2e20983 --- /dev/null +++ b/src/controller.h @@ -0,0 +1,33 @@ +#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 deleted file mode 100644 index ef466bd..0000000 --- a/src/laser.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index 6e97b09..0000000 --- a/src/laser.h +++ /dev/null @@ -1,20 +0,0 @@ -#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 3e61c4c..64022a9 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -14,8 +14,7 @@ Overlay::Overlay(App *app, std::string name) _initialized = true; _name = name; _app = app; - _is_held = false; - _active_hand = 0; + _holding_controller = nullptr; _width_m = 1; _ratio = 1; @@ -46,12 +45,12 @@ OverlayID Overlay::Id() bool Overlay::IsHeld() { - return _is_held; + return _holding_controller != nullptr; } -TrackerID Overlay::ActiveHand() +Controller *Overlay::ActiveHand() { - return _active_hand; + return _holding_controller; } bool Overlay::IsHidden() @@ -168,13 +167,14 @@ float Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len glm::mat4x4 Overlay::GetTransformAbsolute() { - if (_is_held) + if (_holding_controller != nullptr) { VRMat pose; - auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_active_hand, &pose); + TrackerID tracker; + auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &tracker, &pose); assert(err == 0); auto offset = ConvertMat(pose); - auto controller = _app->GetTrackerPose(_active_hand); + auto controller = _app->GetTrackerPose(_holding_controller->DeviceIndex()); return controller * offset; } else @@ -206,32 +206,31 @@ void Overlay::Update() assert(_initialized); } - if (_is_held) + if (_holding_controller != nullptr) { - if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState) + if (!_app->GetInputDigital(_app->_input_handles.grab, _holding_controller->InputHandle()).bState) { ControllerRelease(); } } } -void Overlay::ControllerGrab(TrackerID controller) +void Overlay::ControllerGrab(Controller *controller) { _app->vr_overlay->SetOverlayColor(_id, 0.6f, 0.8f, 0.8f); auto abs_mat = GetTransformAbsolute(); - auto controller_mat = _app->GetTrackerPose(controller); + auto controller_mat = _app->GetTrackerPose(controller->DeviceIndex()); VRMat relative_pose = ConvertMat(glm::inverse(controller_mat) * abs_mat); - _app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller, &relative_pose); + _app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller->DeviceIndex(), &relative_pose); if (_GrabBeginCallback != nullptr) { _GrabBeginCallback(controller); } - _is_held = true; - _active_hand = controller; + _holding_controller = controller; } void Overlay::ControllerRelease() @@ -243,8 +242,7 @@ void Overlay::ControllerRelease() if (_GrabEndCallback != nullptr) { - _GrabEndCallback(_active_hand); + _GrabEndCallback(); } - _is_held = false; - _active_hand = -1; + _holding_controller = nullptr; } diff --git a/src/overlay.h b/src/overlay.h index 24879bf..8cbc9e0 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -5,6 +5,7 @@ #include class App; +class Controller; enum class TargetType { @@ -29,7 +30,7 @@ class Overlay OverlayID Id(); bool IsHeld(); bool IsHidden(); - TrackerID ActiveHand(); + Controller *ActiveHand(); float Alpha(); float Width(); float Ratio(); @@ -51,11 +52,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(TrackerID controller); + void ControllerGrab(Controller *controller); private: bool _initialized; @@ -64,12 +65,11 @@ class Overlay OverlayID _id; std::string _name; - bool _is_held; bool _hidden; float _width_m; float _alpha; float _ratio; - TrackerID _active_hand; + Controller *_holding_controller; Target _target; }; \ No newline at end of file