mirror of
https://github.com/CrispyPin/sinpin-vr.git
synced 2024-11-23 02:20:26 +01:00
resize overlays when grabbed with both controllers
This commit is contained in:
parent
286c1d08a7
commit
533bf45087
7 changed files with 120 additions and 41 deletions
|
@ -1,4 +1,4 @@
|
||||||
# ovr-screen
|
# sinpin-vr
|
||||||
A SteamVR overlay for Linux+X11 that displays all your screens in VR.
|
A SteamVR overlay for Linux+X11 that displays all your screens in VR.
|
||||||
|
|
||||||
From my limited testing, this uses about half the CPU performance of Steam's built-in desktop overlay, if running at 60 FPS. Currently the default is 30 FPS which brings the factor to 3-4x. On my machine, the Steam desktop view increases cpu usage by about 100% of a CPU thread (looking only at the `steam` process), while this overlay uses around 25% at 30 FPS and 45% at 60 FPS.
|
From my limited testing, this uses about half the CPU performance of Steam's built-in desktop overlay, if running at 60 FPS. Currently the default is 30 FPS which brings the factor to 3-4x. On my machine, the Steam desktop view increases cpu usage by about 100% of a CPU thread (looking only at the `steam` process), while this overlay uses around 25% at 30 FPS and 45% at 60 FPS.
|
||||||
|
|
|
@ -24,12 +24,6 @@ struct InputHandles
|
||||||
vr::VRActionHandle_t grab;
|
vr::VRActionHandle_t grab;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ray
|
|
||||||
{
|
|
||||||
Overlay *overlay;
|
|
||||||
float distance;
|
|
||||||
};
|
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -57,6 +57,21 @@ void Controller::ReleaseOverlay()
|
||||||
_grabbed_overlay = nullptr;
|
_grabbed_overlay = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ray Controller::GetLastRay()
|
||||||
|
{
|
||||||
|
return _last_ray;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Controller::GetLastPos()
|
||||||
|
{
|
||||||
|
return _last_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Controller::GetLastRot()
|
||||||
|
{
|
||||||
|
return _last_rotation;
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::Update()
|
void Controller::Update()
|
||||||
{
|
{
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
|
@ -82,6 +97,10 @@ void Controller::UpdateLaser()
|
||||||
auto ray = _app->IntersectRay(controller_pos, forward, 5.0f);
|
auto ray = _app->IntersectRay(controller_pos, forward, 5.0f);
|
||||||
float len = ray.distance;
|
float len = ray.distance;
|
||||||
|
|
||||||
|
_last_pos = controller_pos;
|
||||||
|
_last_rotation = forward;
|
||||||
|
_last_ray = ray;
|
||||||
|
|
||||||
auto hmd_global_pos = GetPos(_app->GetTrackerPose(0));
|
auto hmd_global_pos = GetPos(_app->GetTrackerPose(0));
|
||||||
auto hmd_local_pos = glm::inverse(controller_pose) * glm::vec4(hmd_global_pos - controller_pos, 0);
|
auto hmd_local_pos = glm::inverse(controller_pose) * glm::vec4(hmd_global_pos - controller_pos, 0);
|
||||||
hmd_local_pos.z = 0;
|
hmd_local_pos.z = 0;
|
||||||
|
@ -96,7 +115,7 @@ void Controller::UpdateLaser()
|
||||||
{
|
{
|
||||||
if (ray.overlay->IsHeld())
|
if (ray.overlay->IsHeld())
|
||||||
{
|
{
|
||||||
// TODO resize mode
|
ray.overlay->ControllerResize(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,9 @@ class Controller
|
||||||
ControllerSide Side();
|
ControllerSide Side();
|
||||||
|
|
||||||
bool IsConnected();
|
bool IsConnected();
|
||||||
|
Ray GetLastRay();
|
||||||
|
glm::vec3 GetLastPos();
|
||||||
|
glm::vec3 GetLastRot();
|
||||||
|
|
||||||
void SetHidden(bool state);
|
void SetHidden(bool state);
|
||||||
|
|
||||||
|
@ -39,4 +42,7 @@ class Controller
|
||||||
bool _is_connected;
|
bool _is_connected;
|
||||||
bool _hidden;
|
bool _hidden;
|
||||||
Overlay *_grabbed_overlay;
|
Overlay *_grabbed_overlay;
|
||||||
|
Ray _last_ray;
|
||||||
|
glm::vec3 _last_rotation;
|
||||||
|
glm::vec3 _last_pos;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@ Overlay::Overlay(App *app, std::string name)
|
||||||
_name = name;
|
_name = name;
|
||||||
_app = app;
|
_app = app;
|
||||||
_holding_controller = nullptr;
|
_holding_controller = nullptr;
|
||||||
|
_resize_controller = nullptr;
|
||||||
_width_m = 1;
|
_width_m = 1;
|
||||||
_ratio = 1;
|
_ratio = 1;
|
||||||
_hidden = false;
|
_hidden = false;
|
||||||
|
@ -149,7 +150,7 @@ void Overlay::SetTargetWorld()
|
||||||
|
|
||||||
Ray Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len)
|
Ray Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len)
|
||||||
{
|
{
|
||||||
float closest_dist = max_len;
|
float dist = max_len;
|
||||||
auto end = origin + direction * max_len;
|
auto end = origin + direction * max_len;
|
||||||
|
|
||||||
auto panel_transform = GetTransformAbsolute();
|
auto panel_transform = GetTransformAbsolute();
|
||||||
|
@ -166,46 +167,30 @@ Ray Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len)
|
||||||
|
|
||||||
if (b.z < a.z && b.z < 0 && glm::abs(p.x) < (_width_m * 0.5f) && glm::abs(p.y) < (_width_m * 0.5f * _ratio))
|
if (b.z < a.z && b.z < 0 && glm::abs(p.x) < (_width_m * 0.5f) && glm::abs(p.y) < (_width_m * 0.5f * _ratio))
|
||||||
{
|
{
|
||||||
float dist = r * max_len;
|
dist = glm::min(r * max_len, max_len);
|
||||||
if (dist < closest_dist)
|
|
||||||
{
|
|
||||||
closest_dist = dist;
|
|
||||||
}
|
}
|
||||||
}
|
return Ray{.overlay = this, .distance = dist};
|
||||||
return Ray{.overlay = this, .distance = closest_dist};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4x4 Overlay::GetTransformAbsolute()
|
glm::mat4x4 Overlay::GetTransformAbsolute()
|
||||||
{
|
{
|
||||||
if (_holding_controller != nullptr)
|
if (_target.type == TargetType::World)
|
||||||
{
|
{
|
||||||
VRMat pose;
|
|
||||||
TrackerID tracker;
|
|
||||||
auto err = _app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &tracker, &pose);
|
|
||||||
assert(err == 0);
|
|
||||||
auto offset = ConvertMat(pose);
|
|
||||||
auto controller = _app->GetTrackerPose(_holding_controller->DeviceIndex());
|
|
||||||
return controller * offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (_target.type)
|
|
||||||
{
|
|
||||||
case TargetType::World: {
|
|
||||||
VRMat pose;
|
VRMat pose;
|
||||||
vr::ETrackingUniverseOrigin tracking_universe;
|
vr::ETrackingUniverseOrigin tracking_universe;
|
||||||
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &tracking_universe, &pose);
|
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &tracking_universe, &pose);
|
||||||
return ConvertMat(pose);
|
return ConvertMat(pose);
|
||||||
}
|
}
|
||||||
case TargetType::Tracker: {
|
if (_target.type == TargetType::Tracker)
|
||||||
|
{
|
||||||
VRMat pose;
|
VRMat pose;
|
||||||
_app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_target.id, &pose);
|
_app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_target.id, &pose);
|
||||||
auto offset = ConvertMat(pose);
|
auto offset = ConvertMat(pose);
|
||||||
auto tracker_pose = _app->GetTrackerPose(_target.id);
|
auto tracker_pose = _app->GetTrackerPose(_target.id);
|
||||||
return tracker_pose * offset;
|
return tracker_pose * offset;
|
||||||
}
|
}
|
||||||
}
|
printf("Error: overlay '%s' not set to a valid target", _name.c_str());
|
||||||
}
|
return ConvertMat(VRMatIdentity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Target *Overlay::GetTarget()
|
Target *Overlay::GetTarget()
|
||||||
|
@ -223,7 +208,41 @@ void Overlay::Update()
|
||||||
|
|
||||||
if (_holding_controller != nullptr)
|
if (_holding_controller != nullptr)
|
||||||
{
|
{
|
||||||
if (!_app->GetInputDigital(_app->_input_handles.grab, _holding_controller->InputHandle()).bState)
|
bool hold_controller_holding = _app->GetInputDigital(_app->_input_handles.grab, _holding_controller->InputHandle()).bState;
|
||||||
|
if (_resize_controller != nullptr)
|
||||||
|
{
|
||||||
|
bool resize_controller_holding = _app->GetInputDigital(_app->_input_handles.grab, _resize_controller->InputHandle()).bState;
|
||||||
|
if (!resize_controller_holding)
|
||||||
|
{
|
||||||
|
_resize_controller = nullptr;
|
||||||
|
}
|
||||||
|
else if (!hold_controller_holding)
|
||||||
|
{
|
||||||
|
_resize_controller = nullptr;
|
||||||
|
ControllerRelease();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pos_a = _holding_controller->GetLastPos() + _holding_controller->GetLastRot() * _resize_length_a;
|
||||||
|
auto pos_b = _resize_controller->GetLastPos() + _resize_controller->GetLastRot() * _resize_length_b;
|
||||||
|
|
||||||
|
float distance = glm::length(pos_a - pos_b);
|
||||||
|
float factor = (distance / _resize_base_distance);
|
||||||
|
float min_factor = 0.1f / _resize_original_size;
|
||||||
|
float max_factor = 5.0f / _resize_original_size;
|
||||||
|
factor = glm::clamp(factor, min_factor, max_factor);
|
||||||
|
float new_size = _resize_original_size * factor;
|
||||||
|
|
||||||
|
SetWidth(new_size);
|
||||||
|
|
||||||
|
auto transform = _target.transform;
|
||||||
|
auto pos = _resize_held_offset * factor;
|
||||||
|
transform.m[0][3] = pos.x;
|
||||||
|
transform.m[1][3] = pos.y;
|
||||||
|
SetTransformTracker(_holding_controller->DeviceIndex(), &transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!hold_controller_holding)
|
||||||
{
|
{
|
||||||
ControllerRelease();
|
ControllerRelease();
|
||||||
}
|
}
|
||||||
|
@ -264,6 +283,33 @@ void Overlay::ControllerRelease()
|
||||||
_holding_controller = nullptr;
|
_holding_controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Overlay::ControllerResize(Controller *controller)
|
||||||
|
{
|
||||||
|
if (_resize_controller || controller == _holding_controller)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (auto child : _children)
|
||||||
|
{
|
||||||
|
if (!child->IsHeld())
|
||||||
|
{
|
||||||
|
child->SetTargetWorld();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_resize_controller = controller;
|
||||||
|
_resize_original_size = _width_m;
|
||||||
|
|
||||||
|
_resize_length_a = _holding_controller->GetLastRay().distance;
|
||||||
|
_resize_length_b = _resize_controller->GetLastRay().distance;
|
||||||
|
|
||||||
|
auto pos_a = _holding_controller->GetLastPos() + _holding_controller->GetLastRot() * _resize_length_a;
|
||||||
|
auto pos_b = _resize_controller->GetLastPos() + _resize_controller->GetLastRot() * _resize_length_b;
|
||||||
|
|
||||||
|
// distance between laser points
|
||||||
|
_resize_base_distance = glm::length(pos_a - pos_b);
|
||||||
|
_resize_held_offset = GetPos(_target.transform);
|
||||||
|
}
|
||||||
|
|
||||||
void Overlay::AddChildOverlay(Overlay *overlay)
|
void Overlay::AddChildOverlay(Overlay *overlay)
|
||||||
{
|
{
|
||||||
_children.push_back(overlay);
|
_children.push_back(overlay);
|
||||||
|
|
|
@ -55,8 +55,9 @@ class Overlay
|
||||||
|
|
||||||
Ray IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len);
|
Ray IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len);
|
||||||
|
|
||||||
void ControllerRelease();
|
|
||||||
void ControllerGrab(Controller *controller);
|
void ControllerGrab(Controller *controller);
|
||||||
|
void ControllerRelease();
|
||||||
|
void ControllerResize(Controller *controller);
|
||||||
|
|
||||||
void AddChildOverlay(Overlay *child);
|
void AddChildOverlay(Overlay *child);
|
||||||
void RemoveChildOverlay(Overlay *child);
|
void RemoveChildOverlay(Overlay *child);
|
||||||
|
@ -73,6 +74,12 @@ class Overlay
|
||||||
float _alpha;
|
float _alpha;
|
||||||
float _ratio;
|
float _ratio;
|
||||||
Controller *_holding_controller;
|
Controller *_holding_controller;
|
||||||
|
Controller *_resize_controller;
|
||||||
|
float _resize_original_size;
|
||||||
|
float _resize_base_distance;
|
||||||
|
float _resize_length_a;
|
||||||
|
float _resize_length_b;
|
||||||
|
glm::vec3 _resize_held_offset;
|
||||||
|
|
||||||
std::vector<Overlay *> _children;
|
std::vector<Overlay *> _children;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,13 @@ typedef vr::HmdMatrix34_t VRMat;
|
||||||
const VRMat VRMatIdentity{{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}}};
|
const VRMat VRMatIdentity{{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}}};
|
||||||
const int MAX_TRACKERS = vr::k_unMaxTrackedDeviceCount;
|
const int MAX_TRACKERS = vr::k_unMaxTrackedDeviceCount;
|
||||||
|
|
||||||
|
class Overlay;
|
||||||
|
struct Ray
|
||||||
|
{
|
||||||
|
Overlay *overlay;
|
||||||
|
float distance;
|
||||||
|
};
|
||||||
|
|
||||||
inline void PrintVec(glm::vec3 v)
|
inline void PrintVec(glm::vec3 v)
|
||||||
{
|
{
|
||||||
printf("(%.2f, %.2f, %.2f)\n", v.x, v.y, v.z);
|
printf("(%.2f, %.2f, %.2f)\n", v.x, v.y, v.z);
|
||||||
|
|
Loading…
Reference in a new issue