2023-04-07 01:10:11 +02:00
|
|
|
#include "panel.h"
|
|
|
|
#include "app.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
#include <X11/Xutil.h>
|
2023-04-07 22:40:18 +02:00
|
|
|
#include <glm/common.hpp>
|
2023-04-07 01:10:11 +02:00
|
|
|
#include <glm/glm.hpp>
|
|
|
|
|
2023-04-07 20:32:52 +02:00
|
|
|
Panel::Panel(App *app, vr::HmdMatrix34_t start_pose, int index, int x, int y, int width, int height)
|
2023-04-07 01:10:11 +02:00
|
|
|
: _app(app),
|
|
|
|
_index(index),
|
|
|
|
_x(x),
|
|
|
|
_y(y),
|
|
|
|
_width(width),
|
|
|
|
_height(height)
|
|
|
|
{
|
|
|
|
_name = "screen_view_" + std::to_string(index);
|
|
|
|
_alpha = 1.0f;
|
2023-04-07 20:49:09 +02:00
|
|
|
_meters = 1.0f;
|
2023-04-07 01:10:11 +02:00
|
|
|
_active_hand = -1;
|
|
|
|
glGenTextures(1, &_gl_texture);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, _gl_texture);
|
2023-04-07 19:13:52 +02:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexImage2D(
|
|
|
|
GL_TEXTURE_2D, 0, GL_RGB,
|
|
|
|
_width, _height, 0,
|
|
|
|
GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
2023-04-07 01:10:11 +02:00
|
|
|
|
2023-04-07 13:26:42 +02:00
|
|
|
_texture.eColorSpace = vr::ColorSpace_Auto;
|
|
|
|
_texture.eType = vr::TextureType_OpenGL;
|
2023-04-07 01:10:11 +02:00
|
|
|
_texture.handle = (void *)(uintptr_t)_gl_texture;
|
|
|
|
|
|
|
|
// create overlay
|
|
|
|
{
|
|
|
|
auto overlay_create_err = _app->vr_overlay->CreateOverlay(_name.c_str(), _name.c_str(), &_id);
|
|
|
|
assert(overlay_create_err == 0);
|
|
|
|
_app->vr_overlay->ShowOverlay(_id);
|
|
|
|
uint8_t col[4] = {20, 50, 50, 255};
|
|
|
|
_app->vr_overlay->SetOverlayRaw(_id, &col, 1, 1, 4);
|
|
|
|
printf("Created overlay instance %d\n", _index);
|
|
|
|
|
|
|
|
// (flipping uv on y axis because opengl and xorg are opposite)
|
|
|
|
vr::VRTextureBounds_t bounds{0, 1, 1, 0};
|
|
|
|
_app->vr_overlay->SetOverlayTextureBounds(_id, &bounds);
|
2023-04-07 19:13:52 +02:00
|
|
|
_app->vr_overlay->SetOverlayTransformAbsolute(_id, _app->_tracking_origin, &start_pose);
|
2023-04-07 01:10:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Panel::Update()
|
|
|
|
{
|
|
|
|
Render();
|
|
|
|
UpdateCursor();
|
|
|
|
|
|
|
|
if (!_is_held)
|
|
|
|
{
|
2023-04-07 13:26:42 +02:00
|
|
|
for (auto controller : _app->GetControllers())
|
2023-04-07 01:10:11 +02:00
|
|
|
{
|
2023-04-11 18:03:03 +02:00
|
|
|
if (_app->IsInputJustPressed(controller, _app->_input_handles.grab))
|
2023-04-07 20:49:09 +02:00
|
|
|
{
|
|
|
|
vr::HmdMatrix34_t overlay_pose;
|
|
|
|
vr::ETrackingUniverseOrigin tracking_universe;
|
|
|
|
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &tracking_universe, &overlay_pose);
|
2023-04-07 01:10:11 +02:00
|
|
|
|
2023-04-07 20:49:09 +02:00
|
|
|
auto controller_pos = GetPos(_app->GetTrackerPose(controller));
|
2023-04-07 01:10:11 +02:00
|
|
|
|
2023-04-07 20:49:09 +02:00
|
|
|
auto local_pos = glm::inverse(ConvertMat(overlay_pose)) * glm::vec4(controller_pos - GetPos(overlay_pose), 0);
|
2023-04-07 01:10:11 +02:00
|
|
|
|
2023-04-07 20:49:09 +02:00
|
|
|
float grab_area_thickness = 0.3f;
|
|
|
|
bool close_enough = glm::abs(local_pos.z) < grab_area_thickness;
|
|
|
|
close_enough &= glm::abs(local_pos.x) < _meters / 2.0f;
|
|
|
|
close_enough &= glm::abs(local_pos.y) < _meters / 2.0f;
|
|
|
|
|
|
|
|
if (close_enough)
|
|
|
|
{
|
|
|
|
ControllerGrab(controller);
|
|
|
|
}
|
2023-04-07 01:10:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-04-11 18:03:03 +02:00
|
|
|
if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState)
|
2023-04-07 01:10:11 +02:00
|
|
|
{
|
|
|
|
ControllerRelease();
|
|
|
|
}
|
2023-04-11 18:03:03 +02:00
|
|
|
// auto state = _app->GetControllerState(_active_hand);
|
|
|
|
// auto touchpad = state.rAxis[0];
|
|
|
|
// if (touchpad.x != 0.0f)
|
|
|
|
// {
|
|
|
|
// // TODO take into account the current framerate
|
|
|
|
// _alpha += touchpad.x * 0.05;
|
|
|
|
// _alpha = glm::clamp(_alpha, 0.1f, 1.0f);
|
|
|
|
// _app->vr_overlay->SetOverlayAlpha(_id, _alpha);
|
|
|
|
// }
|
2023-04-07 01:10:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Panel::Render()
|
|
|
|
{
|
2023-04-07 19:13:52 +02:00
|
|
|
glCopyImageSubData(
|
|
|
|
_app->_gl_frame, GL_TEXTURE_2D, 0,
|
|
|
|
_x, _y, 0,
|
|
|
|
_gl_texture, GL_TEXTURE_2D, 0,
|
|
|
|
0, 0, 0,
|
|
|
|
_width, _height, 1);
|
2023-04-07 01:10:11 +02:00
|
|
|
|
|
|
|
auto set_texture_err = _app->vr_overlay->SetOverlayTexture(_id, &_texture);
|
|
|
|
assert(set_texture_err == 0);
|
|
|
|
}
|
|
|
|
|
2023-04-11 18:03:03 +02:00
|
|
|
void Panel::SetHidden(bool state)
|
|
|
|
{
|
|
|
|
_hidden = state;
|
|
|
|
if (state)
|
|
|
|
_app->vr_overlay->HideOverlay(_id);
|
|
|
|
else
|
|
|
|
_app->vr_overlay->ShowOverlay(_id);
|
|
|
|
}
|
|
|
|
|
2023-04-07 01:10:11 +02:00
|
|
|
void Panel::UpdateCursor()
|
|
|
|
{
|
2023-04-07 19:27:35 +02:00
|
|
|
auto global_pos = _app->GetCursorPosition();
|
|
|
|
if (global_pos.x < _x || global_pos.x >= _x + _width || global_pos.y < _y || global_pos.y >= _y + _height)
|
|
|
|
{
|
|
|
|
_app->vr_overlay->ClearOverlayCursorPositionOverride(_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int local_x = global_pos.x - _x;
|
|
|
|
int local_y = global_pos.y - _y;
|
|
|
|
|
2023-04-07 01:10:11 +02:00
|
|
|
// TODO: make this work when aspect ratio is >1 (root window is taller than it is wide)
|
|
|
|
float ratio = (float)_height / (float)_width;
|
|
|
|
float top_edge = 0.5f - ratio / 2.0f;
|
2023-04-07 19:27:35 +02:00
|
|
|
float x = local_x / (float)_width;
|
|
|
|
float y = 1.0f - (local_y / (float)_width + top_edge);
|
2023-04-07 01:10:11 +02:00
|
|
|
auto pos = vr::HmdVector2_t{x, y};
|
|
|
|
_app->vr_overlay->SetOverlayCursorPositionOverride(_id, &pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Panel::ControllerGrab(TrackerID controller)
|
|
|
|
{
|
2023-04-11 18:03:03 +02:00
|
|
|
// printf("Grabbed panel %d\n", _index);
|
2023-04-07 01:10:11 +02:00
|
|
|
_is_held = true;
|
|
|
|
_active_hand = controller;
|
|
|
|
|
2023-04-07 20:49:09 +02:00
|
|
|
_app->vr_overlay->SetOverlayColor(_id, 0.6f, 1.0f, 1.0f);
|
|
|
|
|
2023-04-07 01:10:11 +02:00
|
|
|
vr::HmdMatrix34_t abs_pose;
|
|
|
|
vr::ETrackingUniverseOrigin tracking_universe;
|
|
|
|
|
|
|
|
_app->vr_overlay->GetOverlayTransformAbsolute(_id, &tracking_universe, &abs_pose);
|
|
|
|
auto abs_mat = ConvertMat(abs_pose);
|
|
|
|
|
|
|
|
auto controller_mat = _app->GetTrackerPose(controller);
|
|
|
|
|
|
|
|
vr::HmdMatrix34_t relative_pose = ConvertMat(glm::inverse(controller_mat) * (abs_mat));
|
|
|
|
|
|
|
|
_app->vr_overlay->SetOverlayTransformTrackedDeviceRelative(_id, controller, &relative_pose);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Panel::ControllerRelease()
|
|
|
|
{
|
2023-04-11 18:03:03 +02:00
|
|
|
// printf("Released panel %d\n", _index);
|
2023-04-07 01:10:11 +02:00
|
|
|
_is_held = false;
|
|
|
|
|
2023-04-07 20:49:09 +02:00
|
|
|
_app->vr_overlay->SetOverlayColor(_id, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
2023-04-07 01:10:11 +02:00
|
|
|
vr::HmdMatrix34_t relative_pose;
|
|
|
|
_app->vr_overlay->GetOverlayTransformTrackedDeviceRelative(_id, &_active_hand, &relative_pose);
|
|
|
|
auto relative_mat = ConvertMat(relative_pose);
|
|
|
|
|
|
|
|
auto controller_mat = _app->GetTrackerPose(_active_hand);
|
|
|
|
|
|
|
|
vr::HmdMatrix34_t new_pose = ConvertMat(controller_mat * relative_mat);
|
|
|
|
|
|
|
|
_app->vr_overlay->SetOverlayTransformAbsolute(_id, _app->_tracking_origin, &new_pose);
|
|
|
|
}
|